Files
maestro/DESIGN.md
T
wangjia 52169e412c docs: 更新 DESIGN.md v0.2 + README 到现状 [tsk_ExRzLoBj12Fr]
新增/更新:score 调度算法(§8)、双复审 PR 流程(§9)、模型分级与回退
(§10)、自动合并边界(§11,两条路径 + 逃生口)、归档与运行历史(§12)、
macOS 通知(§13)、额度透传(§14)。分期实施状态更新为 Phase 1+2+3 已落地。

README 新增:环境变量表、各功能速览(score 调度公式、双复审流程、模型分级
表、归档 API、通知触发条件、自动合并逻辑);当前状态由「脚手架」更新为实际
已落地功能。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-13 04:10:16 +08:00

217 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Maestro — 多项目 TODO 管理与 Agent 执行系统 · 设计方案 v0.2
本地优先的 daemon:管理多个本地 git 项目的任务,按复杂度分级驱动审批闸,并用后台 agent(Claude Code)自动执行可执行任务。
> **当前实现状态(2025-06**Phase 1(核心 + 看板 + MCP)与 Phase 2(编排器 + 执行器 + 双复审 + 自动合并)已全面落地;Phase 3 通知、额度透传、归档详情已一并完成。本文档对应已实现代码,不再是纯设计预稿。
## Context(为什么做)
前身是 `~/.claude/skills/todo`JSON + HTML 单机原型):单项目、无真正后端、确认靠临时 http hack、无自动执行。它验证了「复杂度分级 + 确认闸 + 看板」的形态,但不可扩展。Maestro 把它升级为正式系统:**多项目、任务层级化、复杂度驱动的审批闸、完整状态机、本地常驻 daemon、每项目一个后台执行 agent、与 Claude Code 深度集成(MCP + Agent SDK**。
## 0. 关键决策
| 维度 | 决策 |
|---|---|
| 运行时 | Node / TypeScript |
| 部署 | 本地优先 daemon(跑在用户机器,管理本地 git 项目) |
| Claude Code 集成 | MCP 服务(任务读写)+ Claude Agent SDKheadless 自动执行) |
| 自动合并边界 | PR accept 默认自动 `--no-ff` 合并(`merge:false` 逃生口:主检出脏时跳合并只通过) |
## 1. 系统总览
```
maestrod(核心 daemon,常驻)
├─ 任务存储 SQLite ├─ 项目注册表
├─ REST + WebSocket API ├─ MCP server(给任意 Claude Code 会话)
├─ 编排器 Orchestrator └─ 每项目 worker 池(执行器)
│ │
Web 看板(多项目·实时·页面内 accept/reject
执行 agentexecutor run):Agent SDK 在 worktree 跑 headless CC
code review agentreviewer run):只读,审 diff 产出报告 + verdict
安全审计 agentsecurity run):只读,仅审安全问题
```
闭环:建任务 →(Hard 分析拆解 / Medium 写方案 / Easy 写操作)→ 前置审批闸 → ready → 编排器 score 调度领取 → worktree 起 headless CC 执行 → verify → 双复审(code review + 安全审计)→ exec_review(带复审报告)→ accept 自动合并 → done。
## 2. 复杂度分级
Hard / Medium / Easy ↔ 旧 tier 1/2/3。每个任务(含子任务)都带 `complexity`,决定它走哪条「产出 + 审批」路径。(见 `src/model/complexity.ts`
## 3. 任务层级
`parent_id` + `depth`;默认 ≤3 层,极复杂 ≤4 层(创建第 5 层时拒绝)。子任务各自带 complexity。**叶子任务才可执行**;被拆解的 Hard 是容器,进度由子任务汇总。
## 4. 三条产出路径与审批闸
| 复杂度 | 产出(执行前) | 前置闸 | reject 规则 |
|---|---|---|---|
| **Hard** | 强制进 plan 分析 → 产出「分析 + 任务拆解(子任务,各带复杂度)」 | `plan_review`accept 才进下一步 | **必须带改进意见** → 退回重做并附 feedback |
| **Medium** | 写「具体方案 = 改动内容 + 为什么这么做」 | `spec_review`accept/reject | 同上(必带意见) |
| **Easy** | 写清「将执行的操作」记录在任务上 | 无前置闸,直接可执行 | — |
**结果闸 `exec_review`**(所有产生改动的执行后、合并前):
- 展示 code review 报告(含 verdictapprove/reject+ 安全审计报告(含 securityVerdict
- `accept` 默认触发 `--no-ff` 自动合并(见 §11),成功后任务状态 → `done`,异步清理 worktree + 任务分支
- `accept` + `merge:false`(逃生口):仅通过审批,不触发合并(手动处理冲突或工作区脏时用)
- `reject`(必带改进意见)→ 返工,`ready` → 等下一轮编排器重新领取
## 5. 状态机(见 `src/model/status.ts`
`init` · `analyzing` · `plan_review` · `decomposed` · `speccing` · `spec_review` · `ready` · `blocked` · `queued` · `executing` · `exec_review` · `failed` · `needs_attention` · `done` · `paused` · `cancelled`
主要流转:
- `init` →(Hard`analyzing``plan_review` —accept→ `decomposed` —子全 done→ `done`;—reject(+意见)→ `analyzing`
- `init` →(Medium`speccing``spec_review` —accept→ `ready`;—reject(+意见)→ `speccing`
- `init` →(Easy,写完 operations)→ `ready`
- `ready` —deps 满足→ `queued``executing``exec_review` —accept(auto-merge)→ `done`;—reject(+意见)→ `ready`(返工)
- `executing``failed` —自动重试 ≤2 次→ `queued` / `needs_attention`3 次失败后)
合法流转表与守卫在 `TRANSITIONS` / `canTransition()`
## 6. 数据模型(见 `src/model/types.ts` 与 `src/store/schema.sql`
- **Project**repo_path、default_branch、verify_cmd、autonomy、model、concurrency、status、logo、sort_order、last_sync_at
- **Task**project_id、parent_id、depth、complexity、status、priority(P0/P1/P2)、deps[]、plan/spec/operations、result(含 summary/verdict/securitySummary/securityVerdict/branch/worktree/commits/prUrl)、assignee、source_ref(旧 todo 映射用)
- **ApprovalRecord**gate(plan/spec/exec)、action、actor、reason(reject 必填)、at
- **Run**kind(planner/executor/reviewer/security)、worktree、branch、status、transcript_ref、claude_session_id、error
- **Event**append-only):审计 + 实时看板推送源
`TaskResult.prUrl` 在合并后写 `merged:<mergeCommit>`,复用字段记录合并产物。
## 7. 编排器与执行 agent(见 `src/daemon/orchestrator.ts`
编排循环由 `MAESTRO_ORCH_INTERVAL`(秒,默认 15)驱动,`0` 关闭。每轮对 `status=active``autonomy≠manual` 的项目:在途数 < `concurrency` 时领任务。
**领取规则**
- 候选 = 叶子(非容器)、status=`ready``queued`(重试/重启遗留)、deps 全 `done`
- `auto-easy` 模式只领 `easy` 任务;`auto-approved` 领全部
- 按 §8 Score 降序排列,同分创建早的优先
**执行流程**(单任务):
1. `executing` → 创 worktree → 起 executor run`runTask`
2. `verify_cmd` → 跑项目校验命令
3. 双复审顺序执行:code review runkind=reviewer)→ 安全审计 runkind=security),任一失败不挡任务(折叠为 `verdict=null`summary 写失败原因)
4. `setResult`branch/diffSummary/commits/summary/verdict/securitySummary/securityVerdict)→ `exec_review`
5. 失败 → `failed` → 最多 2 次重试(重试 2 次 = 最多 3 次执行)→ `needs_attention`
中断现场恢复:daemon 启动时 `reconcileInterrupted()` 把上次退出时仍 `started` 的 run 标 `failed``executing` 的任务 → `failed``queued` 等重新领取。
## 8. Score 调度(见 `src/model/scoring.ts`
在领取那一刻现算(不落库):
```
score = baseScore(priority) // 自身分:P0=3 / P1=2 / P2=1
+ Σ baseScore(dep.priority) for dep where dep.status=done // 链条惯性:前置投入越重越优先出活
+ Σ baseScore(w.priority) for w where w.status=blocked // 解锁效应:等我的人越多越优先
```
- 依赖与解锁均只算一层(不递归):deps 在创建时即固定且只能引用已存在任务,依赖图天然无环;递归会让深链分数膨胀失控,故不递归。
- 同分时按 `createdAt` 升序(先建先出)。
- `GET /api/agents` 暴露 `scheduling: "score"` 字段,前端可展示当前调度模式。
## 9. 双复审 PR 流程(见 `src/executor/reviewer.ts`
执行成功 + verify 通过后,编排器顺序起两个独立的只读 headless Claude Code
| Run | kind | 产出 | 工具白名单 |
|---|---|---|---|
| Code Review | `reviewer` | 做了什么/怎么做/测试情况/逐条问题/结论 + `VERDICT: approve\|reject` | Read/Grep/Glob + `git diff/log/show/status` |
| 安全审计 | `security` | 凭证泄露/注入/权限/UI红线词/部署风险 + `VERDICT: approve\|reject` | 同上(只读) |
- 提示词强制限制:不得修改任何文件,不得执行除 git 只读命令之外的命令,核对执行者自述与实际 diff 一致性。
- 机器解析 `VERDICT` 行(最后一个匹配项),去掉 VERDICT 行后的全文作为 `summary`
- 任一复审失败(抛错或无法起动)→ `summary=失败原因``verdict=null`,不挡主任务进 `exec_review`
- 看板在 `exec_review` 卡片展示两份 markdown 报告 + verdict 徽章(建议通过 / 建议拒绝 / 未复审)。
## 10. 模型分级与回退(见 `src/executor/models.ts`
| 角色 | Easy | Medium | Hard |
|---|---|---|---|
| executor(执行改动) | claude-sonnet-4-6 | claude-opus-4-8 | claude-fable-5 |
| reviewercode review + 安全审计) | claude-sonnet-4-6 | claude-opus-4-8 | claude-opus-4-8 |
优先级(高→低):
1. `project.model`(若设置,executor/reviewer 均用此模型)
2. 环境变量覆盖(`MAESTRO_MODEL_EASY/MEDIUM/HARD``MAESTRO_MODEL_REVIEW_EASY/MEDIUM/HARD`
3. 上表默认值
**回退链**`claude-opus-4-8``claude-sonnet-4-6`。模型不可用(not_found/invalid/permission 等错误含 `model` 关键词)时,同一 run 内自动切换回退模型重试一次;链上全失败才抛错。
## 11. 自动合并边界(见 `src/executor/merge.ts` + `src/api/server.ts`
`POST /api/tasks/:id/decide { action:"accept" }``exec_review` 时默认触发 `mergeBranch`
**两条路径**(避免 git 重复检出问题):
1. `defaultBranch` 正被主检出(`git rev-parse HEAD` 一致)→ 直接在主检出里 `git merge --no-ff`。要求工作区干净,否则拒绝并提示「先提交/暂存,或使用 merge:false 逃生口」。
2. 否则 → 在 `<dataDir>/worktrees/_merge/<taskId>/` 建临时 worktree 检出 defaultBranch 后合并,合并后无论成败都删临时 worktree。
**冲突处理**`git merge --abort` 后复原,error 返回冲突文件列表;两侧分支均无损,任务保留在 `exec_review`
**合并成功后**(异步):删任务分支 `git branch -d <branch>` + 回收任务 worktree(失败只记日志,不影响响应)。
**`merge:false` 逃生口**`POST /decide { action:"accept", merge:false }`,仅通过审批,不合并分支(用于主检出有未提交改动时手动处理)。
## 12. 归档与运行历史(见 `src/api/server.ts` + `src/store/store.ts`
- `GET /api/tasks/:id/events`:单任务全量事件升序(状态流转/审批/运行历史),供归档详情时间线。
- `GET /api/tasks/:id/runs`:该任务全部 run 记录(kind/status/started_at/ended_at/transcript_ref/error)。
- `GET /api/tasks/:id`:含 `result`branch/commits/diffSummary/summary/verdict/securitySummary/securityVerdict/prUrl)。
- 看板归档详情面板:状态流转时间线 + run 列表 + code review / 安全审计报告展开。
## 13. macOS 通知(见 `src/daemon/notify.ts`
daemon 启动时订阅 Store 事件流,符合条件时用 `osascript display notification` 发原生通知:
| 触发事件 | 通知文案 |
|---|---|
| status → `plan_review` / `spec_review` | ⏳ `<任务名>` 等待审核(拆解/方案) |
| status → `exec_review`(复审均通过) | ⏳ `<任务名>` 等待审核(PR |
| status → `exec_review`(任一 verdict=reject | ⚠ `<任务名>` 复审建议拒绝(PR 待审核) |
| status → `needs_attention` | ❌ `<任务名>` 连续失败需人工 |
| `approval.granted` gate=exec | ✅ `<任务名>` 已合并完成 |
- 同一任务同类型通知 60s 内只发一次(抑制重复触发)。
- `MAESTRO_NOTIFY=0` 关闭;非 macOS 平台自动不启用。
- osascript 字符串注入防护:去换行、转义反斜杠/双引号、截断 80 字符。
## 14. 额度透传(见 `src/daemon/usage.ts`
`GET /api/agents` 响应中附带 `usage` 字段,展示 Claude 订阅额度消耗:
```jsonc
{
"usage": {
"session": { "percent": 42, "resetsAt": "2025-06-13T18:00:00Z" }, // 5 小时滚动窗口
"weekly": { "percent": 18, "resetsAt": "2025-06-16T00:00:00Z" } // 7 天窗口
}
}
```
- 数据源:`GET https://api.anthropic.com/api/oauth/usage`,与 Claude Code statusline `rate_limits` 同一端点。
- 凭证:优先 `~/.claude/.credentials.json`OAuth accessToken),其次 macOS keychainservice "Claude Code-credentials")。token 只进内存,绝不写日志/响应。
- 60s 内存缓存 + 并发去重(in-flight 共享);任何失败(无凭证/网络/非200)→ `null`,前端降级显示。
## 15. 后端架构
- 存储 SQLitebetter-sqlite3,单文件零运维);run 转录日志存 JSONL 文件,Run 表引用路径。
- APIRESTCRUD+ WebSocket`/ws`,Store 事件广播,驱动看板实时刷新)。
- 项目绑定:`maestro project add <repo>` 记录 repo 路径/默认分支/verify/autonomy/model/并发;daemon 中央 DB 行。
- Worktree:执行在 repo 的 git worktree(隔离分支),合并由 §11 逻辑控制,不自动 push。
## 16. Web 看板(`web/`
多项目切换(侧栏拖动排序)/ 全局总览;任务树(层级折叠)、复杂度徽章、状态、内联审批闸(accept/reject,reject 必填意见)、实时执行状态、`exec_review` 的 code review + 安全审计报告 + diff/分支信息。实时 WS 驱动。
项目支持自定义 logo(仓库内文件路径或外链),无 logo 时取首字母徽章兜底。
## 17. Claude Code 集成
- **MCP server(交互面)**:项目里的 Claude Code 配 `.mcp.json``maestro-mcp`。工具:`list_projects` / `create_project` / `list_tasks` / `get_task` / `create_task` / `decompose_task` / `write_plan` / `write_spec` / `write_operations` / `update_status` / `get_next_executable` / `get_pending_approvals`accept/reject 在 Web 看板操作)。
- **Agent SDK(自动面)**:编排器用 Claude Agent SDK 起 headless CC 跑 executor / reviewer / security run。
- approve/reject 是用户动作,走看板按钮(或直接 `POST /api/tasks/:id/decide`)。
## 18. 从现有 skill 迁移
`todo.mjs`/JSON 作为 v0 原型被取代。同步引擎(`src/sync/todo-sync.ts`):读旧 `todo/todo.json`tier1/2/3 → hard/medium/easy,单向幂等同步(`POST /api/projects/:id/sync`)。旧侧 done/accepted 任务自动沿合法路径推到 maestro `done`
## 19. 分期实施状态
-**Phase 1(核心,已完成)**daemon + SQLite + 项目注册 + 任务模型 + 状态机 + Web 看板 + MCP(读写 + 审批)+ CLI + todo 同步引擎。
-**Phase 2(自动化,已完成)**:编排器 + score 调度 + Agent SDK executorEasy/Medium/Hard worktree 自动执行)+ verify + 双复审(code review + 安全审计)+ 自动合并(--no-ff + 逃生口)。
-**Phase 3(打磨,核心已完成)**macOS 原生通知 + Claude 订阅额度透传 + 归档详情时间线 + 模型分级(复杂度→模型映射 + env 覆盖 + 回退链)+ 项目 logo + 侧栏拖动排序。
- 🔲 **后续**:并发资源精细监控 / 指标面板 / 可选远程看板 / PR 平台集成(GitHub PR 链接)。
## 20. 风险与注意事项
- **Agent SDK headless 执行可靠性**verify_cmd 把关 + 双复审 + needs_attention 人工兜底。executor run 最多 100 轮、30min 超时兜底;reviewer run 最多 40 轮、15min 超时兜底。
- **自动执行安全**:worktree 隔离(改动不进主检出)+ 不自动 push + merge 需 exec_review accept + 安全审计 run 专门检查凭证/注入/权限问题。
- **中断恢复**daemon 重启后 `reconcileInterrupted()` 自动恢复执行中断的任务(标 failed → queued)。
- **长任务上下文超限**100 turns / 30min 兜底,超时后转 failed → 重试。
- **worktree 泄漏**:合并后异步清理,daemon 启动时 `git worktree prune` 清残留。