2009627eda
核对发现「均可项目级配置」过度声明:实际仅 planner/executor/conflict 走可配的 project.timeout_ms(30min);verify(10min)/复审(15min)/分项checks(10min) 是硬编码 常量、无项目字段。改文档如实描述,不为无人调优的超时再加 3 个配置字段(YAGNI)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1082 lines
64 KiB
HTML
1082 lines
64 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Maestro 三类任务执行方法优化方案</title>
|
||
<style>
|
||
:root {
|
||
--bg: #0f1117;
|
||
--bg2: #1a1d27;
|
||
--bg3: #242736;
|
||
--border: #2e3148;
|
||
--text: #e2e4ef;
|
||
--text2: #9ba3c2;
|
||
--accent: #6c8aff;
|
||
--green: #4caf82;
|
||
--orange: #f0a35b;
|
||
--red: #e05a5a;
|
||
--purple: #b47bff;
|
||
--teal: #4ec9b0;
|
||
}
|
||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||
body {
|
||
background: var(--bg);
|
||
color: var(--text);
|
||
font-family: 'SF Mono', 'Fira Code', monospace;
|
||
font-size: 14px;
|
||
line-height: 1.7;
|
||
}
|
||
header {
|
||
background: var(--bg2);
|
||
border-bottom: 1px solid var(--border);
|
||
padding: 24px 40px;
|
||
position: sticky; top: 0; z-index: 10;
|
||
}
|
||
header h1 { font-size: 20px; color: var(--accent); letter-spacing: .5px; }
|
||
header p { color: var(--text2); font-size: 12px; margin-top: 4px; }
|
||
.toc {
|
||
background: var(--bg2);
|
||
border-bottom: 1px solid var(--border);
|
||
padding: 12px 40px;
|
||
display: flex; gap: 24px; flex-wrap: wrap;
|
||
}
|
||
.toc a { color: var(--text2); text-decoration: none; font-size: 13px; }
|
||
.toc a:hover { color: var(--accent); }
|
||
main { max-width: 1200px; margin: 0 auto; padding: 40px; }
|
||
section { margin-bottom: 60px; }
|
||
h2 {
|
||
font-size: 18px; color: var(--accent);
|
||
border-left: 3px solid var(--accent);
|
||
padding-left: 14px;
|
||
margin-bottom: 24px;
|
||
}
|
||
h3 { font-size: 15px; color: var(--teal); margin: 24px 0 12px; }
|
||
h4 { font-size: 13px; color: var(--orange); margin: 16px 0 8px; }
|
||
|
||
/* Category cards */
|
||
.cat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 16px; }
|
||
.cat-card {
|
||
background: var(--bg2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
padding: 20px;
|
||
}
|
||
.cat-card .label { font-size: 11px; color: var(--text2); letter-spacing: 1px; text-transform: uppercase; margin-bottom: 6px; }
|
||
.cat-card .value { color: var(--text); font-size: 13px; }
|
||
.cat-card .value.changed { color: var(--green); }
|
||
.cat-card .value.new { color: var(--orange); }
|
||
|
||
/* Dim table */
|
||
.dim-table { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||
.dim-table th {
|
||
background: var(--bg3);
|
||
color: var(--text2);
|
||
text-align: left;
|
||
padding: 8px 12px;
|
||
font-weight: 600;
|
||
font-size: 11px;
|
||
letter-spacing: .5px;
|
||
border-bottom: 1px solid var(--border);
|
||
}
|
||
.dim-table td {
|
||
padding: 10px 12px;
|
||
border-bottom: 1px solid var(--border);
|
||
vertical-align: top;
|
||
}
|
||
.dim-table tr:last-child td { border-bottom: none; }
|
||
.dim-table tr:hover td { background: rgba(108,138,255,.04); }
|
||
.dim-label { color: var(--text2); width: 120px; }
|
||
.dim-was { color: var(--text2); font-size: 12px; text-decoration: line-through; opacity: .6; }
|
||
.dim-now { color: var(--green); font-weight: 600; }
|
||
.dim-same { color: var(--text); }
|
||
.tag {
|
||
display: inline-block;
|
||
padding: 1px 7px;
|
||
border-radius: 4px;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
margin-right: 4px;
|
||
}
|
||
.tag-new { background: rgba(240,163,91,.15); color: var(--orange); border: 1px solid rgba(240,163,91,.3); }
|
||
.tag-changed { background: rgba(76,175,130,.15); color: var(--green); border: 1px solid rgba(76,175,130,.3); }
|
||
.tag-keep { background: rgba(155,163,194,.1); color: var(--text2); border: 1px solid rgba(155,163,194,.2); }
|
||
.tag-hard { background: rgba(224,90,90,.15); color: var(--red); border: 1px solid rgba(224,90,90,.3); }
|
||
.tag-fable { background: rgba(180,123,255,.15); color: var(--purple); border: 1px solid rgba(180,123,255,.3); }
|
||
.tag-opus { background: rgba(108,138,255,.15); color: var(--accent); border: 1px solid rgba(108,138,255,.3); }
|
||
.tag-sonnet { background: rgba(78,201,176,.15); color: var(--teal); border: 1px solid rgba(78,201,176,.3); }
|
||
|
||
/* Rules */
|
||
.rule-list { list-style: none; display: flex; flex-direction: column; gap: 10px; }
|
||
.rule-item {
|
||
background: var(--bg2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 6px;
|
||
padding: 14px 16px;
|
||
display: grid;
|
||
grid-template-columns: 28px 1fr;
|
||
gap: 0 12px;
|
||
}
|
||
.rule-num {
|
||
color: var(--accent);
|
||
font-weight: 700;
|
||
font-size: 13px;
|
||
padding-top: 1px;
|
||
}
|
||
.rule-body strong { color: var(--orange); }
|
||
.rule-impl {
|
||
grid-column: 2;
|
||
margin-top: 6px;
|
||
font-size: 12px;
|
||
color: var(--text2);
|
||
border-left: 2px solid var(--border);
|
||
padding-left: 10px;
|
||
}
|
||
.rule-impl code { color: var(--teal); }
|
||
|
||
/* DB tables */
|
||
.db-grid { display: flex; flex-direction: column; gap: 16px; }
|
||
.db-table-card {
|
||
background: var(--bg2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
.db-table-card .db-header {
|
||
background: var(--bg3);
|
||
padding: 10px 16px;
|
||
display: flex; align-items: center; gap: 10px;
|
||
}
|
||
.db-table-card .db-name { font-weight: 700; color: var(--accent); font-size: 14px; }
|
||
.db-table-card .db-desc { color: var(--text2); font-size: 12px; }
|
||
.db-cols { padding: 0; }
|
||
.db-col {
|
||
display: grid;
|
||
grid-template-columns: 180px 120px 1fr;
|
||
gap: 0;
|
||
padding: 8px 16px;
|
||
border-bottom: 1px solid var(--border);
|
||
font-size: 12px;
|
||
}
|
||
.db-col:last-child { border-bottom: none; }
|
||
.db-col .col-name { color: var(--teal); font-weight: 600; }
|
||
.db-col .col-type { color: var(--orange); }
|
||
.db-col .col-note { color: var(--text2); }
|
||
.db-col.highlight { background: rgba(108,138,255,.05); }
|
||
|
||
/* State machine */
|
||
.mermaid-wrap {
|
||
background: var(--bg2);
|
||
border: 1px solid var(--border);
|
||
border-radius: 8px;
|
||
padding: 24px;
|
||
overflow-x: auto;
|
||
}
|
||
.mermaid { display: flex; justify-content: center; }
|
||
|
||
/* Badges */
|
||
.badge {
|
||
display: inline-flex; align-items: center;
|
||
padding: 2px 10px; border-radius: 12px;
|
||
font-size: 11px; font-weight: 700;
|
||
}
|
||
.badge-approved { background: rgba(76,175,130,.2); color: var(--green); }
|
||
.badge-new { background: rgba(240,163,91,.2); color: var(--orange); }
|
||
|
||
/* Status flow */
|
||
.flow-row {
|
||
display: flex; align-items: center; flex-wrap: wrap;
|
||
gap: 8px; margin: 8px 0;
|
||
}
|
||
.st {
|
||
background: var(--bg3);
|
||
border: 1px solid var(--border);
|
||
border-radius: 5px;
|
||
padding: 3px 10px;
|
||
font-size: 12px;
|
||
color: var(--text);
|
||
}
|
||
.st.gate { border-color: var(--orange); color: var(--orange); }
|
||
.st.terminal { border-color: var(--green); color: var(--green); }
|
||
.st.err { border-color: var(--red); color: var(--red); }
|
||
.st.attn { border-color: var(--purple); color: var(--purple); }
|
||
.arrow { color: var(--text2); font-size: 13px; }
|
||
|
||
code { background: var(--bg3); padding: 1px 5px; border-radius: 3px; color: var(--teal); font-size: 12px; }
|
||
.note { color: var(--text2); font-size: 12px; margin-top: 6px; }
|
||
.divider { border: none; border-top: 1px solid var(--border); margin: 32px 0; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<header>
|
||
<h1>Maestro · 三类任务执行方法优化方案</h1>
|
||
<p>2026-06-14 定稿 · 2026-06-25 全部实现并上线 · 含实现状态</p>
|
||
</header>
|
||
|
||
<nav class="toc">
|
||
<a href="#status">★ 实现状态</a>
|
||
<a href="#cat1">① 任务拆解类 (planner)</a>
|
||
<a href="#cat2">② 执行类 (executor)</a>
|
||
<a href="#cat3">③ 解冲突类 (conflict)</a>
|
||
<a href="#rules">④ 通用规则 (13条)</a>
|
||
<a href="#fsm">⑤ 状态机流转图</a>
|
||
<a href="#db">⑥ 数据库结构</a>
|
||
</nav>
|
||
|
||
<main>
|
||
|
||
<!-- ============================================================ 实现状态 -->
|
||
<section id="status">
|
||
<h2>★ 实现状态 <span class="badge badge-approved">✅ 全部上线</span></h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">本方案各项已于 2026-06-25 实现、补测试并经 launchd daemon 端到端实跑验证;下表为「优化点 → 实现 → 提交」对照。线上实测捕获并修复了 3 个单测未覆盖的 bug(DB 迁移漏列 / fable-5 不可用未触发回退 / autoApproveExec 传错 id)。</p>
|
||
|
||
<table class="dim-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:170px">优化点</th>
|
||
<th>实现要点</th>
|
||
<th style="width:90px">状态</th>
|
||
<th style="width:120px">提交</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td class="dim-label">Agent 记忆注入 L1–L4</td>
|
||
<td>L1 上次失败原因(重试任务)· L2 项目级 agent 规范(DB 列)· L3 拆解背景(父意图+兄弟状态)· L4 全局规范文件,注入 4 处 prompt 头部</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>ecea1ae</code> <code>fe7923a</code> <code>74be3ec</code></td></tr>
|
||
<tr><td class="dim-label">① plan 自动放行</td>
|
||
<td>autoApprovePlan:全 easy 子任务 + ≤5 个时跳过 plan_review(项目级开关,默认关)</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>73f80d2</code></td></tr>
|
||
<tr><td class="dim-label">② approve 前硬闸</td>
|
||
<td>分项 lint/typecheck/build 闸 + diff 体量闸 + 复审并行(Promise.all)</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>2d12769</code></td></tr>
|
||
<tr><td class="dim-label">② exec 自动放行</td>
|
||
<td>autoApproveExec:双复审 approve 后跳过 exec_review 自动 --no-ff 合并;抽出共享合并流程 exec-merge.ts</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>1f318c2</code> <code>4c09186</code></td></tr>
|
||
<tr><td class="dim-label">模型可配置(项目维度)</td>
|
||
<td>projects.models(JSON,按角色×复杂度覆盖);默认统一 opus-4.8;优先级 models > 旧 project.model(仅 exec/planner)> env > 默认;回退链 opus→sonnet→fable</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>ff2d7c2</code> <code>59ce391</code></td></tr>
|
||
<tr><td class="dim-label">② diff 声明外文件闸</td>
|
||
<td>tasks.scope_files(glob/路径);scopeFileGate 改动越界=硬闸;planner 拆解出 files 自动填充;executor prompt 注入范围约束</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>59ce391</code></td></tr>
|
||
<tr><td class="dim-label">线上实测 bug 修复</td>
|
||
<td>ensureColumn 漏迁移补列 · isModelError 识别「issue with the selected model」触发回退 · autoApproveExec 传错 id</td>
|
||
<td><span class="badge badge-approved">✅</span></td>
|
||
<td><code>1bf3fec</code> <code>a9c5102</code> <code>4c09186</code></td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p class="note">注:③ 解冲突专用 conflict run / 模型固定档 等部分按方案落地,conflict 模型同样走「项目可配置 + 默认 opus-4.8」。fable-5 在本机不可用,已从内置默认移除,仅在项目级显式配置时使用。</p>
|
||
</section>
|
||
|
||
<!-- ============================================================ CAT 1 -->
|
||
<section id="cat1">
|
||
<h2>① 任务拆解类 (planner) <span class="badge badge-approved">✅ 定稿</span></h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">Hard 任务拆解(decompose) · Medium 写方案(spec) · 只读主仓、不建 worktree</p>
|
||
|
||
<table class="dim-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:130px">维度</th>
|
||
<th style="width:260px">现状</th>
|
||
<th>优化决策</th>
|
||
<th style="width:80px">变更</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="dim-label">触发 / 执行期锁</td>
|
||
<td>Hard→analyzing / Medium→speccing;无写保护</td>
|
||
<td class="dim-now">
|
||
<strong>执行期锁(通用规则)</strong>:任务有在途 run 即锁只读;禁改 title/spec/complexity/deps,禁再调度;run 结束解锁。<br>
|
||
<span class="note">覆盖 AUTO 占位回填竞态;store mutation 入口 + API 层加"在途即拒"校验。</span>
|
||
</td>
|
||
<td><span class="tag tag-new">新增</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">调度并发</td>
|
||
<td>与 executor 共用 concurrency 池</td>
|
||
<td class="dim-same">维持共用池,不改并发模型</td>
|
||
<td><span class="tag tag-keep">不变</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">执行流程</td>
|
||
<td>纯只读 Read/Glob/Grep;maxTurns=60 固定</td>
|
||
<td class="dim-now">
|
||
① 加 <code>Bash(git log/*)</code> <code>Bash(git diff/*)</code> <code>Bash(git show/*)</code>(读历史/演化)<br>
|
||
② decompose prompt 注入 <code>tasks.depth</code> + 剩余可拆层数(≤3层),防无限拆 hard<br>
|
||
③ maxTurns 按复杂度:<strong>hard=90 / medium=60 / easy=40</strong>
|
||
</td>
|
||
<td><span class="tag tag-changed">改进</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">模型 / 档位</td>
|
||
<td>一律 <code>claude-opus-4-8</code></td>
|
||
<td class="dim-now">
|
||
按复杂度分档:<span class="tag tag-hard">hard</span> <span class="tag tag-fable">fable-5</span>
|
||
<span class="tag tag-changed">medium</span> <span class="tag tag-opus">opus-4-8</span>
|
||
<span class="tag tag-keep">easy</span> <span class="tag tag-sonnet">sonnet-4-6</span><br>
|
||
env <code>MAESTRO_MODEL_PLAN_EASY/MEDIUM/HARD</code> 三档可独立覆盖
|
||
</td>
|
||
<td><span class="tag tag-changed">改进</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">输出格式</td>
|
||
<td>spec=3段md;decompose=分析+fenced JSON<br><code>{plan, subtasks:[{title,complexity}]}</code></td>
|
||
<td class="dim-now">
|
||
<strong>decompose</strong> 扩展为:<br>
|
||
① 正文先输出子任务 <strong>Markdown 表格</strong>(标题/复杂度/优先级/依赖序号)供人审<br>
|
||
② 末尾 JSON 扩展:<code>{plan, subtasks:[{title,complexity,priority,deps:[序号]}]}</code><br>
|
||
③ 解析向后兼容(缺 deps/priority 给默认值);deps 序号→taskId 二次映射后写 <code>tasks.deps</code><br>
|
||
<strong>spec</strong> 增加验收标准必填 + 可选影响文件清单
|
||
</td>
|
||
<td><span class="tag tag-changed">扩展</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">是否审批</td>
|
||
<td>decompose→plan_review;spec→spec_review;均强制人审</td>
|
||
<td class="dim-now">
|
||
默认仍人审;<strong>可选自动放行</strong>(默认关):<br>
|
||
<code>auto-approved</code> + 拆解全 easy + 子任务数≤N → 跳过 plan_review 直接 ready<br>
|
||
<span class="note">项目级开关 autoApprovePlan 控制;高风险,默认关</span>
|
||
</td>
|
||
<td><span class="tag tag-new">新增选项</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h4>实现涉及文件</h4>
|
||
<div class="cat-grid" style="margin-top:8px">
|
||
<div class="cat-card">
|
||
<div class="label">models.ts</div>
|
||
<div class="value changed">planner 档位表三档分化:sonnet/opus/fable(当前三档同值 opus)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">runner.ts · runPlanner</div>
|
||
<div class="value changed">allowedTools 加3条 git 只读;maxTurns 改按复杂度取值</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">runner.ts · buildPlannerPrompt</div>
|
||
<div class="value changed">decompose 分支:注入 depth/剩余层数;改要求表格+扩展 JSON</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">pipeline.ts · parseDecompose</div>
|
||
<div class="value changed">解析扩展 JSON 字段 priority/deps,兼容旧格式</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">ingest.ts · decompose-result</div>
|
||
<div class="value changed">priority 落 createTask;deps 序号→taskId 二次映射后 setDeps;判定 autoApprovePlan</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">store.ts + api/server.ts</div>
|
||
<div class="value new">执行期锁:所有 mutation 入口加"在途即拒"校验</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<hr class="divider">
|
||
|
||
<!-- ============================================================ CAT 2 -->
|
||
<section id="cat2">
|
||
<h2>② 执行类 (executor + verify + 双复审) <span class="badge badge-approved">✅ 定稿</span></h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">执行 → verify → 双复审(code+security)→ exec_review 人审 → 合并</p>
|
||
|
||
<h3>当前 approve 前的检查链</h3>
|
||
<div style="overflow-x:auto;margin-bottom:20px">
|
||
<table class="dim-table">
|
||
<thead>
|
||
<tr><th>#</th><th>检查</th><th>当前性质</th><th>优化后</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr><td>1</td><td>executor 完成 + commit 含 task ID</td><td>硬闸</td><td class="dim-same">不变</td></tr>
|
||
<tr><td>2</td><td>verify(<code>project.verifyCmd</code>,10min,未配=通过)</td><td>硬闸(可选)</td><td class="dim-same">不变</td></tr>
|
||
<tr><td>3 <span class="tag tag-new">新</span></td><td>执行前 sync main + 分歧度量</td><td>无</td><td class="dim-now">新增:merge main 进 worktree;冲突/改动面过大→重评估/needs_attention</td></tr>
|
||
<tr><td>4 <span class="tag tag-new">新</span></td><td>分项 lint/typecheck/build 闸</td><td>无</td><td class="dim-now">project 可配 checks;分项报告;任一非0=硬失败</td></tr>
|
||
<tr><td>5 <span class="tag tag-new">新</span></td><td>diff 越界/体量闸</td><td>无</td><td class="dim-now">改了声明外文件 / diff 行数超阈值 → 拦截或告警</td></tr>
|
||
<tr><td>6</td><td>code review(maxTurns40,15min)</td><td style="color:var(--orange)">仅建议</td><td class="dim-now">reject → <strong>硬闸</strong>:退回重执行(带复审意见)而非进 exec_review</td></tr>
|
||
<tr><td>7</td><td>security review(与 code 串行)</td><td style="color:var(--orange)">仅建议</td><td class="dim-now">reject → 硬闸;改<strong>并行</strong>跑(Promise.all,总耗≤15min)</td></tr>
|
||
<tr><td>→</td><td>exec_review 人审</td><td>强制</td><td class="dim-now">补完硬闸后:auto-approved+全绿+双approve → 自动合并(默认关)</td></tr>
|
||
<tr><td>merge</td><td>git merge --no-ff(approve后)</td><td>硬闸</td><td class="dim-same">不变(冲突→③解冲突)</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<table class="dim-table">
|
||
<thead>
|
||
<tr><th style="width:130px">维度</th><th style="width:260px">现状</th><th>优化决策</th><th style="width:80px">变更</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="dim-label">触发</td>
|
||
<td>ready/queued → claimOne runKind=executor</td>
|
||
<td class="dim-now">同上 + 执行前 sync main(通用规则13)</td>
|
||
<td><span class="tag tag-changed">改进</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">调度并发</td>
|
||
<td>共用 concurrency 池;复审在 worker 内串行,不占名额</td>
|
||
<td class="dim-same">维持不变</td>
|
||
<td><span class="tag tag-keep">不变</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">执行流程</td>
|
||
<td>建 worktree → executing → verifying → diff → reviewing(串行) → exec_review</td>
|
||
<td class="dim-now">
|
||
① 新增 sync main 步骤(verify 前)<br>
|
||
② 新增 分项检查 + diff 越界闸(verify 后)<br>
|
||
③ code+security 双复审改 <strong>Promise.all 并行</strong><br>
|
||
④ reject 变硬闸(不进 exec_review,退回/needs_attention)
|
||
</td>
|
||
<td><span class="tag tag-changed">改进</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">模型 / 档位</td>
|
||
<td>reviewer easy=sonnet/medium=opus/hard=opus;code+security 共用档;project.model 覆盖全角色</td>
|
||
<td class="dim-now">
|
||
复审统一 <span class="tag tag-fable">fable-5</span>(三档全升)<br>
|
||
<strong>复审不被 project.model 降档</strong>(保自审独立性)
|
||
</td>
|
||
<td><span class="tag tag-changed">升档</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">输出格式</td>
|
||
<td>verdict 二元 approve/reject;均为建议</td>
|
||
<td class="dim-now">verdict 仍二元;但 <strong>reject 变硬闸</strong>(ingest 分流,不再无条件进 exec_review)</td>
|
||
<td><span class="tag tag-changed">硬化</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">是否审批</td>
|
||
<td>双复审后一律 exec_review 强制人审</td>
|
||
<td class="dim-now">
|
||
分阶段:<strong>先补完三项硬闸,再开自动合并</strong><br>
|
||
条件:auto-approved + verify全过 + 分项检查全过 + diff合规 + 双approve → 跳过 exec_review 自动合并(默认关)
|
||
</td>
|
||
<td><span class="tag tag-new">新增选项</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h4>实现涉及文件</h4>
|
||
<div class="cat-grid" style="margin-top:8px">
|
||
<div class="cat-card">
|
||
<div class="label">pipeline.ts</div>
|
||
<div class="value changed">双复审改 Promise.all;新增 sync main 步骤;加 diff 越界判定</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">models.ts · reviewer 档</div>
|
||
<div class="value changed">三档全改 fable-5;pickModel 对 reviewer 角色跳过 project.model</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">ingest.ts · result 分支</div>
|
||
<div class="value changed">按 code/security verdict 分流:reject→退回重执行;双approve+开关→自动合并</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">verify.ts / pipeline</div>
|
||
<div class="value new">分项 lint/typecheck/build 闸(新 project.checks 配置)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">worktree.ts / pipeline</div>
|
||
<div class="value new">执行前 git merge main 进 worktree;分歧度量超阈值→重评估信号</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">protocol.ts</div>
|
||
<div class="value changed">新增 phase=sync-main,emit 新信号类型(重评估/diff越界)</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<hr class="divider">
|
||
|
||
<!-- ============================================================ CAT 3 -->
|
||
<section id="cat3">
|
||
<h2>③ 解冲突类 (conflict agent) <span class="badge badge-new">🆕 新实现</span></h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">当前仅检测冲突+abort,无专用 agent;本轮新建完整解冲突流程</p>
|
||
|
||
<h3>现状硬伤</h3>
|
||
<ul style="color:var(--text2);font-size:13px;margin-left:20px;margin-bottom:16px">
|
||
<li>executor 白名单<strong style="color:var(--red)">没有 git merge</strong>——补救任务被要求 git merge 却跑不了,CC 只能 Read/Edit 硬模拟,极易丢改动</li>
|
||
<li>解冲突标 easy→sonnet,<strong style="color:var(--red)">最弱档</strong>,认知难度远超单文件改动</li>
|
||
<li>补救 worktree 从 defaultBranch 新建分支,operations 文字写"已从 targetBranch 检出",<strong style="color:var(--red)">文案与实际不符</strong></li>
|
||
</ul>
|
||
|
||
<table class="dim-table">
|
||
<thead>
|
||
<tr><th style="width:130px">维度</th><th style="width:200px">现状</th><th>优化决策</th><th style="width:80px">变更</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="dim-label">触发 / 调度</td>
|
||
<td>合并冲突→建 P0 easy 补救任务;按 score 排队等领取</td>
|
||
<td class="dim-now">
|
||
触发不变(自动建补救任务,幂等)<br>
|
||
调度按<strong>最高优先级(P0)插队</strong>:补救任务以 P0 入队,rankByScore 即排队首、名额空出时优先领取;<strong>不中断在途任务</strong>(维持 No-preemption 架构)
|
||
</td>
|
||
<td><span class="tag tag-approved">✅ 维持</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">执行流程</td>
|
||
<td>复用 executor pipeline;CC 靠 Read/Edit 猜着解冲突;无专用模板</td>
|
||
<td class="dim-now">
|
||
<strong>专用 conflict pipeline</strong>:<br>
|
||
1. worker 在补救 worktree 内真正发起 <code>git merge <branch></code> 制造冲突态<br>
|
||
2. CC 以只读+Edit 逐个解冲突文件(白名单加 <code>Bash(git merge:*)</code>)<br>
|
||
3. CC commit 沿用合并 commit message<br>
|
||
4. 走双复审(同②)<br>
|
||
5. exec_review 通过后自动收口原任务
|
||
</td>
|
||
<td><span class="tag tag-new">新建</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">模型 / 档位</td>
|
||
<td>easy → sonnet(最弱)</td>
|
||
<td class="dim-now">固定 <span class="tag tag-fable">fable-5</span>(不随原任务复杂度,恒最强)</td>
|
||
<td><span class="tag tag-changed">大幅升档</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">输出格式</td>
|
||
<td>无专用;executor 自述</td>
|
||
<td class="dim-now">
|
||
<strong>专用解冲突自述模板</strong>:<br>
|
||
解了哪些文件 / 各文件取舍策略 / 保留了双方哪些意图 / 测试结果
|
||
</td>
|
||
<td><span class="tag tag-new">新增</span></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="dim-label">是否审批</td>
|
||
<td>走 exec_review + 合并成功自动收口原任务</td>
|
||
<td class="dim-same">保持;可选纳入②的自动放行条件</td>
|
||
<td><span class="tag tag-keep">不变</span></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<h4>实现涉及文件</h4>
|
||
<div class="cat-grid" style="margin-top:8px">
|
||
<div class="cat-card">
|
||
<div class="label">protocol.ts</div>
|
||
<div class="value new">runKind 加 'conflict';新增 conflict-related OutboxPayload 类型</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">pipeline.ts</div>
|
||
<div class="value new">新增 runConflictPipeline 分支:git merge 触发冲突态 → CC 解 → commit → 双复审</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">runner.ts · buildConflictPrompt</div>
|
||
<div class="value new">专用解冲突 prompt 模板(冲突文件列表/取舍原则/禁丢任一方改动/commit规范)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">models.ts</div>
|
||
<div class="value new">ModelRole 加 'conflict';可按项目配置,默认 opus-4.8(fable-5 已移出内置默认)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">orchestrator.ts</div>
|
||
<div class="value">无需改:补救任务 P0 入队,rankByScore 即排队首;不中断在途(No-preemption 不变)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">store.ts · ensureMergeRemediationTask</div>
|
||
<div class="value changed">complexity 不再固定 easy;operations 改用 conflict runKind 标记,修正 worktree 文案</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<hr class="divider">
|
||
|
||
<!-- ============================================================ RULES -->
|
||
<section id="rules">
|
||
<h2>④ 任务通用规则(13条,全部采纳)</h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">跨三类的横切规则;蓝色=本轮新引入;灰色=已有不变量明文固化</p>
|
||
|
||
<ul class="rule-list">
|
||
<li class="rule-item">
|
||
<div class="rule-num">1</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-new">新增</span>
|
||
<strong>执行期锁</strong>:任务有在途 run(planner/executor/reviewer/conflict)即锁只读——禁改 title/spec/complexity/deps 等任何字段,禁再调度;run 结束(finishRun/failAttempt/reap)解锁。
|
||
<div class="rule-impl">实现:store mutation 入口 + API 层加"在途即拒"校验;orchestrator.claimable 已天然排除,保持</div>
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">2</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>worktree 隔离</strong>:写类 run(executor/conflict)在独立 worktree 内,禁碰 worktree 外文件;planner/reviewer 只读,不建 worktree。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">3</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>不 push / 不部署</strong>:任何 run 都不得 <code>git push</code> / 对外发布 / 部署;解冲突的 merge 是受控本地合并,不 push。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">4</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>commit 含 task ID</strong>:所有产出 commit message 必带任务 ID;<code>ensureCommitted</code> 兜底。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">5</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-changed">改进</span>
|
||
<strong>模型回退链</strong>:模型不可用 → <code>fable-5 → opus-4-8 → sonnet-4-6</code> 回退(fable 置链首),单 run 内只重试一次。
|
||
<div class="rule-impl">实现:<code>models.ts</code> <code>MODEL_FALLBACK_CHAIN</code> 改为 <code>['claude-fable-5','claude-opus-4-8','claude-sonnet-4-6']</code></div>
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">6</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>重试退避 + 上限升级</strong>:失败按退避(backoff,间隔递增)自动重试;超 <code>max_retries</code>(项目配,默认2)→ 转 <code>needs_attention</code>(需人工介入)。
|
||
<div class="rule-impl">needs_attention = 任务卡住不再自动重试,等人改/requeue/取消。触发:①失败超重试上限 ②合并冲突 ③歧义</div>
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">7</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-new">新增</span>
|
||
<strong>自动放行默认关</strong>:所有"跳过人审自动放行"(plan/exec)默认关闭,须项目级开关 + <code>auto-approved</code> autonomy 才生效。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">8</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>审批 reject 必带意见</strong>:plan/spec/exec 的 reject 必须带 reason,按状态机回流。
|
||
<div class="rule-impl">plan_review→analyzing · spec_review→speccing · exec_review→ready</div>
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">9</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-changed">强化</span>
|
||
<strong>复审独立性</strong>:复审只读、与执行分离、用最强模型(fable-5);复审不被 project.model 降档;任一 verdict=reject 变硬闸(退回重执行,不进 exec_review)。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">10</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>daemon 唯一 DB 写者 / worker 不碰 DB</strong>:进程模型铁律;状态变更只经 <code>transition()</code> 守卫(<code>canTransition</code>)。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">11</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-new">新增</span>
|
||
<strong>统一输出锚点</strong>:每类 run 固定输出模板——planner=表格+JSON · executor=自述 · reviewer=模板+VERDICT · conflict=解冲突自述,便于机器解析 + 人审。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">12</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-keep">固化</span>
|
||
<strong>超时分层</strong>:planner/executor/conflict 30min(共用 <code>project.timeout_ms</code>,<strong>项目级可配</strong>)· verify 10min · 复审 15min(并行)· 分项 checks 单项 10min——后三者为固定常量(合理默认,暂不单列项目配置)。
|
||
</div>
|
||
</li>
|
||
<li class="rule-item">
|
||
<div class="rule-num">13</div>
|
||
<div class="rule-body">
|
||
<span class="tag tag-approved">✅ 已实现</span>
|
||
<strong>执行前同步 main + 分歧重评估</strong>:任务正式执行前,先把 defaultBranch 最新代码 merge 进 worktree;若改动过大 / 耦合过深 / 存在逻辑冲突,则触发方案重评估(转 needs_attention 待人工)而非盲目继续。
|
||
<div class="rule-impl">实现:sync main 前先跑 <code>reevalScopeGate</code>——以 <code>git diff HEAD...origin/main</code> 取 main 自分支点以来改动的文件,与任务声明范围 <code>scopeFiles</code> 求交集;非空即 emit <code>needs-reeval</code> → daemon <code>markReeval</code> 直接转 <code>needs_attention</code>(不重试、不计失败次数、run 收尾 cancelled)。与③协同:执行前同步冲突=早发现;执行后合并冲突=③兜底</div>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<hr class="divider">
|
||
|
||
<!-- ============================================================ FSM -->
|
||
<section id="fsm">
|
||
<h2>⑤ 任务状态机流转图</h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">据 <code>src/model/status.ts</code> TRANSITIONS 真实表绘制;paused/cancelled 通用终态图中略去</p>
|
||
|
||
<h3>主干流转(按复杂度)</h3>
|
||
|
||
<div style="margin-bottom:16px">
|
||
<h4>Hard 任务</h4>
|
||
<div class="flow-row">
|
||
<span class="st">init</span><span class="arrow">→</span>
|
||
<span class="st">analyzing</span><span class="arrow">→(拆解完成)</span>
|
||
<span class="st gate">plan_review ⊙</span><span class="arrow">→(accept)</span>
|
||
<span class="st">decomposed</span><span class="arrow">→(子全done)</span>
|
||
<span class="st terminal">done</span>
|
||
</div>
|
||
<div class="flow-row" style="margin-left:140px">
|
||
<span class="arrow">reject(+意见)↙</span>
|
||
<span class="st">analyzing</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-bottom:16px">
|
||
<h4>Medium 任务</h4>
|
||
<div class="flow-row">
|
||
<span class="st">init</span><span class="arrow">→</span>
|
||
<span class="st">speccing</span><span class="arrow">→(方案完成)</span>
|
||
<span class="st gate">spec_review ⊙</span><span class="arrow">→(accept)</span>
|
||
<span class="st">ready</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="margin-bottom:20px">
|
||
<h4>Easy 任务</h4>
|
||
<div class="flow-row">
|
||
<span class="st">init</span><span class="arrow">→</span>
|
||
<span class="st">ready</span>
|
||
</div>
|
||
</div>
|
||
|
||
<h3>执行主链(所有复杂度共用,从 ready 开始)</h3>
|
||
<div class="flow-row">
|
||
<span class="st">ready</span><span class="arrow">→(调度)</span>
|
||
<span class="st">queued</span><span class="arrow">→(worker起跑)</span>
|
||
<span class="st">executing</span>
|
||
<span class="arrow">→(完成)</span>
|
||
<span class="st gate">exec_review ⊙</span>
|
||
<span class="arrow">→(accept+合并)</span>
|
||
<span class="st terminal">done</span>
|
||
</div>
|
||
<div class="flow-row" style="margin-top:8px;margin-left:290px">
|
||
<span class="arrow">reject(+意见)↓</span>
|
||
<span class="st">ready</span>
|
||
<span class="arrow">(带复审意见重做)</span>
|
||
</div>
|
||
|
||
<h3 style="margin-top:20px">失败 / 重评估链</h3>
|
||
<div class="flow-row">
|
||
<span class="st">executing</span><span class="arrow">→</span>
|
||
<span class="st err">failed</span>
|
||
<span class="arrow">→(退避重试)</span>
|
||
<span class="st">queued</span>
|
||
</div>
|
||
<div class="flow-row">
|
||
<span class="st err">failed</span><span class="arrow">→(超限)</span>
|
||
<span class="st attn">needs_attention</span>
|
||
<span class="arrow">→(人工requeue)</span>
|
||
<span class="st">ready / queued / analyzing / speccing</span>
|
||
</div>
|
||
|
||
<h3>合并冲突链(③)</h3>
|
||
<div class="flow-row">
|
||
<span class="st gate">exec_review</span>
|
||
<span class="arrow">→(approve but 冲突)</span>
|
||
<span class="st attn">conflict run (P0 插队)</span>
|
||
<span class="arrow">→(解决+复审)</span>
|
||
<span class="st gate">exec_review</span>
|
||
<span class="arrow">→(approve)</span>
|
||
<span class="st terminal">done</span>
|
||
<span class="arrow">→自动收口原任务</span>
|
||
</div>
|
||
|
||
<h3 style="margin-top:20px">完整状态机(自包含 SVG · 圆节点)</h3>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1160 600" style="width:100%;display:block;margin:16px 0">
|
||
<defs>
|
||
<marker id="fsm-o" markerWidth="7" markerHeight="6" refX="6" refY="3" orient="auto"><polygon points="0 0,7 3,0 6" fill="#d6783b"/></marker>
|
||
<marker id="fsm-b" markerWidth="7" markerHeight="6" refX="6" refY="3" orient="auto"><polygon points="0 0,7 3,0 6" fill="#5b8fd6"/></marker>
|
||
<marker id="fsm-g" markerWidth="7" markerHeight="6" refX="6" refY="3" orient="auto"><polygon points="0 0,7 3,0 6" fill="#82b366"/></marker>
|
||
<marker id="fsm-p" markerWidth="7" markerHeight="6" refX="6" refY="3" orient="auto"><polygon points="0 0,7 3,0 6" fill="#9673a6"/></marker>
|
||
<marker id="fsm-r" markerWidth="7" markerHeight="6" refX="6" refY="3" orient="auto"><polygon points="0 0,7 3,0 6" fill="#b85450"/></marker>
|
||
<marker id="fsm-a" markerWidth="7" markerHeight="6" refX="6" refY="3" orient="auto"><polygon points="0 0,7 3,0 6" fill="#d6b656"/></marker>
|
||
</defs>
|
||
<text x="20" y="24" font-family="monospace" font-size="14" font-weight="bold" fill="#e8e8e8">Maestro 任务状态机(据 src/model/status.ts TRANSITIONS)</text>
|
||
<!-- edges -->
|
||
<path d="M 80 295 Q 160 190 206 108" stroke="#d6783b" stroke-width="1.5" fill="none" marker-end="url(#fsm-o)"/>
|
||
<path d="M 92 298 Q 160 245 198 205" stroke="#5b8fd6" stroke-width="1.5" fill="none" marker-end="url(#fsm-b)"/>
|
||
<path d="M 104 310 Q 160 310 202 310" stroke="#82b366" stroke-width="1.5" fill="none" marker-end="url(#fsm-g)"/>
|
||
<path d="M 308 90 Q 360 90 386 90" stroke="#d6783b" stroke-width="1.5" fill="none" marker-end="url(#fsm-o)"/>
|
||
<path d="M 512 90 Q 568 90 594 90" stroke="#d6783b" stroke-width="1.5" fill="none" marker-end="url(#fsm-o)"/>
|
||
<path d="M 430 73 Q 350 42 272 73" stroke="#b85450" stroke-width="1.5" fill="none" marker-end="url(#fsm-r)"/>
|
||
<path d="M 718 98 Q 910 180 1010 295" stroke="#d6783b" stroke-width="1.5" fill="none" marker-end="url(#fsm-o)"/>
|
||
<path d="M 598 80 Q 430 28 262 75" stroke="#d6783b" stroke-width="1.5" fill="none" stroke-dasharray="4,3" marker-end="url(#fsm-o)"/>
|
||
<path d="M 304 190 Q 360 190 386 190" stroke="#5b8fd6" stroke-width="1.5" fill="none" marker-end="url(#fsm-b)"/>
|
||
<path d="M 452 208 Q 360 252 282 294" stroke="#5b8fd6" stroke-width="1.5" fill="none" marker-end="url(#fsm-g)"/>
|
||
<path d="M 430 176 Q 350 150 272 177" stroke="#b85450" stroke-width="1.5" fill="none" marker-end="url(#fsm-r)"/>
|
||
<path d="M 296 310 Q 360 310 388 310" stroke="#82b366" stroke-width="1.5" fill="none" marker-end="url(#fsm-g)"/>
|
||
<path d="M 388 326 Q 350 346 308 328" stroke="#82b366" stroke-width="1.5" fill="none" marker-end="url(#fsm-g)"/>
|
||
<path d="M 470 310 Q 518 310 558 310" stroke="#9673a6" stroke-width="1.5" fill="none" marker-end="url(#fsm-p)"/>
|
||
<path d="M 658 310 Q 720 310 760 310" stroke="#9673a6" stroke-width="1.5" fill="none" marker-end="url(#fsm-p)"/>
|
||
<path d="M 874 310 Q 958 310 1012 310" stroke="#9673a6" stroke-width="1.5" fill="none" marker-end="url(#fsm-p)"/>
|
||
<path d="M 800 328 Q 520 422 288 326" stroke="#b85450" stroke-width="1.5" fill="none" marker-end="url(#fsm-r)"/>
|
||
<path d="M 250 328 Q 250 382 250 420" stroke="#b85450" stroke-width="1.5" fill="none" marker-end="url(#fsm-r)"/>
|
||
<path d="M 286 424 Q 326 382 282 328" stroke="#82b366" stroke-width="1.5" fill="none" marker-end="url(#fsm-g)"/>
|
||
<path d="M 652 326 Q 736 384 788 424" stroke="#b85450" stroke-width="1.5" fill="none" marker-end="url(#fsm-r)"/>
|
||
<path d="M 578 326 Q 556 392 588 430" stroke="#d6b656" stroke-width="1.5" fill="none" stroke-dasharray="4,3" marker-end="url(#fsm-a)"/>
|
||
<path d="M 786 432 Q 600 358 470 326" stroke="#d6783b" stroke-width="1.5" fill="none" marker-end="url(#fsm-o)"/>
|
||
<path d="M 762 448 Q 720 448 678 448" stroke="#b85450" stroke-width="1.5" fill="none" marker-end="url(#fsm-r)"/>
|
||
<path d="M 558 434 Q 410 378 292 332" stroke="#d6783b" stroke-width="1.5" fill="none" marker-end="url(#fsm-o)"/>
|
||
<!-- edge labels -->
|
||
<text x="148" y="198" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">hard</text>
|
||
<text x="150" y="250" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#5b8fd6">medium</text>
|
||
<text x="156" y="302" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#82b366">easy</text>
|
||
<text x="350" y="80" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">拆解完成</text>
|
||
<text x="560" y="80" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">accept</text>
|
||
<text x="350" y="50" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#b85450">reject</text>
|
||
<text x="900" y="172" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">子任务全 done</text>
|
||
<text x="430" y="26" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">重拆</text>
|
||
<text x="350" y="180" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#5b8fd6">方案完成</text>
|
||
<text x="356" y="256" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#82b366">accept</text>
|
||
<text x="350" y="150" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#b85450">reject</text>
|
||
<text x="348" y="302" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#82b366">调度领取</text>
|
||
<text x="350" y="346" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#82b366">退回</text>
|
||
<text x="516" y="302" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#9673a6">worker 启动</text>
|
||
<text x="716" y="302" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#9673a6">执行完成</text>
|
||
<text x="958" y="302" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#9673a6">accept(合并)</text>
|
||
<text x="540" y="402" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#b85450">reject(返工)</text>
|
||
<text x="182" y="386" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#b85450">依赖未满足</text>
|
||
<text x="330" y="386" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#82b366">依赖满足</text>
|
||
<text x="772" y="360" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#b85450">执行失败</text>
|
||
<text x="470" y="396" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6b656">分歧重评估(规则13)</text>
|
||
<text x="624" y="360" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">退避重试</text>
|
||
<text x="712" y="440" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#b85450">超限</text>
|
||
<text x="430" y="372" text-anchor="middle" font-family="sans-serif" font-size="8.5" fill="#d6783b">人工 requeue</text>
|
||
<!-- nodes -->
|
||
<ellipse cx="64" cy="310" rx="40" ry="18" fill="#2a2a2a" stroke="#888888"/>
|
||
<text x="64" y="314" text-anchor="middle" font-family="monospace" font-size="11" fill="#aaaaaa">init</text>
|
||
<ellipse cx="250" cy="90" rx="58" ry="18" fill="#2e2014" stroke="#d6783b"/>
|
||
<text x="250" y="94" text-anchor="middle" font-family="monospace" font-size="11" fill="#f0a060">analyzing</text>
|
||
<ellipse cx="450" cy="90" rx="62" ry="18" fill="#2e2014" stroke="#d6783b"/>
|
||
<text x="450" y="94" text-anchor="middle" font-family="monospace" font-size="11" fill="#f0a060">plan_review</text>
|
||
<ellipse cx="660" cy="90" rx="64" ry="18" fill="#2e2014" stroke="#d6783b"/>
|
||
<text x="660" y="94" text-anchor="middle" font-family="monospace" font-size="11" fill="#f0a060">decomposed</text>
|
||
<ellipse cx="250" cy="190" rx="54" ry="18" fill="#14233a" stroke="#5b8fd6"/>
|
||
<text x="250" y="194" text-anchor="middle" font-family="monospace" font-size="11" fill="#7ab0ff">speccing</text>
|
||
<ellipse cx="450" cy="190" rx="62" ry="18" fill="#14233a" stroke="#5b8fd6"/>
|
||
<text x="450" y="194" text-anchor="middle" font-family="monospace" font-size="11" fill="#7ab0ff">spec_review</text>
|
||
<ellipse cx="250" cy="310" rx="46" ry="18" fill="#1a2e1a" stroke="#82b366"/>
|
||
<text x="250" y="314" text-anchor="middle" font-family="monospace" font-size="11" fill="#82b366">ready</text>
|
||
<ellipse cx="420" cy="310" rx="50" ry="18" fill="#1a2e1a" stroke="#82b366"/>
|
||
<text x="420" y="314" text-anchor="middle" font-family="monospace" font-size="11" fill="#82b366">queued</text>
|
||
<ellipse cx="600" cy="310" rx="58" ry="18" fill="#221a2e" stroke="#9673a6"/>
|
||
<text x="600" y="314" text-anchor="middle" font-family="monospace" font-size="11" fill="#c4a8d4">executing</text>
|
||
<ellipse cx="810" cy="310" rx="64" ry="18" fill="#221a2e" stroke="#9673a6"/>
|
||
<text x="810" y="314" text-anchor="middle" font-family="monospace" font-size="11" fill="#c4a8d4">exec_review</text>
|
||
<ellipse cx="1050" cy="310" rx="42" ry="18" fill="#1a472a" stroke="#2d7a40"/>
|
||
<text x="1050" y="314" text-anchor="middle" font-family="monospace" font-size="11" font-weight="bold" fill="#ffffff">done</text>
|
||
<ellipse cx="250" cy="440" rx="50" ry="18" fill="#2e1a1a" stroke="#b85450"/>
|
||
<text x="250" y="444" text-anchor="middle" font-family="monospace" font-size="11" fill="#e07070">blocked</text>
|
||
<ellipse cx="810" cy="440" rx="46" ry="18" fill="#2e1a1a" stroke="#b85450"/>
|
||
<text x="810" y="444" text-anchor="middle" font-family="monospace" font-size="11" fill="#e07070">failed</text>
|
||
<ellipse cx="600" cy="448" rx="76" ry="18" fill="#2e2014" stroke="#d6b656"/>
|
||
<text x="600" y="452" text-anchor="middle" font-family="monospace" font-size="11" fill="#e6c860">needs_attention</text>
|
||
<ellipse cx="110" cy="545" rx="48" ry="18" fill="#2e2a14" stroke="#d6b656"/>
|
||
<text x="110" y="549" text-anchor="middle" font-family="monospace" font-size="11" fill="#d6b656">paused</text>
|
||
<ellipse cx="300" cy="545" rx="58" ry="18" fill="#2e2e2e" stroke="#555555"/>
|
||
<text x="300" y="549" text-anchor="middle" font-family="monospace" font-size="11" font-weight="bold" fill="#888888">cancelled</text>
|
||
<!-- legend -->
|
||
<rect x="900" y="470" width="240" height="112" fill="#11161f" stroke="#252b36" rx="4"/>
|
||
<line x1="912" y1="486" x2="934" y2="486" stroke="#d6783b" stroke-width="2"/><text x="942" y="489" font-family="sans-serif" font-size="9" fill="#9aa4b2">Hard 拆解</text>
|
||
<line x1="912" y1="502" x2="934" y2="502" stroke="#5b8fd6" stroke-width="2"/><text x="942" y="505" font-family="sans-serif" font-size="9" fill="#9aa4b2">Medium 方案</text>
|
||
<line x1="912" y1="518" x2="934" y2="518" stroke="#82b366" stroke-width="2"/><text x="942" y="521" font-family="sans-serif" font-size="9" fill="#9aa4b2">执行调度</text>
|
||
<line x1="912" y1="534" x2="934" y2="534" stroke="#9673a6" stroke-width="2"/><text x="942" y="537" font-family="sans-serif" font-size="9" fill="#9aa4b2">Agent 运行</text>
|
||
<line x1="912" y1="550" x2="934" y2="550" stroke="#b85450" stroke-width="2"/><text x="942" y="553" font-family="sans-serif" font-size="9" fill="#9aa4b2">异常 / 失败</text>
|
||
<line x1="912" y1="566" x2="934" y2="566" stroke="#d6b656" stroke-width="2" stroke-dasharray="4,3"/><text x="942" y="569" font-family="sans-serif" font-size="9" fill="#9aa4b2">规则13 分歧重评估</text>
|
||
<text x="20" y="590" font-family="sans-serif" font-size="9" fill="#64748b">注:needs_attention 可回 ready/queued/analyzing/speccing(人工 requeue,图中以单边代表);paused 与所有活跃态双向互通、cancelled 任意态可达(略去以保主干清晰)。</text>
|
||
</svg>
|
||
|
||
<div style="margin-top:12px;color:var(--text2);font-size:12px">
|
||
⊙ = 人审闸(plan_review / spec_review / exec_review) ·
|
||
paused ↔ 所有活跃态互通(图中略) ·
|
||
cancelled = 所有活跃态均可取消(图中略)
|
||
</div>
|
||
</section>
|
||
|
||
<hr class="divider">
|
||
|
||
<!-- ============================================================ DB -->
|
||
<section id="db">
|
||
<h2>⑥ 数据库结构(单一 SQLite · <code>~/.maestro/</code>)</h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">WAL 模式,外键开。三类任务是 tasks 表上按 complexity+status+run.kind 区分的行为,不是独立表。schema 见 <code>src/store/schema.sql</code></p>
|
||
|
||
<div class="db-grid">
|
||
<div class="db-table-card">
|
||
<div class="db-header">
|
||
<span class="db-name">projects</span>
|
||
<span class="db-desc">项目配置</span>
|
||
</div>
|
||
<div class="db-cols">
|
||
<div class="db-col"><span class="col-name">id</span><span class="col-type">TEXT PK</span><span class="col-note">唯一标识</span></div>
|
||
<div class="db-col"><span class="col-name">autonomy</span><span class="col-type">TEXT</span><span class="col-note">manual | auto-easy | auto-approved</span></div>
|
||
<div class="db-col"><span class="col-name">concurrency</span><span class="col-type">INTEGER</span><span class="col-note">并发 run 上限(默认1)</span></div>
|
||
<div class="db-col"><span class="col-name">max_retries</span><span class="col-type">INTEGER</span><span class="col-note">失败最大重试次数(默认2)</span></div>
|
||
<div class="db-col"><span class="col-name">timeout_ms</span><span class="col-type">INTEGER</span><span class="col-note">单次执行超时毫秒(默认30min)</span></div>
|
||
<div class="db-col"><span class="col-name">verify_cmd</span><span class="col-type">TEXT?</span><span class="col-note">验证命令(未配=视为通过)</span></div>
|
||
<div class="db-col"><span class="col-name">model</span><span class="col-type">TEXT?</span><span class="col-note">旧·单项目级模型覆盖(仅 exec/planner)</span></div>
|
||
<div class="db-col highlight"><span class="col-name">models</span><span class="col-type">TEXT?</span><span class="col-note">🆕 按角色×复杂度模型配置 JSON(executor/planner/reviewer/conflict;默认 opus-4.8)</span></div>
|
||
<div class="db-col highlight"><span class="col-name">agent_rules</span><span class="col-type">TEXT?</span><span class="col-note">🆕 项目级 agent 规范(注入 4 处 prompt,记忆 L2)</span></div>
|
||
<div class="db-col highlight"><span class="col-name">checks</span><span class="col-type">TEXT?</span><span class="col-note">🆕 分项检查配置 JSON(lint/typecheck/build)</span></div>
|
||
<div class="db-col highlight"><span class="col-name">auto_approve_plan</span><span class="col-type">INTEGER</span><span class="col-note">🆕 全easy子任务自动放行(0=关)</span></div>
|
||
<div class="db-col highlight"><span class="col-name">auto_approve_exec</span><span class="col-type">INTEGER</span><span class="col-note">🆕 双approve自动合并(0=关)</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="db-table-card">
|
||
<div class="db-header">
|
||
<span class="db-name">tasks</span>
|
||
<span class="db-desc">任务主表(三类共用)</span>
|
||
</div>
|
||
<div class="db-cols">
|
||
<div class="db-col"><span class="col-name">id</span><span class="col-type">TEXT PK</span><span class="col-note"></span></div>
|
||
<div class="db-col"><span class="col-name">parent_id</span><span class="col-type">TEXT?</span><span class="col-note">Hard 拆解的父任务</span></div>
|
||
<div class="db-col"><span class="col-name">depth</span><span class="col-type">INTEGER</span><span class="col-note">1..4;cat1 直接读此值注入 decompose prompt</span></div>
|
||
<div class="db-col"><span class="col-name">complexity</span><span class="col-type">TEXT</span><span class="col-note">hard | medium | easy(决定 run 类型和模型档)</span></div>
|
||
<div class="db-col"><span class="col-name">status</span><span class="col-type">TEXT</span><span class="col-note">见状态机(16种)</span></div>
|
||
<div class="db-col"><span class="col-name">priority</span><span class="col-type">INTEGER</span><span class="col-note">P0=最高 / P1=中 / P2=最低;cat1 planner 可直接输出</span></div>
|
||
<div class="db-col"><span class="col-name">deps</span><span class="col-type">TEXT</span><span class="col-note">JSON ids;cat1 planner 可直接产出,序号→id 二次映射后写入</span></div>
|
||
<div class="db-col highlight"><span class="col-name">scope_files</span><span class="col-type">TEXT?</span><span class="col-note">🆕 声明改动范围 glob JSON;越界硬闸 + 规则13 分歧重评估据此判定</span></div>
|
||
<div class="db-col"><span class="col-name">plan</span><span class="col-type">TEXT?</span><span class="col-note">Hard:分析+拆解(decompose 写入)</span></div>
|
||
<div class="db-col"><span class="col-name">spec</span><span class="col-type">TEXT?</span><span class="col-note">Medium:改动方案(spec 写入)</span></div>
|
||
<div class="db-col"><span class="col-name">operations</span><span class="col-type">TEXT?</span><span class="col-note">Easy:操作说明</span></div>
|
||
<div class="db-col"><span class="col-name">result</span><span class="col-type">TEXT?</span><span class="col-note">JSON TaskResult(branch/worktree/diffSummary/verdict/securityVerdict/mergeTaskId…)</span></div>
|
||
<div class="db-col"><span class="col-name">retry_baseline</span><span class="col-type">INTEGER</span><span class="col-note">上次手动重投时的失败数基线(重置重试计数用)</span></div>
|
||
<div class="db-col"><span class="col-name">next_eligible_at</span><span class="col-type">TEXT?</span><span class="col-note">退避截止时间;早于此不被调度(null=即刻可领)</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="db-table-card">
|
||
<div class="db-header">
|
||
<span class="db-name">runs</span>
|
||
<span class="db-desc">每次 agent 运行记录</span>
|
||
</div>
|
||
<div class="db-cols">
|
||
<div class="db-col"><span class="col-name">kind</span><span class="col-type">TEXT</span><span class="col-note">planner | executor | reviewer | security <strong style="color:var(--orange)">+ conflict(本轮新增)</strong></span></div>
|
||
<div class="db-col"><span class="col-name">status</span><span class="col-type">TEXT</span><span class="col-note">started | succeeded | failed | cancelled</span></div>
|
||
<div class="db-col"><span class="col-name">worktree</span><span class="col-type">TEXT?</span><span class="col-note">executor/conflict 有;planner/reviewer 无</span></div>
|
||
<div class="db-col"><span class="col-name">worker_pid</span><span class="col-type">INTEGER?</span><span class="col-note">daemon 判活用</span></div>
|
||
<div class="db-col"><span class="col-name">last_seq</span><span class="col-type">INTEGER</span><span class="col-note">已 ingest 的 outbox 最大 seq(幂等游标)</span></div>
|
||
<div class="db-col"><span class="col-name">transcript_ref</span><span class="col-type">TEXT?</span><span class="col-note">转录 .jsonl 路径</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="db-table-card">
|
||
<div class="db-header">
|
||
<span class="db-name">approvals</span>
|
||
<span class="db-desc">审批闸记录(不可变日志)</span>
|
||
</div>
|
||
<div class="db-cols">
|
||
<div class="db-col"><span class="col-name">gate</span><span class="col-type">TEXT</span><span class="col-note">plan | spec | exec</span></div>
|
||
<div class="db-col"><span class="col-name">action</span><span class="col-type">TEXT</span><span class="col-note">accept | reject</span></div>
|
||
<div class="db-col"><span class="col-name">reason</span><span class="col-type">TEXT?</span><span class="col-note">reject 时必填</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="db-table-card">
|
||
<div class="db-header">
|
||
<span class="db-name">events</span>
|
||
<span class="db-desc">追加型事件日志(审计 + 看板实时推送源)</span>
|
||
</div>
|
||
<div class="db-cols">
|
||
<div class="db-col"><span class="col-name">type</span><span class="col-type">TEXT</span><span class="col-note">task.updated · merge.failed · merge.remediated · …</span></div>
|
||
<div class="db-col"><span class="col-name">payload</span><span class="col-type">TEXT</span><span class="col-note">JSON;包含冲突文件列表、verdict 等结构化数据</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<h3 style="margin-top:24px">表关系(ER · 主外键)</h3>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 920 440" style="width:100%;display:block;margin:12px 0;max-width:920px">
|
||
<defs>
|
||
<marker id="er-fk" markerWidth="8" markerHeight="7" refX="7" refY="3.5" orient="auto"><polygon points="0 0,8 3.5,0 7" fill="#64748b"/></marker>
|
||
</defs>
|
||
<!-- 关系连线(projects/tasks 为父,1—N 指向子;tasks 自引用 parent_id)-->
|
||
<!-- projects 1—N tasks -->
|
||
<path d="M 150 152 Q 150 230 312 256" stroke="#64748b" stroke-width="1.5" fill="none" marker-end="url(#er-fk)"/>
|
||
<text x="150" y="210" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">1</text>
|
||
<text x="262" y="248" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">N</text>
|
||
<!-- tasks 自引用 parent_id -->
|
||
<path d="M 470 232 Q 540 196 506 232" stroke="#82b366" stroke-width="1.5" fill="none" stroke-dasharray="4,3" marker-end="url(#er-fk)"/>
|
||
<text x="540" y="200" text-anchor="middle" font-family="sans-serif" font-size="10" fill="#82b366">parent_id (自引用)</text>
|
||
<!-- tasks 1—N runs -->
|
||
<path d="M 488 268 Q 640 250 700 168" stroke="#64748b" stroke-width="1.5" fill="none" marker-end="url(#er-fk)"/>
|
||
<text x="520" y="258" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">1</text>
|
||
<text x="676" y="186" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">N</text>
|
||
<!-- tasks 1—N approvals -->
|
||
<path d="M 488 300 Q 640 330 700 326" stroke="#64748b" stroke-width="1.5" fill="none" marker-end="url(#er-fk)"/>
|
||
<text x="520" y="316" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">1</text>
|
||
<text x="676" y="318" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">N</text>
|
||
<!-- projects 1—N events / tasks 1—N events -->
|
||
<path d="M 120 152 Q 90 360 322 392" stroke="#64748b" stroke-width="1.5" fill="none" marker-end="url(#er-fk)"/>
|
||
<text x="300" y="384" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">N</text>
|
||
<path d="M 400 326 Q 400 360 400 372" stroke="#64748b" stroke-width="1.5" fill="none" marker-end="url(#er-fk)"/>
|
||
<text x="414" y="352" text-anchor="middle" font-family="sans-serif" font-size="11" fill="#9aa4b2">N</text>
|
||
|
||
<!-- projects -->
|
||
<rect x="40" y="40" width="220" height="112" rx="6" fill="#11161f" stroke="#d6b656"/>
|
||
<rect x="40" y="40" width="220" height="26" rx="6" fill="#2e2a14" stroke="#d6b656"/>
|
||
<text x="52" y="58" font-family="monospace" font-size="13" font-weight="bold" fill="#d6b656">projects</text>
|
||
<text x="52" y="86" font-family="monospace" font-size="10.5" fill="#9aa4b2">id (PK) · autonomy · concurrency</text>
|
||
<text x="52" y="104" font-family="monospace" font-size="10.5" fill="#9aa4b2">verify_cmd · model · checks</text>
|
||
<text x="52" y="122" font-family="monospace" font-size="10.5" fill="#f0c674">models · agent_rules 🆕</text>
|
||
<text x="52" y="140" font-family="monospace" font-size="10.5" fill="#f0c674">auto_approve_plan/exec 🆕</text>
|
||
|
||
<!-- tasks -->
|
||
<rect x="312" y="232" width="176" height="98" rx="6" fill="#11161f" stroke="#82b366"/>
|
||
<rect x="312" y="232" width="176" height="26" rx="6" fill="#1a2e1a" stroke="#82b366"/>
|
||
<text x="324" y="250" font-family="monospace" font-size="13" font-weight="bold" fill="#82b366">tasks</text>
|
||
<text x="324" y="278" font-family="monospace" font-size="10.5" fill="#9aa4b2">id (PK) · project_id (FK)</text>
|
||
<text x="324" y="296" font-family="monospace" font-size="10.5" fill="#9aa4b2">parent_id (FK自) · depth · deps</text>
|
||
<text x="324" y="314" font-family="monospace" font-size="10.5" fill="#7cc47c">scope_files 🆕 · complexity · status</text>
|
||
|
||
<!-- runs -->
|
||
<rect x="700" y="96" width="180" height="72" rx="6" fill="#11161f" stroke="#9673a6"/>
|
||
<rect x="700" y="96" width="180" height="26" rx="6" fill="#221a2e" stroke="#9673a6"/>
|
||
<text x="712" y="114" font-family="monospace" font-size="13" font-weight="bold" fill="#c4a8d4">runs</text>
|
||
<text x="712" y="142" font-family="monospace" font-size="10.5" fill="#9aa4b2">id (PK) · task_id (FK)</text>
|
||
<text x="712" y="160" font-family="monospace" font-size="10.5" fill="#9aa4b2">kind(+conflict) · status · last_seq</text>
|
||
|
||
<!-- approvals -->
|
||
<rect x="700" y="288" width="180" height="68" rx="6" fill="#11161f" stroke="#5b8fd6"/>
|
||
<rect x="700" y="288" width="180" height="26" rx="6" fill="#14233a" stroke="#5b8fd6"/>
|
||
<text x="712" y="306" font-family="monospace" font-size="13" font-weight="bold" fill="#7ab0ff">approvals</text>
|
||
<text x="712" y="334" font-family="monospace" font-size="10.5" fill="#9aa4b2">id (PK) · task_id (FK)</text>
|
||
<text x="712" y="350" font-family="monospace" font-size="10.5" fill="#9aa4b2">gate · action · reason</text>
|
||
|
||
<!-- events -->
|
||
<rect x="300" y="372" width="220" height="56" rx="6" fill="#11161f" stroke="#b85450"/>
|
||
<rect x="300" y="372" width="220" height="26" rx="6" fill="#2e1a1a" stroke="#b85450"/>
|
||
<text x="312" y="390" font-family="monospace" font-size="13" font-weight="bold" fill="#e07070">events</text>
|
||
<text x="312" y="418" font-family="monospace" font-size="10.5" fill="#9aa4b2">project_id (FK) · task_id (FK?) · type · payload</text>
|
||
</svg>
|
||
<div style="color:var(--text2);font-size:12px">
|
||
projects 1—N tasks(项目下多任务)· tasks 自引用 parent_id(Hard 拆解树)· tasks 1—N runs / approvals(每任务多次运行与审批)· projects/tasks 1—N events(审计日志,task_id 可空)。
|
||
</div>
|
||
|
||
<div style="margin-top:16px;color:var(--text2);font-size:12px">
|
||
🆕 标注的列是本轮优化新增字段(projects/tasks 表 schema 经 ensureColumn 幂等迁移);runs.kind 无 CHECK 约束,加 'conflict' 兼容老数据。
|
||
</div>
|
||
</section>
|
||
|
||
<hr class="divider">
|
||
|
||
<section style="margin-bottom:40px">
|
||
<h2>实现顺序</h2>
|
||
<p style="color:var(--text2);margin-bottom:16px">每类先 typecheck + build + test 验证,通过后再进下一类</p>
|
||
<div class="cat-grid">
|
||
<div class="cat-card">
|
||
<div class="label">第一批(① 任务拆解类)</div>
|
||
<div class="value">models.ts 档位分化 → runner.ts(git工具+maxTurns+prompt改) → pipeline.ts(parseDecompose扩展) → ingest.ts(priority/deps落库+autoApprovePlan) → store.ts+api(执行期锁)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">第二批(② 执行类)</div>
|
||
<div class="value">pipeline.ts(sync main+并行复审+分项检查+diff闸) → models.ts reviewer改fable → ingest.ts(reject硬闸+自动合并条件) → protocol.ts(新信号类型)</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">第三批(③ 解冲突类)</div>
|
||
<div class="value">protocol.ts runKind+conflict → pipeline.ts conflict分支 → runner.ts buildConflictPrompt → models.ts conflict角色(默认opus-4.8);调度无需改:补救任务 P0 插队、不中断在途</div>
|
||
</div>
|
||
<div class="cat-card">
|
||
<div class="label">第四批(DB schema migration)</div>
|
||
<div class="value">projects 表加 checks/auto_approve_plan/auto_approve_exec 列;schema.sql + store.ts 读写;版本迁移脚本</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</main>
|
||
</body>
|
||
</html>
|