From ed9df72eeb4c27edd0c18432c2f3c1e59dded690 Mon Sep 17 00:00:00 2001 From: Eve Date: Wed, 8 Apr 2026 04:30:44 +0800 Subject: [PATCH] bootstrap: record per-agent workspace skeleton setup --- ...08-agent-workspace-bootstrap-manifest.json | 80 +++++ ...-04-08-agent-workspace-bootstrap-report.md | 73 +++++ scripts/bootstrap_agent_workspaces.py | 309 ++++++++++++++++++ 3 files changed, 462 insertions(+) create mode 100644 docs/plans/2026-04-08-agent-workspace-bootstrap-manifest.json create mode 100644 docs/plans/2026-04-08-agent-workspace-bootstrap-report.md create mode 100644 scripts/bootstrap_agent_workspaces.py diff --git a/docs/plans/2026-04-08-agent-workspace-bootstrap-manifest.json b/docs/plans/2026-04-08-agent-workspace-bootstrap-manifest.json new file mode 100644 index 0000000..78d9389 --- /dev/null +++ b/docs/plans/2026-04-08-agent-workspace-bootstrap-manifest.json @@ -0,0 +1,80 @@ +{ + "generatedAt": "2026-04-08T04:29:37.793730", + "createdDirectories": [ + "/home/alice/.openclaw/workspace-prompt-optimizer", + "/home/alice/.openclaw/workspace-prompt-optimizer/memory", + "/home/alice/.openclaw/workspace-prompt-optimizer/tasks", + "/home/alice/.openclaw/workspace-prompt-optimizer/logs", + "/home/alice/.openclaw/workspace-reviewer", + "/home/alice/.openclaw/workspace-reviewer/memory", + "/home/alice/.openclaw/workspace-reviewer/tasks", + "/home/alice/.openclaw/workspace-reviewer/logs", + "/home/alice/.openclaw/workspace-research", + "/home/alice/.openclaw/workspace-research/memory", + "/home/alice/.openclaw/workspace-research/tasks", + "/home/alice/.openclaw/workspace-research/logs", + "/home/alice/.openclaw/workspace-engineering", + "/home/alice/.openclaw/workspace-engineering/memory", + "/home/alice/.openclaw/workspace-engineering/tasks", + "/home/alice/.openclaw/workspace-engineering/logs", + "/home/alice/.openclaw/workspace-ops", + "/home/alice/.openclaw/workspace-ops/memory", + "/home/alice/.openclaw/workspace-ops/tasks", + "/home/alice/.openclaw/workspace-ops/logs" + ], + "createdFiles": [ + "/home/alice/.openclaw/workspace-prompt-optimizer/SOUL.md", + "/home/alice/.openclaw/workspace-prompt-optimizer/AGENTS.md", + "/home/alice/.openclaw/workspace-prompt-optimizer/USER.md", + "/home/alice/.openclaw/workspace-prompt-optimizer/WORKFLOW.md", + "/home/alice/.openclaw/workspace-prompt-optimizer/TASK_TEMPLATE.md", + "/home/alice/.openclaw/workspace-prompt-optimizer/REPORT_TEMPLATE.md", + "/home/alice/.openclaw/workspace-reviewer/SOUL.md", + "/home/alice/.openclaw/workspace-reviewer/AGENTS.md", + "/home/alice/.openclaw/workspace-reviewer/USER.md", + "/home/alice/.openclaw/workspace-reviewer/WORKFLOW.md", + "/home/alice/.openclaw/workspace-reviewer/TASK_TEMPLATE.md", + "/home/alice/.openclaw/workspace-reviewer/REPORT_TEMPLATE.md", + "/home/alice/.openclaw/workspace-research/SOUL.md", + "/home/alice/.openclaw/workspace-research/AGENTS.md", + "/home/alice/.openclaw/workspace-research/USER.md", + "/home/alice/.openclaw/workspace-research/WORKFLOW.md", + "/home/alice/.openclaw/workspace-research/TASK_TEMPLATE.md", + "/home/alice/.openclaw/workspace-research/REPORT_TEMPLATE.md", + "/home/alice/.openclaw/workspace-engineering/SOUL.md", + "/home/alice/.openclaw/workspace-engineering/AGENTS.md", + "/home/alice/.openclaw/workspace-engineering/USER.md", + "/home/alice/.openclaw/workspace-engineering/WORKFLOW.md", + "/home/alice/.openclaw/workspace-engineering/TASK_TEMPLATE.md", + "/home/alice/.openclaw/workspace-engineering/REPORT_TEMPLATE.md", + "/home/alice/.openclaw/workspace-ops/SOUL.md", + "/home/alice/.openclaw/workspace-ops/AGENTS.md", + "/home/alice/.openclaw/workspace-ops/USER.md", + "/home/alice/.openclaw/workspace-ops/WORKFLOW.md", + "/home/alice/.openclaw/workspace-ops/TASK_TEMPLATE.md", + "/home/alice/.openclaw/workspace-ops/REPORT_TEMPLATE.md" + ], + "skippedExistingFiles": [], + "agents": [ + { + "id": "prompt-optimizer", + "workspace": "/home/alice/.openclaw/workspace-prompt-optimizer" + }, + { + "id": "reviewer", + "workspace": "/home/alice/.openclaw/workspace-reviewer" + }, + { + "id": "research", + "workspace": "/home/alice/.openclaw/workspace-research" + }, + { + "id": "engineering", + "workspace": "/home/alice/.openclaw/workspace-engineering" + }, + { + "id": "ops", + "workspace": "/home/alice/.openclaw/workspace-ops" + } + ] +} diff --git a/docs/plans/2026-04-08-agent-workspace-bootstrap-report.md b/docs/plans/2026-04-08-agent-workspace-bootstrap-report.md new file mode 100644 index 0000000..aacf9b0 --- /dev/null +++ b/docs/plans/2026-04-08-agent-workspace-bootstrap-report.md @@ -0,0 +1,73 @@ +# 2026-04-08 Agent Workspace Bootstrap Report + +- Generated at: `2026-04-08T04:29:37.793730` + +## Workspaces +- `prompt-optimizer` → `/home/alice/.openclaw/workspace-prompt-optimizer` +- `reviewer` → `/home/alice/.openclaw/workspace-reviewer` +- `research` → `/home/alice/.openclaw/workspace-research` +- `engineering` → `/home/alice/.openclaw/workspace-engineering` +- `ops` → `/home/alice/.openclaw/workspace-ops` + +## Created Directories +- `/home/alice/.openclaw/workspace-prompt-optimizer` +- `/home/alice/.openclaw/workspace-prompt-optimizer/memory` +- `/home/alice/.openclaw/workspace-prompt-optimizer/tasks` +- `/home/alice/.openclaw/workspace-prompt-optimizer/logs` +- `/home/alice/.openclaw/workspace-reviewer` +- `/home/alice/.openclaw/workspace-reviewer/memory` +- `/home/alice/.openclaw/workspace-reviewer/tasks` +- `/home/alice/.openclaw/workspace-reviewer/logs` +- `/home/alice/.openclaw/workspace-research` +- `/home/alice/.openclaw/workspace-research/memory` +- `/home/alice/.openclaw/workspace-research/tasks` +- `/home/alice/.openclaw/workspace-research/logs` +- `/home/alice/.openclaw/workspace-engineering` +- `/home/alice/.openclaw/workspace-engineering/memory` +- `/home/alice/.openclaw/workspace-engineering/tasks` +- `/home/alice/.openclaw/workspace-engineering/logs` +- `/home/alice/.openclaw/workspace-ops` +- `/home/alice/.openclaw/workspace-ops/memory` +- `/home/alice/.openclaw/workspace-ops/tasks` +- `/home/alice/.openclaw/workspace-ops/logs` + +## Created Files +- `/home/alice/.openclaw/workspace-prompt-optimizer/SOUL.md` +- `/home/alice/.openclaw/workspace-prompt-optimizer/AGENTS.md` +- `/home/alice/.openclaw/workspace-prompt-optimizer/USER.md` +- `/home/alice/.openclaw/workspace-prompt-optimizer/WORKFLOW.md` +- `/home/alice/.openclaw/workspace-prompt-optimizer/TASK_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-prompt-optimizer/REPORT_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-reviewer/SOUL.md` +- `/home/alice/.openclaw/workspace-reviewer/AGENTS.md` +- `/home/alice/.openclaw/workspace-reviewer/USER.md` +- `/home/alice/.openclaw/workspace-reviewer/WORKFLOW.md` +- `/home/alice/.openclaw/workspace-reviewer/TASK_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-reviewer/REPORT_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-research/SOUL.md` +- `/home/alice/.openclaw/workspace-research/AGENTS.md` +- `/home/alice/.openclaw/workspace-research/USER.md` +- `/home/alice/.openclaw/workspace-research/WORKFLOW.md` +- `/home/alice/.openclaw/workspace-research/TASK_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-research/REPORT_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-engineering/SOUL.md` +- `/home/alice/.openclaw/workspace-engineering/AGENTS.md` +- `/home/alice/.openclaw/workspace-engineering/USER.md` +- `/home/alice/.openclaw/workspace-engineering/WORKFLOW.md` +- `/home/alice/.openclaw/workspace-engineering/TASK_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-engineering/REPORT_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-ops/SOUL.md` +- `/home/alice/.openclaw/workspace-ops/AGENTS.md` +- `/home/alice/.openclaw/workspace-ops/USER.md` +- `/home/alice/.openclaw/workspace-ops/WORKFLOW.md` +- `/home/alice/.openclaw/workspace-ops/TASK_TEMPLATE.md` +- `/home/alice/.openclaw/workspace-ops/REPORT_TEMPLATE.md` + +## Skipped Existing Files +- (none) + +## Notes +- This bootstrap only creates minimal skeleton files and folders. +- It does not patch gateway config. +- It does not restart OpenClaw. +- It is safe to rerun; existing files are preserved. diff --git a/scripts/bootstrap_agent_workspaces.py b/scripts/bootstrap_agent_workspaces.py new file mode 100644 index 0000000..b424f49 --- /dev/null +++ b/scripts/bootstrap_agent_workspaces.py @@ -0,0 +1,309 @@ +#!/usr/bin/env python3 +from pathlib import Path +from datetime import datetime +import json + +ROOT = Path('/home/alice/.openclaw') +MAIN_WORKSPACE = ROOT / 'workspace' +SCRIPTS_REPORT = MAIN_WORKSPACE / 'docs/plans/2026-04-08-agent-workspace-bootstrap-report.md' +SCRIPTS_MANIFEST = MAIN_WORKSPACE / 'docs/plans/2026-04-08-agent-workspace-bootstrap-manifest.json' + +USER_MD = """# USER.md + +- **Name**: Eric Chang +- **What to call them**: 艾瑞克 / Eric 總管 +- **Timezone**: Asia/Taipei +- **Language**: 繁體中文(臺灣) +- **Preferences**: + - 結構化回報 + - 不可失聯、不可黑盒 + - 高風險動作需先請示 + - 最終正式對上回報由 Eve 負責 + +## Collaboration Boundary +- 你知道總管的偏好,但**不直接對總管發言**。 +- 你的直接對口只有 Eve。 +""" + +REPORT_TEMPLATE = """# REPORT_TEMPLATE.md + +- 任務目標: +- 已做事項: +- 結果: +- 證據: +- 未完成事項: +- 風險: +- 建議狀態:`通過 / 補件 / 退回 / 阻塞` +- 回報對象:Eve +""" + +TASK_TEMPLATE = """# TASK_TEMPLATE.md + +- task_id: +- 任務摘要: +- 目標: +- 限制: +- 主責 agent: +- 協作 agent: +- 狀態: +- 開始時間: +- 最後更新: +- 阻塞項: +- 驗收標準: +- 證據路徑: +""" + +AGENTS = [ + { + 'id': 'prompt-optimizer', + 'name': 'Prompt Optimizer', + 'workspace': ROOT / 'workspace-prompt-optimizer', + 'theme': '任務澄清、結構化、去歧義', + 'emoji': '🧭', + 'mission': '把 Eve 交辦的模糊需求整理成清楚、可執行、可驗收的任務單。', + 'scope': [ + '澄清需求與限制', + '產出乾淨的任務描述與驗收標準', + '避免下游 agent 接到含糊、歪斜或缺漏的指令' + ], + 'not_scope': [ + '不直接對總管回話', + '不自行宣告任務正式完成', + '不越權改變需求方向' + ], + }, + { + 'id': 'reviewer', + 'name': 'Reviewer', + 'workspace': ROOT / 'workspace-reviewer', + 'theme': '嚴謹、保守、驗收導向', + 'emoji': '🛡️', + 'mission': '作為 Eve 的審查輔助者,專注找出漏洞、缺口、風險與不一致。', + 'scope': [ + '審查結果是否符合需求', + '指出證據不足、測試不足、程序不正義', + '提供通過 / 補件 / 退回建議' + ], + 'not_scope': [ + '不是對上窗口', + '不是第二個 Eve', + '不可越權判定最終正式完成' + ], + }, + { + 'id': 'research', + 'name': 'Research', + 'workspace': ROOT / 'workspace-research', + 'theme': '查證、比較、整理資訊', + 'emoji': '🔎', + 'mission': '快速蒐集、比較、整理可信資訊,回傳 Eve 可用的研究結果。', + 'scope': [ + '研究技術選項與文件', + '整理來源、限制、風險與建議', + '避免未經查證的推測' + ], + 'not_scope': [ + '不直接對總管發言', + '不把推測包裝成事實', + '不自行決定產品或架構方向' + ], + }, + { + 'id': 'engineering', + 'name': 'Engineering', + 'workspace': ROOT / 'workspace-engineering', + 'theme': '實作、除錯、測試、交付', + 'emoji': '🧰', + 'mission': '負責程式實作、除錯、測試與技術交付,並留下可驗證證據。', + 'scope': [ + '修改程式與設定檔', + '執行測試與驗證', + '清楚回報結果、限制與風險' + ], + 'not_scope': [ + '不自行越權部署高風險變更', + '不跳過驗證就宣稱完成', + '不直接對總管回話' + ], + }, + { + 'id': 'ops', + 'name': 'Ops', + 'workspace': ROOT / 'workspace-ops', + 'theme': '穩定、維運、診斷、可恢復性', + 'emoji': '⚙️', + 'mission': '負責服務、部署、系統診斷與環境維護,優先考慮穩定性與可恢復性。', + 'scope': [ + '系統診斷、log 調查、服務狀態檢查', + '部署與設定相關作業', + '在高風險動作前先明確標示風險與回復路徑' + ], + 'not_scope': [ + '未授權前不執行高風險操作', + '不把維運動作變成黑盒', + '不直接對總管回話' + ], + }, +] + + +def soul_md(agent): + return f"""# SOUL.md + +你是 {agent['name']}。 + +- 角色主題:{agent['theme']} +- 表情:{agent['emoji']} +- 核心使命:{agent['mission']} + +你的工作不是搶決策權,而是把 Eve 交辦的任務做深、做實、做出可驗證結果。 +語氣保持冷靜、清楚、節制;回報時以結構化條列為主,不誇大,不腦補。 +""" + + +def agents_md(agent): + scope = '\n'.join(f'- {x}' for x in agent['scope']) + not_scope = '\n'.join(f'- {x}' for x in agent['not_scope']) + return f"""# AGENTS.md + +## Identity +- id: `{agent['id']}` +- name: `{agent['name']}` +- direct manager: `Eve / coder` + +## Mission +{agent['mission']} + +## Scope +{scope} + +## Hard Boundaries +{not_scope} +- 只向 Eve 回報,不越級對 Eric 總管發言 +- 遇到阻塞、失敗、風險或不確定性時,必須立即如實回報 +- 沒有證據時,不可宣稱已驗證或已完成 +- 任務可失敗,但不可失聯 + +## Completion Rule +- 你可以回報「已完成實作 / 已完成審查 / 已完成研究」 +- 但不可把任務標記為最終正式完成 +- 最終對上結論由 Eve 整合後回報 +""" + + +def workflow_md(agent): + return f"""# WORKFLOW.md + +## Default Flow +1. 接收 Eve 派工 +2. 先重述目標、限制、驗收標準 +3. 在 `{agent['id']}` 的角色邊界內執行任務 +4. 若出現阻塞、風險或需求歧義,立即回報 Eve +5. 任務完成後,使用結構化格式回報 Eve + +## Reporting Format +- 任務目標 +- 已做事項 +- 結果 +- 證據 +- 風險 / 限制 +- 建議狀態(通過 / 補件 / 退回 / 阻塞) + +## Guardrails +- 不直接對總管發言 +- 不黑盒作業 +- 不腦補未查證事實 +- 高風險動作未授權前不可自行執行 +- 不把中間完成誤報成最終完成 +""" + + +def write_if_missing(path: Path, content: str, created: list, skipped: list): + if path.exists(): + skipped.append(str(path)) + return + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(content) + created.append(str(path)) + + +created = [] +skipped = [] +created_dirs = [] + +for agent in AGENTS: + ws = agent['workspace'] + if not ws.exists(): + ws.mkdir(parents=True, exist_ok=True) + created_dirs.append(str(ws)) + for sub in ['memory', 'tasks', 'logs']: + subdir = ws / sub + if not subdir.exists(): + subdir.mkdir(parents=True, exist_ok=True) + created_dirs.append(str(subdir)) + + write_if_missing(ws / 'SOUL.md', soul_md(agent), created, skipped) + write_if_missing(ws / 'AGENTS.md', agents_md(agent), created, skipped) + write_if_missing(ws / 'USER.md', USER_MD, created, skipped) + write_if_missing(ws / 'WORKFLOW.md', workflow_md(agent), created, skipped) + write_if_missing(ws / 'TASK_TEMPLATE.md', TASK_TEMPLATE, created, skipped) + write_if_missing(ws / 'REPORT_TEMPLATE.md', REPORT_TEMPLATE, created, skipped) + +manifest = { + 'generatedAt': datetime.now().isoformat(), + 'createdDirectories': created_dirs, + 'createdFiles': created, + 'skippedExistingFiles': skipped, + 'agents': [ + { + 'id': a['id'], + 'workspace': str(a['workspace']) + } + for a in AGENTS + ] +} +SCRIPTS_MANIFEST.parent.mkdir(parents=True, exist_ok=True) +SCRIPTS_MANIFEST.write_text(json.dumps(manifest, ensure_ascii=False, indent=2) + '\n') + +lines = [ + '# 2026-04-08 Agent Workspace Bootstrap Report', + '', + f'- Generated at: `{manifest["generatedAt"]}`', + '', + '## Workspaces', +] +for a in AGENTS: + lines.append(f'- `{a["id"]}` → `{a["workspace"]}`') + +lines += [ + '', + '## Created Directories', +] +lines += [f'- `{x}`' for x in created_dirs] or ['- (none)'] +lines += [ + '', + '## Created Files', +] +lines += [f'- `{x}`' for x in created] or ['- (none)'] +lines += [ + '', + '## Skipped Existing Files', +] +lines += [f'- `{x}`' for x in skipped] or ['- (none)'] +lines += [ + '', + '## Notes', + '- This bootstrap only creates minimal skeleton files and folders.', + '- It does not patch gateway config.', + '- It does not restart OpenClaw.', + '- It is safe to rerun; existing files are preserved.', +] +SCRIPTS_REPORT.write_text('\n'.join(lines) + '\n') + +print(json.dumps({ + 'createdDirectories': len(created_dirs), + 'createdFiles': len(created), + 'skippedExistingFiles': len(skipped), + 'report': str(SCRIPTS_REPORT), + 'manifest': str(SCRIPTS_MANIFEST), +}, ensure_ascii=False))