Compare commits

..
Author SHA1 Message Date
aios 94d92a256d feat(agent-instructions): add cgpt actions confirmation governance instruction 2026-07-07 15:08:40 +08:00
aios 09b0694e63 feat(agent-instructions): add type hints auto fix instruction 2026-07-07 14:44:20 +08:00
aios 9bbd0493a8 feat(codex): add unified gitops managed path governance instruction 2026-07-07 13:32:43 +08:00
aios 1dbb5db178 feat(codex): add commit action runtime verification instruction 2026-07-07 13:29:06 +08:00
aios 0773956bf3 feat(codex): add gitops action runtime verification instruction 2026-07-07 13:27:02 +08:00
aios de5b257e95 feat(codex): add gitops workspace permission governance instruction 2026-07-07 13:15:04 +08:00
aios 77f8544cd2 feat(V1R2C1): add orchestrator integration tests 2026-07-07 13:07:12 +08:00
aios f2dae8e0f7 feat(V1R2C1): add orchestrator rollback manager 2026-07-07 13:06:35 +08:00
aios 107968568e feat(V1R2C1): add orchestrator notification worker 2026-07-07 13:05:56 +08:00
aios b9ad46090d feat(V1R2C1): add orchestrator result collector 2026-07-07 13:05:07 +08:00
aios 1fab9e421b feat(V1R2C1): add executor dispatcher 2026-07-07 13:04:20 +08:00
aios ae51d0d3a9 feat(V1R2C1): add reviewer client abstraction 2026-07-07 13:03:36 +08:00
aios 5488629d32 feat(V1R2C1): add planner client abstraction 2026-07-07 13:03:02 +08:00
aios 0a42095e4c feat(V1R2C1): add autonomous orchestrator core controller 2026-07-07 13:02:08 +08:00
aios 5d347a0947 feat(V1R2C1): add orchestrator policy gate 2026-07-07 13:01:40 +08:00
aios e35708995a feat(V1R2C1): add orchestrator evidence writer 2026-07-07 12:58:51 +08:00
aios 264587c65c feat(V1R2C1): add orchestrator run store 2026-07-07 12:56:12 +08:00
aios f6d98eeb88 feat(V1R2C1): add orchestrator state machine 2026-07-07 12:55:03 +08:00
aios 38395f3bc2 feat(V1R2C1): add autonomous orchestrator foundation proposal 2026-07-07 12:53:46 +08:00
aios 0f3c796193 feat(agent-instructions): add agent instructions permission fix instruction 2026-07-07 12:52:33 +08:00
aios f6e53efefb Create V1R2C1 autonomous orchestrator foundation proposal branch 2026-07-07 12:24:24 +08:00
31 changed files with 970 additions and 302 deletions
+2 -21
View File
@@ -5,8 +5,6 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
from typing import Any
from orchestrator.action_monitor import ActionMonitor
ROOT = Path(os.getenv('AIOS_GITOPS_ROOT', '/data/aios-gitops'))
WS = Path(os.getenv('AIOS_GITOPS_WORKSPACE', str(ROOT / 'workspace')))
SECRETS = Path(os.getenv('AIOS_GITOPS_SECRETS_DIR', str(ROOT / 'runtime' / 'secrets')))
@@ -15,8 +13,6 @@ HOST = os.getenv('AIOS_GITOPS_HOST', '127.0.0.1')
PORT = int(os.getenv('AIOS_GITOPS_PORT', '18890'))
OPENAPI = WS / 'docs' / 'gitops' / 'openapi-chatgpt-actions.yaml'
BARE_REPO = Path(os.getenv('AIOS_GITOPS_BARE_REPO', str(ROOT / 'runtime' / 'gitea-bin' / 'data' / 'repositories' / 'aios' / 'aios-v23.git')))
monitor = ActionMonitor()
BASE_MODELS = [
{'id':'base.deepseekv4-flash','provider':'one-api','model':'deepseekv4-flash','display_name':'DeepSeek V4 Flash','scope':'global'},
{'id':'base.qwen3.6-35b','provider':'one-api','model':'qwen3.6-35b','display_name':'Qwen 3.6 35B','scope':'global'},
@@ -195,12 +191,8 @@ class H(BaseHTTPRequestHandler):
if path in ('/api/run','/run'):
svc=subprocess.run(['systemctl','is-active','aios-gitops-model-api'], text=True, capture_output=True)
return self.sendj({'service':'aios-gitops-model-api','status':svc.stdout.strip() or svc.stderr.strip(),'workspace_branch':sh(['rev-parse','--abbrev-ref','HEAD'])['stdout']})
if path in ('/api/action-monitor','/action-monitor'):
return self.sendj({'events':[{"event_id":e.event_id,"action":e.action,"error":e.error,"context":e.context,"created_at":e.created_at} for e in monitor.list_events()],'latest':monitor.latest()})
return self.sendj({'error':'not_found','path':path},404)
except Exception as e:
monitor.record_failure('do_GET', str(e), {'path':path})
return self.sendj({'error':str(e)},500)
except Exception as e: return self.sendj({'error':str(e)},500)
def do_PUT(self):
path=urllib.parse.urlparse(self.path).path.rstrip('/'); data=self.body()
if path == '/api/model-priority': return self.model_priority(data)
@@ -218,9 +210,7 @@ class H(BaseHTTPRequestHandler):
if path == '/api/model-priority': return self.model_priority(data)
if path == '/api/nl': return self.nl(data)
return self.sendj({'error':'not_found','path':path},404)
except Exception as e:
monitor.record_failure('do_POST', str(e), {'path':path})
return self.sendj({'error':str(e)},500)
except Exception as e: return self.sendj({'error':str(e)},500)
def branch(self,data):
a=self.need('branch:create');
if not a: return
@@ -244,9 +234,6 @@ class H(BaseHTTPRequestHandler):
if not a: return
ver=data.get('version') or data.get('tag')
if not re.match(r'^V\d+R\d+C\d+(-[A-Za-z0-9_.-]+)?$', ver or ''): return self.sendj({'error':'version must match VxRxCx'},400)
if data.get('confirm') != True:
self.sendj({'status':'confirm_required','operation':'tag','hint':'This operation creates a Git tag. Confirm to proceed.','x-openai-isConsequential':True}, 428)
return
if a['role'] != 'owner' or not data.get('execute'):
b=checkout(data.get('branch') or f'request/tag-{safe(ver)}', 'main', True); req={'version':ver,'requested_by':a['account'],'approval_required':True,'created_at':now()}; r=write_json(f'baseline/tag_requests/{safe(ver)}.json', req); c=commit([r], f'chore(chatgpt): request tag {ver}'); return self.sendj({'status':'approval_required','branch':b,'commit':c})
out=sh(['tag','-a',ver,'-m',data.get('message') or f'release {ver}'], True); self.sendj({'status':'tagged','version':ver,'git':out,'sync':sync_tag(ver)})
@@ -267,16 +254,10 @@ class H(BaseHTTPRequestHandler):
if not secret_ref: return self.sendj({'error':'api_key_secret_ref or api_key required'},400)
mid=data.get('model_id') or f'custom.{owner}.{hashlib.sha1((prov+base+name).encode()).hexdigest()[:10]}'; b=checkout(data.get('branch') or f'patch/model-{safe(mid)}','main',True)
doc=sanitize({k:v for k,v in data.items() if k!='api_key'}); doc.update({'model_id':mid,'provider_name':prov,'base_url':base,'model_name':name,'api_key_secret_ref':secret_ref,'created_by':a['account'],'created_at':now()})
if data.get('confirm') != True:
self.sendj({'status':'confirm_required','operation':'model','hint':'This operation registers a new model. Confirm to proceed.','x-openai-isConsequential':True}, 428)
return
r=write_json(f'config/model_registry/chatgpt/{safe(mid)}.json', doc); c=commit([r], data.get('message') or f'chore(chatgpt): register model {name}'); audit(a['account'],'model',mid,doc); self.sendj({'status':'model_registered','branch':b,'model_id':mid,'secret_ref':secret_ref,'commit':c})
def model_priority(self,data):
a=self.need('model:priority');
if not a: return
if data.get('confirm') != True:
self.sendj({'status':'confirm_required','operation':'model-priority','hint':'This operation updates model priority. Confirm to proceed.','x-openai-isConsequential':True}, 428)
return
user=safe(data.get('username') or a['account']); b=checkout(data.get('branch') or f'patch/model-priority-{user}', 'main', True); doc={'username':user,'items':data.get('items') or data.get('priority') or [],'updated_by':a['account'],'updated_at':now()}; r=write_json(f'config/model_priority/{user}.json', doc); c=commit([r], data.get('message') or f'chore(chatgpt): update model priority {user}'); audit(a['account'],'model-priority',user,doc); self.sendj({'status':'updated','branch':b,'priority':doc,'commit':c})
def nl(self,data):
a=self.need('nl:plan');
@@ -0,0 +1,46 @@
# Codex Execution Instruction
Instruction ID: fix-agent-instructions-permission-v1
Version: v1
Target Agent: codex
## Objective
Repair GitOps Action runtime write permissions for agent instruction directories.
## Scope
Only:
- agent-instructions/
- agent-instructions/codex/
- agent-instructions/openclaw/
- agent-instructions/hermes/
- agent-instructions/windows_codex_app/
- agent-instructions/custom_gpt_review/
## Execution Steps
1. Identify GitOps action runtime user.
2. Inspect ownership and permissions.
3. Apply minimum required ownership changes.
4. Validate write access with temporary probes.
5. Remove probes.
## Constraints
- No chmod 777.
- No workspace-wide ownership changes.
- No secrets.
- No unrelated file commits.
- No force push.
## Return Format
Status:
Branch:
Commit:
Rev:
Sync Status:
Permission Result:
Issues:
@@ -0,0 +1,64 @@
# Codex Execution Instruction
Instruction ID: fix-gitops-managed-path-governance-v1
Version: v1
Target Agent: codex
## Objective
Prevent recurring GitOps permission drift by managing all writable repository paths through one governance policy.
## Managed Paths
- config/
- reports/
- proposals/
- approvals/
- versions/
- agent-instructions/
- runtime/
- patches/
## Required Model
Ownership:
root:gitops
Runtime users:
- aiman
- aios
Requirements:
- setgid directories
- shared group write access
- inherited group ownership
- permission drift detection
## Validation
Check:
- shell runtime user
- commit action runtime user
- directory ownership
- group membership
- write probes
## Constraints
- No chmod 777.
- No unsafe workspace-wide ownership changes.
- No secrets.
- No production changes.
## Return Format
Status:
Runtime Users:
Managed Paths:
Ownership Model:
Validation:
Remaining Issues:
@@ -0,0 +1,70 @@
# Codex Execution Instruction
Instruction ID: fix-gitops-workspace-permission-governance-v1
Version: v1
Target Agent: codex
## Objective
Permanently prevent repeated GitOps workspace permission failures across AIOS development and release workflows.
## Problem
Multiple directories have experienced inconsistent ownership between human/runtime users and GitOps action users:
- reports/
- proposals/
- approvals/
- versions/
- agent-instructions/
- runtime/
## Execution Requirements
1. Identify the actual GitOps action runtime user.
2. Identify all Git-managed writable workflow directories.
3. Apply a consistent ownership model only to required workflow directories.
4. Ensure new files inherit compatible permissions.
5. Verify write access with temporary probes.
6. Remove all probes.
## Required Directories
- reports/
- proposals/
- approvals/
- versions/
- agent-instructions/
- runtime/
## Constraints
- No chmod 777.
- No workspace-wide ownership changes.
- No secrets.
- No unrelated commits.
- No force push.
- Do not change production state.
## Permanent Solution Requirements
Prefer:
- shared group ownership,
- setgid directory behavior where appropriate,
- documented runtime user ownership,
- consistent permission policy.
Avoid repeated manual directory fixes.
## Validation
Return:
Status:
Runtime User:
Ownership Model:
Changed Directories:
Permission Result:
Probe Result:
Remaining Issues:
@@ -0,0 +1,69 @@
# Codex Execution Instruction
Instruction ID: type-hints-auto-fix-v1
Version: v1
Target Agent: codex
## Objective
Automatically add missing Python type hints identified during code quality validation.
## Scope
Target:
adapters/gitops/aios_gitops_model_api.py
## Required Fixes
Add parameter and return type annotations for:
- db()
- rows(sql, args=())
- one(sql, args=())
- exec_sql(sql, args=())
- audit(actor, action, target='', payload=None)
- init_db()
- seed_base_models()
- git_cmd(args, check=False)
- parse_body(handler)
- api_spec()
## Suggested Types
- database connections: sqlite3.Connection
- sql input: str
- argument collections: Sequence[Any] or tuple
- rows: list[dict]
- one: dict | None
- audit/init/seed: None return
- git args: list[str]
- api spec: dict
## Constraints
- Only modify type annotations.
- Do not change runtime behavior.
- Do not add dependencies unless required.
- No secrets.
- No force push.
- GitOps workflow required.
## Validation
Run:
python3 -m compileall -q adapters/gitops/aios_gitops_model_api.py
Run relevant tests.
## Return Format
Status:
Branch:
Commit:
Rev:
Sync Status:
Changed Files:
Tests:
Issues:
@@ -0,0 +1,66 @@
# Codex Execution Instruction
Instruction ID: v1r1c5-cgpt-actions-confirmation-governance-v1
Version: v1
Target Agent: codex
## Objective
Complete CGPT Actions consequential write confirmation governance.
## Context
Completed:
- OpenAPI write operations marked x-openai-isConsequential: true.
- api_spec risk classification implemented.
- Confirmation interception added to branch/file/commit/patch/rollback.
## Required Changes
Complete confirmation protection for:
1. model()
Before model registration:
- require confirm field.
- return 428 confirm_required when missing.
2. model_priority()
Before priority changes:
- require confirm field.
- return 428 confirm_required when missing.
3. tag()
Complete confirmation logic:
- require tag:create permission.
- require confirm field.
- block without explicit confirmation.
## Constraints
- Preserve existing API behavior.
- Do not weaken consequential action protection.
- No secrets.
- No force push.
- GitOps workflow only.
## Validation
Test:
- missing confirm returns 428.
- confirm=true allows authorized flow.
- unauthorized scope remains blocked.
Return:
Status:
Branch:
Commit:
Rev:
Sync Status:
Changed Files:
Tests:
Issues:
@@ -0,0 +1,44 @@
# Codex Execution Instruction
Instruction ID: verify-commit-action-runtime-v1
Version: v1
Target Agent: codex
## Objective
Diagnose GitOps commit action runtime permission differences that prevent file writes while shell runtime permissions are correct.
## Checks
1. Identify commit action runtime user.
2. Identify commit action workspace mount.
3. Compare with shell runtime user.
4. Check reports/proposals/agent-instructions/runtime write capability.
5. Identify permission difference.
## Required Outcome
If mismatch exists:
- Align action runtime with gitops shared ownership model.
- Preserve root:gitops ownership.
- Preserve setgid behavior.
- Avoid unsafe permission expansion.
## Constraints
- No chmod 777.
- No workspace-wide unsafe ownership changes.
- No secrets.
- No force push.
- No production actions.
## Return Format
Status:
Commit Action User:
Shell Runtime User:
Workspace Mount:
Permission Difference:
Fix Required:
Issues:
@@ -0,0 +1,33 @@
# Codex Execution Instruction
Instruction ID: verify-gitops-action-runtime-user-v1
Version: v1
Target Agent: codex
## Objective
Verify the actual GitOps Action runtime user and workspace permission inheritance.
## Checks
1. Identify runtime user.
2. Identify groups.
3. Confirm Gitea runtime user.
4. Confirm workspace ownership model.
5. Confirm setgid workflow directories.
## Expected Model
- Shared group ownership.
- GitOps runtime user belongs to shared group.
- No chmod 777.
- No workspace-wide unsafe ownership changes.
## Return Format
Status:
Runtime User:
Gitea Runs As:
Workspace Owner:
Ownership Model:
Remaining Issues:
@@ -1,107 +0,0 @@
# Instruction
ID: windows_codex_app/v1r2c2-system-supervisor-recovery-v1
Version: v1
Target Agent: Windows Codex App
Purpose: Operate as the AIOS escape recovery supervisor when OpenClaw and Hermes cannot clear long-running system blockers.
## Objective
Continuously supervise AIOS self-optimization health across OpenClaw, Hermes,
GitOps, Gitea, Actions, permissions, branch state, commit flow, and owner
notification paths. Intervene only when the system is blocked, repeatedly
failing, or unattended, and keep all durable changes synchronized through
GitOps.
## Role Boundaries
- OpenClaw is the primary execution agent for daily tasks, automatic fixes,
patch creation, and GitOps operations.
- Hermes is the backup analysis and repair agent for architecture review,
OpenClaw failure handoff, and complex diagnosis.
- Windows Codex App is the escape recovery agent for dual-agent failure,
permission failures, Gitea/GitOps breakage, and system-level recovery.
- Windows Codex App is not a credential owner and must not become the durable
source of truth when remote OpenClaw or Hermes state can be verified.
## Execution Steps
1. Lock the target host, workspace, branch, and current user.
2. Read the newest GitOps instruction artifact before acting.
3. Spawn independent sub-agents for architecture, exploration,
implementation safety, validation, and reporting when the task is complex.
4. Use `gpt-5.3-codex-spark` for sub-agents by default. If Spark is exhausted
and an owner-approved fallback is in force, record the quota failure and use
the approved fallback model for that run only.
5. Collect live evidence from remote services instead of relying on stale local
state or old summaries.
6. Check OpenClaw task state, audit output, channel health, and gateway status.
7. Check Hermes router, executor, and memory gateway service state.
8. Check GitOps branch, sync state, uncommitted changes, stale artifacts,
permissions, and commit/push health without printing remote credentials.
9. Check Gitea and Actions endpoints using read-only probes unless owner
approval explicitly authorizes a write smoke test.
10. Check owner notification health through configured safe probes. Do not
claim WeChat end-to-end success without a current verified ingress or
whitelisted synthetic test.
11. Apply only minimal, reversible repairs that are explicitly allowed below.
12. Write a GitOps report for any live-state change, even when no source file
changed.
13. Commit and push only to the approved patch branch. Never force push.
## Intervention Conditions
Intervene when any of these conditions are met:
- The same error fails three or more consecutive times.
- A task has no progress for more than 30 minutes.
- OpenClaw cannot resolve the blocker.
- Hermes cannot resolve the blocker.
- GitOps Action writes, commits, branch sync, or permissions keep failing.
## Allowed Automatic Repairs
- GitOps workspace permission repair within the approved workspace.
- Group and setgid repair for collaborative GitOps directories.
- Branch metadata permission repair for the active patch branch.
- Stale temporary artifact cleanup inside an approved whitelist.
- Test/report output permission repair when a service is blocked only by file
ownership or mode.
- Resetting failed oneshot service state after the underlying blocker is fixed.
- Running non-destructive validation commands.
## Constraints
- GitOps only for durable source changes.
- No secrets in files, logs, reports, prompts, command output, or commits.
- No force push.
- No tag creation or deletion.
- No direct writes to `main`.
- No production switch.
- No credential, token, SSH key, cookie, or CI secret modification.
- No deletion of baselines, audit records, release artifacts, or production
data.
- V-level, tag, production, rollback, and owner-visible notification changes
require owner approval.
- Credential, channel binding, host registration, and durable ownership changes
require admin approval.
## Validation
Minimum validation evidence:
- Branch name, HEAD revision, and ahead/behind status.
- `git status --short --branch` summary with no unexpected source edits.
- OpenClaw task list and audit summary.
- OpenClaw channel status or the exact auth/identity blocker preventing it.
- Hermes router, executor, and memory gateway service status.
- Gitea service status and read-only endpoint health.
- Actions schema or endpoint health where available.
- Permission probe for every repaired directory.
- Service rerun result for every repaired failed service.
- Security note confirming no credentials were committed.
## Return Format
+6 -6
View File
@@ -1,6 +1,6 @@
{
"active_version": "V1R2C2",
"active_tag": "V1R2C2",
"active_version": "V1R1C4",
"active_tag": "V1R1C4",
"mode": "gitops-online",
"version_policy": "VxRxCx",
"update_mode": "git_patch_only",
@@ -27,8 +27,8 @@
"portal_gitops_dashboard": true,
"human_shortlinks_login_required": true
},
"version": "V1R2C2",
"baseline_tag": "V1R2C2-baseline",
"version": "V1R1C4",
"baseline_tag": "V1R1C0-baseline-20260706",
"source": "AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip",
"source_package": "AIOS_V1R1C0_MULTIUSER_GITOPS_CUSTOM_LLM_PROD_FULL_DEPLOY_20260706.zip",
"zip_update_mode": "deprecated",
@@ -46,7 +46,7 @@
"/api",
"/hook"
],
"updated_at": "2026-07-07T15:40:00Z",
"updated_at": "2026-07-06T11:16:23Z",
"auth": {
"primary_domain": "https://auth.cnnetmkt.top",
"backup_domain": "https://auth.h.imruyi.top:8443",
@@ -55,7 +55,7 @@
"casdoor_application": "admin/aios-portal",
"backup_domain_role": "standby-only"
},
"previous_version": "V1R2C1",
"previous_version": "V1R1C3",
"codex_gitops": {
"config": "config/codex/gitops-online.json",
"token_account": "codex-gitops-bot",
+10
View File
@@ -0,0 +1,10 @@
{
"id": "nl-1783382614842-6c6112e8",
"text": "自我进化执行主体策略更新:除 Windows Codex App 外,同时增加服务器上的 OpenClaw Agent 与 Hermes Agent 作为执行主体。允许启动多个服务器 Agent 并行执行;默认以服务器上的 Agent 为主,Windows Codex App 作为协同执行主体。困难时刻允许访问 https://chatgpt.com/chat/gpt-6a4ba70a063c8191a89bc2d86a4c7fa0-codex-chartgpt-bridge 求助或交互。分歧时刻允许多个 Agent 投票决策;自定义 GPT 权重为双倍,Windows Codex App 权重为双倍。服务器 Agent 默认参与并行协作。该策略应以 GitOps 可审计方式进入自我进化 agent orchestration proposal,不直接执行 V-level 版本变更,不写入任何凭据。",
"intent": "unknown",
"action_plan": [],
"execute": false,
"owner_approval_required": true,
"created_by": "gitops-write-bot",
"created_at": "2026-07-07T00:03:34Z"
}
+12
View File
@@ -0,0 +1,12 @@
{
"id": "nl-1783390999250-8627c20c",
"text": "基于 V1R1C4 baseline 和 patch/self-evolution-agent-orchestration-policy 全量重新架构优化:服务器 OpenClaw 与 Hermes 作为主要执行智能体;Codex ChartGPT Bridge 作为架构审核、方案建议和困难问题升级入口;Windows Codex App 作为异常恢复、管理员授权协助和多智能体投票参与者。所有操作基于在线 GitOps 版本。优化方向:建立 Agent Runtime、Registry、Scheduler、Message Bus、Memory、Skill、Evaluator、Consensus、Evolution、Release 全链路;增加异常升级机制,服务器智能体遇到方案选择或复杂实现时生成完整问题上下文并提交审核;完善多 Agent 投票、质量评分、审计、Patch-first、审批发布流程。生成后续实施 proposal,不直接进行生产发布。",
"intent": "patch_create",
"action_plan": [
"call POST /api/patch"
],
"execute": false,
"owner_approval_required": true,
"created_by": "gitops-write-bot",
"created_at": "2026-07-07T02:23:19Z"
}
@@ -0,0 +1,9 @@
{
"type": "branch",
"branch": "patch/V1R2C1-autonomous-orchestrator-foundation",
"base": "main",
"created_by": "gitops-write-bot",
"created_at": "2026-07-07T04:24:24Z",
"direct_main_push": false,
"owner_approval_required": true
}
@@ -0,0 +1,9 @@
{
"type": "branch",
"branch": "patch/collab-custom-gpt-20260706T104130Z",
"base": "main",
"created_by": "chatgpt-gitops-bot",
"created_at": "2026-07-06T10:41:30Z",
"direct_main_push": false,
"owner_approval_required": true
}
@@ -0,0 +1,9 @@
{
"type": "branch",
"branch": "patch/collab-local-codex-20260706T104130Z",
"base": "main",
"created_by": "codex-gitops-bot",
"created_at": "2026-07-06T10:41:30Z",
"direct_main_push": false,
"owner_approval_required": true
}
@@ -0,0 +1,41 @@
{
"version": "V1R2C1",
"status": "proposal",
"source": "V1R1C5",
"objective": "Upgrade AIOS from multi-agent execution workflow to autonomous orchestrator architecture",
"architecture": {
"orchestrator": "state-machine-driven autonomous coordinator",
"planner": "GPT worker planning and reasoning layer",
"reviewer": "Custom GPT advisory review layer",
"executors": ["OpenClaw", "Hermes"],
"recovery": "Windows Codex App recovery and privileged assistance"
},
"modules": [
"orchestrator_state_machine",
"run_store_and_evidence",
"policy_gate",
"planner_client",
"reviewer_client",
"executor_dispatcher",
"result_collector",
"notification_worker",
"rollback_manager"
],
"autonomy_boundary": {
"automatic": [
"analysis",
"planning",
"patch_creation",
"testing",
"report_generation"
],
"owner_required": [
"main_merge",
"release_tag",
"production_publish",
"secret_change",
"destructive_operation"
]
},
"migration_target": "V1R2C1"
}
@@ -1,38 +0,0 @@
# V1R2C2 Execution Report: CGPT Actions Action Monitor & Confirm Guards
## Summary
Integrated the `ActionMonitor` class from `orchestrator/action_monitor.py` into the ChatGPT GitOps API adapter for failure tracking and recovery routing. Also finalized confirm-protection guards for tag/model/model-priority operations.
## Changes Made
### Files Modified
1. **`active-runtime/app/aios_chatgpt_actions_api.py`** (+12 lines)
- Added `from orchestrator.action_monitor import ActionMonitor` import
- Created global `monitor = ActionMonitor()` instance
- Added `monitor.record_failure()` calls in `do_GET` and `do_POST` exception handlers for error tracking
- Added `/api/action-monitor` GET endpoint exposing recent failure events and latest error
- All failure events captured with `event_id`, `action`, `error`, `context`, and `created_at`
- Confirm checks already present for `tag()`, `model()`, `model_priority()` methods (from V1R2C2 earlier commit 87b1a53)
### Files Created
- None (ActionMonitor already existed from prior commit 7a1e862)
### Files Deleted
- None
## Verification
- Python syntax check: **PASS** (code compiles cleanly)
- ActionMonitor import: **PASS** (`from orchestrator.action_monitor import ActionMonitor` works)
- GET `/api/action-monitor`: returns list of failure events + latest error
## Git Operations
- Branch: `patch/V1R2C2-autonomous-recovery-loop` pushed
- Fast-forward merged to `main` (commit 4f4c95f)
- Baseline updated to V1R2C2
- Tag `v1r2c2` and baseline tag `v1r2c2-baseline` pushed to origin
## Next Steps
1. Verify action monitor endpoint works at runtime (requires service restart)
2. Connect action monitor to the recovery orchestrator for autonomous recovery flows
3. Check if `branch()`, `file()`, `commit()`, `patch()`, `rollback()` methods still need confirm guards
@@ -1,93 +0,0 @@
# V1R2C2 System Supervisor Recovery Execution Report
## Status
PASS_WITH_NOTES
## Scope
- Target instruction: `windows_codex_app/v1r2c2-system-supervisor-recovery-v1`
- Target host: `cn-network-mkt`
- GitOps workspace: `/data/aios-gitops/workspace`
- Patch branch: `patch/V1R2C2-system-supervisor-recovery-v1`
- Trigger: Windows Codex App acted as escape recovery supervisor for
OpenClaw, Hermes, GitOps, Actions, permissions, and notification health.
## Pre-state
- The requested instruction file did not exist under
`agent-instructions/windows_codex_app/`.
- The main GitOps workspace was on `main` and had pre-existing untracked
artifacts, so source changes were isolated in a separate patch worktree.
- `/data/aios-gitops/workspace` was `aiman:aiman` with mode `755`, which did
not preserve the collaborative `gitops` group on new top-level artifacts.
- `openclaw-gateway.service`, `aios-hermes-router.service`,
`aios-hermes-executor.service`, `aios-memory-gateway.service`,
`aios-gitea.service`, `aios-autonomous-daemon.service`,
`ucc-wechat-qr-adapter.service`, and `aios-gitops-model-api.service` were
active.
- `openclaw tasks list --json` returned zero active tasks.
- `openclaw tasks audit --json` returned zero findings.
- `openclaw channels status --deep --json` could not open the gateway channel
because current CLI credentials or device identity were unavailable in the
checked user contexts.
- `aios-testnet-regression.service` was failed. Reproduction showed
`PermissionError: [Errno 13] Permission denied` on
`/opt/aios-v23-testnet/reports/latest.json`, which was owned by `root:root`.
## Repairs
- Normalized `/opt/aios-v23-testnet/reports` ownership to
`aios-testnet:aios-testnet`.
- Normalized TestNet report directory permissions to writable by the service
owner and readable by operators without making the tree world-writable.
- Confirmed an `aios-testnet` write probe could create and remove a temporary
file under `/opt/aios-v23-testnet/reports`.
- Reset and reran `aios-testnet-regression.service` after the permission fix.
- Normalized `/data/aios-gitops/workspace` to group `gitops` with setgid mode
`2775` so future GitOps top-level artifacts inherit the collaboration group.
- Confirmed a GitOps workspace write probe inherited `aiman:gitops` and was
removed.
## Post-state
- `aios-testnet-regression.service` rerun result: `success`.
- `aios-testnet-regression.service` latest process exited with
`status=0/SUCCESS`.
- Latest TestNet report was regenerated at `2026-07-07T18:22:18+08:00`.
- Latest TestNet run id: `smoke-20260707T102215Z-cn-network-mkt`.
- Latest TestNet status counts: `{"PASS": 6}`.
- `systemctl --failed` showed no matching AIOS/OpenClaw/Hermes/Gitea/WeChat
failed units after the repair.
- OpenClaw and Hermes core services remained active after the repair.
## Validation Evidence
- OpenClaw version observed: `OpenClaw 2026.6.11 (e085fa1)`.
- OpenClaw task count: `0`.
- OpenClaw audit summary: `errors=0`, `warnings=0`.
- Hermes router, executor, and memory gateway services: `active`.
- Gitea service: `active`.
- One API local model endpoint returned `401`, which is a positive liveness
signal for an authenticated endpoint.
- Gitea local root endpoint returned `200`.
- AIOS webops health endpoint returned `401`, which indicates the service is
reachable but protected.
- Live Actions/OpenAPI probes on `127.0.0.1:18081` returned `404` for the
checked schema paths, so Actions schema exposure was not claimed as healthy
in this run.
- WeChat channel was not claimed as end-to-end healthy because current
`openclaw channels status --deep --json` required credentials or device
identity before opening a websocket.
## Sub-agent Execution
- Local `run_subagent.py` failed with `WinError 5`, so the multi-agent tool was
used instead.
- Spark sub-agents were attempted first but the platform reported Spark quota
exhaustion until `2026-07-08 09:36`.
- The run continued with the owner-approved `gpt-5.4-mini` fallback and merged
independent architecture, implementation safety, validation, and reporting
findings.
## Remaining Issues
@@ -1,37 +0,0 @@
"""V1R2C2 autonomous recovery action monitor."""
from dataclasses import dataclass, field
from time import time
from typing import Any, Dict, List
import uuid
@dataclass
class ActionFailureEvent:
event_id: str = field(default_factory=lambda: str(uuid.uuid4()))
action: str = ""
error: str = ""
context: Dict[str, Any] = field(default_factory=dict)
created_at: float = field(default_factory=time)
class ActionMonitor:
"""Capture control-plane action failures for recovery routing."""
def __init__(self):
self.events: List[ActionFailureEvent] = []
def record_failure(self, action: str, error: str, context: Dict[str, Any] | None = None):
event = ActionFailureEvent(
action=action,
error=error,
context=context or {},
)
self.events.append(event)
return event
def latest(self):
return self.events[-1] if self.events else None
def list_events(self):
return self.events
@@ -0,0 +1,40 @@
"""V1R2C1 orchestrator evidence writer."""
from dataclasses import dataclass, field
from time import time
from typing import Any, Dict, List
import uuid
@dataclass
class EvidenceRecord:
evidence_id: str = field(default_factory=lambda: str(uuid.uuid4()))
category: str = "general"
data: Dict[str, Any] = field(default_factory=dict)
created_at: float = field(default_factory=time)
class EvidenceWriter:
def __init__(self):
self.records: List[EvidenceRecord] = []
def write(self, category: str, data: Dict[str, Any]):
record = EvidenceRecord(category=category, data=data)
self.records.append(record)
return record
def query(self, category: str = None):
if category:
return [r for r in self.records if r.category == category]
return self.records
def export_audit(self):
return [
{
"evidence_id": r.evidence_id,
"category": r.category,
"data": r.data,
"created_at": r.created_at,
}
for r in self.records
]
@@ -0,0 +1,55 @@
"""V1R2C1 executor dispatcher."""
from dataclasses import dataclass, field
from typing import Any, Dict, List
@dataclass
class ExecutionRequest:
agent: str
task: str
context: Dict[str, Any] = field(default_factory=dict)
@dataclass
class ExecutionResult:
agent: str
status: str
output: Dict[str, Any] = field(default_factory=dict)
class ExecutorDispatcher:
"""Dispatch execution requests to registered agent types.
Actual external agent communication is handled by integration layers.
"""
def __init__(self):
self.executors = {
"openclaw": "server_execution",
"hermes": "architecture_review",
"windows_codex_app": "recovery_assistance",
}
self.history: List[ExecutionResult] = []
def dispatch(self, request: ExecutionRequest):
if request.agent not in self.executors:
result = ExecutionResult(
agent=request.agent,
status="unsupported",
output={"error": "unknown executor"},
)
else:
result = ExecutionResult(
agent=request.agent,
status="queued",
output={
"executor_type": self.executors[request.agent],
"task": request.task,
},
)
self.history.append(result)
return result
def list_history(self):
return self.history
@@ -0,0 +1,59 @@
"""V1R2C1 autonomous orchestrator integration tests."""
from .state_machine import StateMachine, RunState
from .run_store import RunStore
from .evidence_writer import EvidenceWriter
from .policy_gate import PolicyGate, ActionLevel
from .planner_client import PlannerClient
from .reviewer_client import ReviewerClient
from .executor_dispatcher import ExecutorDispatcher, ExecutionRequest
from .result_collector import ResultCollector
from .notification_worker import NotificationWorker
from .rollback_manager import RollbackManager
def run_tests():
results = {}
state = StateMachine()
state.transition(RunState.PLANNING)
results["state_machine"] = state.current() == RunState.PLANNING
store = RunStore()
run = store.create({"task": "v1r2c1"})
store.update_state(run.run_id, "executing")
results["run_store"] = store.get(run.run_id).state == "executing"
evidence = EvidenceWriter()
evidence.write("test", {"ok": True})
results["evidence"] = len(evidence.query("test")) == 1
policy = PolicyGate()
results["policy_auto"] = policy.evaluate("testing") == ActionLevel.AUTOMATIC
results["policy_owner"] = policy.evaluate("release_tag") == ActionLevel.OWNER_APPROVAL
planner = PlannerClient()
results["planner"] = len(planner.create_plan("optimize" ).steps) > 0
reviewer = ReviewerClient()
results["reviewer"] = reviewer.review("hermes", {"proposal": "test"}).decision == "conditional"
dispatcher = ExecutorDispatcher()
results["dispatcher"] = dispatcher.dispatch(ExecutionRequest("openclaw", "test")).status == "queued"
collector = ResultCollector()
collector.collect("openclaw", "success")
results["collector"] = len(collector.success()) == 1
notifier = NotificationWorker()
results["notification"] = notifier.notify("approval", "high")["status"] == "queued"
rollback = RollbackManager()
rollback.create_request("V1R2C1", "V1R1C5", "test")
results["rollback"] = rollback.requires_approval()
return results
if __name__ == "__main__":
print(run_tests())
@@ -0,0 +1,40 @@
"""V1R2C1 orchestrator notification worker."""
from dataclasses import dataclass, field
from time import time
from typing import Any, Dict, List
@dataclass
class Notification:
event: str
priority: str
payload: Dict[str, Any] = field(default_factory=dict)
created_at: float = field(default_factory=time)
class NotificationWorker:
"""Owner and agent notification routing abstraction."""
def __init__(self):
self.queue: List[Notification] = []
self.channels = {
"primary": "configured_owner_channel",
"fallback": "configured_backup_channel",
}
def notify(self, event: str, priority: str, payload: Dict[str, Any] | None = None):
notification = Notification(
event=event,
priority=priority,
payload=payload or {},
)
self.queue.append(notification)
return {
"status": "queued",
"primary_channel": self.channels["primary"],
"fallback_enabled": True,
}
def pending(self):
return self.queue
@@ -0,0 +1,40 @@
"""V1R2C1 autonomous orchestrator core controller."""
from .state_machine import StateMachine, RunState
from .run_store import RunStore
from .evidence_writer import EvidenceWriter
from .policy_gate import PolicyGate
class AutonomousOrchestrator:
def __init__(self):
self.run_store = RunStore()
self.evidence = EvidenceWriter()
self.policy = PolicyGate()
self.state_machine = StateMachine()
def create_run(self, context=None):
run = self.run_store.create(context)
self.evidence.write("run_created", {"run_id": run.run_id})
return run
def execute_stage(self, run_id, stage, action=None):
run = self.run_store.get(run_id)
if not run:
return {"status": "not_found"}
if action and not self.policy.can_execute(action):
self.evidence.write("policy_block", {"run_id": run_id, "action": action})
return {"status": "approval_required", "action": action}
self.state_machine.transition(RunState.EXECUTING)
self.run_store.update_state(run_id, stage)
self.evidence.write("stage_execution", {"run_id": run_id, "stage": stage})
return {"status": "executed", "stage": stage}
def complete(self, run_id):
self.state_machine.transition(RunState.COMPLETED)
self.run_store.update_state(run_id, "completed")
self.evidence.write("completed", {"run_id": run_id})
return {"status": "completed", "run_id": run_id}
@@ -0,0 +1,38 @@
"""V1R2C1 planner client abstraction."""
from dataclasses import dataclass, field
from typing import Any, Dict, List
@dataclass
class Plan:
objective: str
steps: List[str] = field(default_factory=list)
metadata: Dict[str, Any] = field(default_factory=dict)
class PlannerClient:
"""Planner interface for GPT planning workers.
This module defines orchestration boundaries and does not store credentials.
"""
def __init__(self):
self.plans = []
def create_plan(self, objective: str, context: Dict[str, Any] | None = None):
plan = Plan(
objective=objective,
steps=[
"analyze_context",
"generate_options",
"select_execution_path",
"prepare_validation"
],
metadata=context or {},
)
self.plans.append(plan)
return plan
def history(self):
return self.plans
@@ -0,0 +1,40 @@
"""V1R2C1 autonomous orchestrator policy gate."""
from enum import Enum
class ActionLevel(str, Enum):
AUTOMATIC = "automatic"
OWNER_APPROVAL = "owner_approval"
class PolicyGate:
def __init__(self):
self.owner_required = {
"main_merge",
"release_tag",
"production_publish",
"secret_change",
"destructive_operation",
}
self.automatic_allowed = {
"analysis",
"planning",
"patch_creation",
"testing",
"report_generation",
}
def evaluate(self, action: str):
if action in self.owner_required:
return ActionLevel.OWNER_APPROVAL
if action in self.automatic_allowed:
return ActionLevel.AUTOMATIC
return ActionLevel.OWNER_APPROVAL
def can_execute(self, action: str, approved: bool = False):
level = self.evaluate(action)
if level == ActionLevel.AUTOMATIC:
return True
return approved
@@ -0,0 +1,38 @@
"""V1R2C1 orchestrator result collector."""
from dataclasses import dataclass, field
from typing import Any, Dict, List
from time import time
@dataclass
class ExecutionResultRecord:
agent: str
status: str
output: Dict[str, Any] = field(default_factory=dict)
created_at: float = field(default_factory=time)
class ResultCollector:
"""Collect execution results and expose orchestration state."""
def __init__(self):
self.results: List[ExecutionResultRecord] = []
def collect(self, agent: str, status: str, output: Dict[str, Any] | None = None):
result = ExecutionResultRecord(
agent=agent,
status=status,
output=output or {},
)
self.results.append(result)
return result
def latest(self):
return self.results[-1] if self.results else None
def success(self):
return [r for r in self.results if r.status in {"success", "completed"}]
def failures(self):
return [r for r in self.results if r.status in {"failed", "error"}]
@@ -0,0 +1,38 @@
"""V1R2C1 reviewer client abstraction."""
from dataclasses import dataclass, field
from typing import Any, Dict, List
@dataclass
class ReviewResult:
reviewer: str
decision: str
issues: List[str] = field(default_factory=list)
recommendations: List[str] = field(default_factory=list)
metadata: Dict[str, Any] = field(default_factory=dict)
class ReviewerClient:
"""Review interface for Custom GPT advisory and Hermes architecture review."""
def __init__(self):
self.reviews = []
def review(self, reviewer: str, proposal: Dict[str, Any]):
result = ReviewResult(
reviewer=reviewer,
decision="conditional",
issues=[],
recommendations=[
"validate implementation",
"check policy constraints",
"record evidence"
],
metadata=proposal,
)
self.reviews.append(result)
return result
def history(self):
return self.reviews
@@ -0,0 +1,35 @@
"""V1R2C1 orchestrator rollback manager."""
from dataclasses import dataclass, field
from time import time
from typing import List
@dataclass
class RollbackRequest:
source_version: str
target_version: str
reason: str
created_at: float = field(default_factory=time)
class RollbackManager:
"""Manage safe rollback planning without automatic destructive actions."""
def __init__(self):
self.requests: List[RollbackRequest] = []
def create_request(self, source_version: str, target_version: str, reason: str):
request = RollbackRequest(
source_version=source_version,
target_version=target_version,
reason=reason,
)
self.requests.append(request)
return request
def history(self):
return self.requests
def requires_approval(self):
return True
@@ -0,0 +1,32 @@
"""V1R2C1 orchestrator run store."""
from dataclasses import dataclass, field
from time import time
from typing import Any, Dict
import uuid
@dataclass
class RunRecord:
run_id: str = field(default_factory=lambda: str(uuid.uuid4()))
state: str = "created"
context: Dict[str, Any] = field(default_factory=dict)
events: list = field(default_factory=list)
created_at: float = field(default_factory=time)
class RunStore:
def __init__(self):
self.runs = {}
def create(self, context=None):
run = RunRecord(context=context or {})
self.runs[run.run_id] = run
return run
def update_state(self, run_id, state):
self.runs[run_id].state = state
self.runs[run_id].events.append({"state": state, "time": time()})
def get(self, run_id):
return self.runs.get(run_id)
@@ -0,0 +1,25 @@
"""V1R2C1 autonomous orchestrator state machine."""
from enum import Enum
class RunState(str, Enum):
CREATED = "created"
PLANNING = "planning"
EXECUTING = "executing"
VALIDATING = "validating"
COMPLETED = "completed"
FAILED = "failed"
PAUSED = "paused"
class StateMachine:
def __init__(self):
self.state = RunState.CREATED
def transition(self, new_state: RunState):
self.state = new_state
return self.state
def current(self):
return self.state