Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c53bde4cf3 | ||
|
|
88204a90c8 |
+1
-1
@@ -44,7 +44,7 @@
|
||||
- `script/check-scaffold-parity.ts` — scaffold-template twin 逐字节
|
||||
校验(schema $id owner token 归一化比较);
|
||||
- `script/delink-core.ts` — 去链接化契约执行(#NNNN 活引用 → [org-internal #NNNN]
|
||||
注记;幂等;--check 零剩余才过;Inc 6b 字节锁镜像翻转 rewritten 后无递延);
|
||||
注记,`--strip` 进一步收敛为溯源短注 [TT-NNNN];幂等;--check 零剩余才过;Inc 6b 字节锁镜像翻转 rewritten 后无递延);
|
||||
- `script/check-core-p1.ts` — P1 零残留终验(私网 IP / 实例主机名 / 个人
|
||||
身份 / 旧 owner token 全树 grep;豁免 id-aliases.json 与历史命名空间
|
||||
URL 声明;Inc 6b 起无字节锁递延);
|
||||
|
||||
@@ -67,7 +67,7 @@ creating thin wrapper checklist files would add no value.
|
||||
|
||||
| # | 检查项 | 通过 | 不通过 | 备注 |
|
||||
| --- | --------------------------------------------------------------------- | ---- | ------ | ---- |
|
||||
| 1.1 | SDLC 流水线各阶段均有对应 skill(analyze-dag→review-dag 单门→implement→review-code→verify→release→retrospective;legacy roadmap/requirements/design/plan 已归档 [org-internal #3072] phase 3,见 `<instance-root>/archive/`) | ☐ | ☐ | |
|
||||
| 1.1 | SDLC 流水线各阶段均有对应 skill(analyze-dag→review-dag 单门→implement→review-code→verify→release→retrospective;legacy roadmap/requirements/design/plan 已归档 [TT-3072] phase 3,见 `<instance-root>/archive/`) | ☐ | ☐ | |
|
||||
| 1.2 | 每个 `skills/<name>/` 目录恰好包含一个 `SKILL.md`(例外:`_shared/` 目录不含 `SKILL.md`,为共享引用文档目录) | ☐ | ☐ | |
|
||||
| 1.3 | 每个产物型 skill 都有配套 `checklists/<name>.md`(无清单的自检要求即为缺口) | ☐ | ☐ | |
|
||||
| 1.4 | `checklists/` 中无孤儿清单(存在清单但无任何 skill 引用) | ☐ | ☐ | |
|
||||
@@ -179,7 +179,7 @@ creating thin wrapper checklist files would add no value.
|
||||
| 8.5 | 防范范围收窄:明令禁止「只看重点/从简」类弱化措辞(IEEE 1028-2008 完整性) | ☐ | ☐ | |
|
||||
| 8.6 | 留痕:审计产物落盘到结构化文件,而非仅存于对话 | ☐ | ☐ | |
|
||||
| 8.7 | 闭环:存在重审循环与收敛/审批终止条件(ISO 19011:2018 跟踪与关闭) | ☐ | ☐ | |
|
||||
| 8.8 | 流程自身测试为绿:Orchestrator(bash 可用)在派发审计员**之前**机械运行流程自身的测试套件与守卫门(`bun run test:parallel` 全量分片 + `check:*` 守卫族,如 core-parity / encoding-health / derived-artifacts),并把命令、基线 SHA 与结果摘要落盘到 `<runs-root>/audit/reviews/audit-process/process-tests-green.md`(Tier 1);审计员(只读,无 bash)核对该记录存在于当前基线且为绿——任何红测试/红守卫本身即流程缺陷,按 findings 登记(缺陷逃逸案例:红测试存活 3 轮审计、无任何维度运行过测试套件,[org-internal #4787]) | ☐ | ☐ | 运行归 Orchestrator、核对归审计员(角色边界:`core/skills/_shared/review-orchestrator-rules.md` §No bash for Explorer sub-agents) |
|
||||
| 8.8 | 流程自身测试为绿:Orchestrator(bash 可用)在派发审计员**之前**机械运行流程自身的测试套件与守卫门(`bun run test:parallel` 全量分片 + `check:*` 守卫族,如 core-parity / encoding-health / derived-artifacts),并把命令、基线 SHA 与结果摘要落盘到 `<runs-root>/audit/reviews/audit-process/process-tests-green.md`(Tier 1);审计员(只读,无 bash)核对该记录存在于当前基线且为绿——任何红测试/红守卫本身即流程缺陷,按 findings 登记(缺陷逃逸案例:红测试存活 3 轮审计、无任何维度运行过测试套件,[TT-4787]) | ☐ | ☐ | 运行归 Orchestrator、核对归审计员(角色边界:`core/skills/_shared/review-orchestrator-rules.md` §No bash for Explorer sub-agents) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -116,8 +116,8 @@
|
||||
| 5.4 | 测试相互独立,可任意顺序运行,无共享可变状态 | ☐ | ☐ | |
|
||||
| 5.5 | Mock/Stub 的使用合理,模拟的外部行为与真实行为一致 | ☐ | ☐ | |
|
||||
| 5.6 | 测试命名清晰表达了测试场景和预期结果 | ☐ | ☐ | |
|
||||
| 5.7 | 本次变更涉及的测试已通过(`test:changed`,由 mechanical-green gate 机器判定,评审员引用 gate 结果即可)。全量套件(`test:parallel`)归 verify,不是代码评审门禁([org-internal #2598] 检查分层) | ☐ | ☐ | |
|
||||
| 5.8 | 评审发现的"dummy fixture / harness 默认值漂移"类问题,不能仅凭 `WAIVED` 处置:若漂移值是 harness 对**生产 CLI/配置默认值**的镜像(如 harness 旧 owner 默认 vs CLI 新 owner 默认这类 token 漂移),WAIVED 会把真实漂移放行到 post-merge([org-internal #3169] TST-F002 → 后续 [org-internal #3172] 才修)。处置前确认该值是否被生产路径读取;被读取则必须 FIX 或显式登记 TD | ☐ | ☐ | |
|
||||
| 5.7 | 本次变更涉及的测试已通过(`test:changed`,由 mechanical-green gate 机器判定,评审员引用 gate 结果即可)。全量套件(`test:parallel`)归 verify,不是代码评审门禁([TT-2598] 检查分层) | ☐ | ☐ | |
|
||||
| 5.8 | 评审发现的"dummy fixture / harness 默认值漂移"类问题,不能仅凭 `WAIVED` 处置:若漂移值是 harness 对**生产 CLI/配置默认值**的镜像(如 harness 旧 owner 默认 vs CLI 新 owner 默认这类 token 漂移),WAIVED 会把真实漂移放行到 post-merge([TT-3169] TST-F002 → 后续 [TT-3172] 才修)。处置前确认该值是否被生产路径读取;被读取则必须 FIX 或显式登记 TD | ☐ | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
> **权威源**:本文件判据逐行复制 `dag-pipeline/spec-04` §1 三张表
|
||||
> (含 `NFR:` 前缀 / 里程碑边 / 里程碑节点豁免与 `estimated_sessions` 判据)。
|
||||
> 若本文件与 spec-04 §1 不一致,以 spec-04 §1 为唯一权威源。
|
||||
> (`spec-0N` 前身为 `dag-pipeline/03-design-0N-*`,2026-08-21 [org-internal #3072] phase 3
|
||||
> (`spec-0N` 前身为 `dag-pipeline/03-design-0N-*`,2026-08-21 [TT-3072] phase 3
|
||||
> 升格迁移,旧名仅保留墓碑占位以维持旧 URL 可达。)
|
||||
|
||||
## TOPO — 拓扑维
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
2. **POST** 项在完成编码和所有验证命令后检查;
|
||||
3. 对"不通过"项必须在代码评审前修复;
|
||||
4. 无法满足的项标记 `[N/A: <原因>]`;
|
||||
5. **DAG 路由产物解析([org-internal #3072] phase 3 后唯一管线模式)**:DAG 运行不存在
|
||||
5. **DAG 路由产物解析([TT-3072] phase 3 后唯一管线模式)**:DAG 运行不存在
|
||||
legacy `{slug}/04-plan-*` / `{slug}/03-design-*` 页面,PRE-1~PRE-7、
|
||||
PRE-11、PRE-12、PRE-19、POST-15.1 引用的产物按 `implement`/`verify`
|
||||
SKILL 的 DAG-route read map 解析:工作项定义 → 冻结 DAG 副本
|
||||
@@ -68,17 +68,17 @@
|
||||
| ------ | -------------------------------------------------------------------------- | ---- | ------ | --- | ---- |
|
||||
| PRE-11 | 设计文档(wiki pages `{slug}/03-design-**`)已存在且包含本工作项涉及的全部组件设计 | ☐ | ☐ | ☐ | |
|
||||
| PRE-12 | 迭代计划(plan/)已存在且本工作项有明确的工作项 ID 和验收条件 | ☐ | ☐ | ☐ | |
|
||||
| PRE-13 | 评审门已收敛:DAG 路由下为 review-dag 单门收敛(`octopus review status --stage review-dag` 的 state 为 `success`,与 `pipeline-gate.md` DAG 路由变体一致);standalone 模式(bugfix/refactor/port)无上游评审门,标记 `[N/A: standalone 无上游评审]`(legacy design-space / iteration-plan 双门已随 [org-internal #3072] phase 3 归档) | ☐ | ☐ | ☐ | |
|
||||
| PRE-13 | 评审门已收敛:DAG 路由下为 review-dag 单门收敛(`octopus review status --stage review-dag` 的 state 为 `success`,与 `pipeline-gate.md` DAG 路由变体一致);standalone 模式(bugfix/refactor/port)无上游评审门,标记 `[N/A: standalone 无上游评审]`(legacy design-space / iteration-plan 双门已随 [TT-3072] phase 3 归档) | ☐ | ☐ | ☐ | |
|
||||
| PRE-14 | 合并前基准刷新:当前分支已 rebase 到目标分支(`git fetch origin && git rebase origin/main`),无合并冲突。若 rebase 引入新变更,重新运行 `bun typecheck && bun run test:parallel` 后再提交 | ☐ | ☐ | ☐ | |
|
||||
|
||||
### 5. UI 组件设计完整性(仅前端/UI 工作项)
|
||||
|
||||
| # | 检查项 | 通过 | 不通过 | N/A | 备注 |
|
||||
| ------ | -------------------------------------------------------------------------- | ---- | ------ | --- | ---- |
|
||||
| PRE-15 | 设计文档覆盖了组件的全部四种状态(Loading / Empty / Error / Success),每种状态有明确的渲染内容和触发条件(参见 `.octopus/archive/templates/design.md` §11.1,legacy 设计模板 [org-internal #3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-16 | 设计文档覆盖了组件所需的全部交互行为:列表导航、焦点管理、键盘快捷键、展开/折叠、实时过滤(参见 `.octopus/archive/templates/design.md` §11.2,legacy 设计模板 [org-internal #3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-17 | 设计文档覆盖了组件的全部可访问性要求:ARIA role/label、键盘可达、焦点环、对比度、色彩独立性(参见 `.octopus/archive/templates/design.md` §11.3,legacy 设计模板 [org-internal #3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-18 | 设计文档已逐组件声明测试策略类型(render / source-verification / E2E / manual)。已知测试基础设施限制(Kobalte portal + happydom、路由上下文缺失等)已有对应替代方案标记(参见 `.octopus/archive/templates/design.md` §11.4,legacy 设计模板 [org-internal #3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-15 | 设计文档覆盖了组件的全部四种状态(Loading / Empty / Error / Success),每种状态有明确的渲染内容和触发条件(参见 `.octopus/archive/templates/design.md` §11.1,legacy 设计模板 [TT-3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-16 | 设计文档覆盖了组件所需的全部交互行为:列表导航、焦点管理、键盘快捷键、展开/折叠、实时过滤(参见 `.octopus/archive/templates/design.md` §11.2,legacy 设计模板 [TT-3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-17 | 设计文档覆盖了组件的全部可访问性要求:ARIA role/label、键盘可达、焦点环、对比度、色彩独立性(参见 `.octopus/archive/templates/design.md` §11.3,legacy 设计模板 [TT-3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-18 | 设计文档已逐组件声明测试策略类型(render / source-verification / E2E / manual)。已知测试基础设施限制(Kobalte portal + happydom、路由上下文缺失等)已有对应替代方案标记(参见 `.octopus/archive/templates/design.md` §11.4,legacy 设计模板 [TT-3072] phase 3) | ☐ | ☐ | ☐ | |
|
||||
| PRE-19 | 超过 3 个 MANUAL 类型的 AC 已标记为设计风险,并在 plan 中标注更高级测试基础设施依赖 | ☐ | ☐ | ☐ | |
|
||||
|
||||
---
|
||||
@@ -97,7 +97,7 @@
|
||||
| POST-6 | 若不得已偏离设计,有明确的注释标注原因和设计修正建议(含 ADR/amend 引用 — 不可仅写"偏离设计") | ☐ | ☐ | ☐ | |
|
||||
| POST-6.1 | 已用设计文档中的决策树/状态机/真值表,代入至少 2 组具体输入手工 trace 每条分支,确认代码输出与设计预期一致(尤其条件取反、`===` vs `!==`、状态翻转等易错点) | ☐ | ☐ | ☐ | |
|
||||
| POST-6.2 | 因 API 不兼容、上游限制或测试基础设施不足而延迟的项,已在代码中用 `[OPEN: <short-id>]` 标注(含延迟原因、影响范围、建议解决时机)。verify Phase 5.5 会为每个 `[OPEN]` 项在源票 `## TD 登记` 评论登记一行(registry-first,`ticket-lifecycle.md`;排期后才升格独立票)。禁止仅标注 `[OPEN]` 而不登记 | ☐ | ☐ | ☐ | |
|
||||
| POST-6.3 | 邻近配额([org-internal #3002] G3):本迭代触碰的区域(包/模块)若在源票 `## TD 登记` 中有适用行,已带走 ≥1 项一并处置(修复或带理由显式再延迟);无适用行时在报告记录 `0 applicable` | ☐ | ☐ | ☐ | |
|
||||
| POST-6.3 | 邻近配额([TT-3002] G3):本迭代触碰的区域(包/模块)若在源票 `## TD 登记` 中有适用行,已带走 ≥1 项一并处置(修复或带理由显式再延迟);无适用行时在报告记录 `0 applicable` | ☐ | ☐ | ☐ | |
|
||||
|
||||
### 5. 代码质量
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
| POST-10.4 | 多写操作(INSERT + UPDATE)用 `Database.transaction` 包裹保证原子性 | ☐ | ☐ | ☐ | |
|
||||
| POST-11 | 无硬编码凭据、密钥、内网地址或环境特定值 | ☐ | ☐ | ☐ | |
|
||||
| POST-11.1 | 提交前无法跟踪链接检查(单一事实来源:`code-review.md` SEC 3.7.1——`git diff --cached --diff-filter=T` 为空;判据以该条为准)| ☐ | ☐ | ☐ | |
|
||||
| POST-11.2 | 提交前已确认无进程/流程副产品混入暂存区(如 `.claim` 空文件、claim carrier、临时 pid/日志)——`git status` 逐条核对,`git add -A` 前先看 untracked 清单([org-internal #3169] 教训:`.claim` 空文件随 iter-0 混入,round-1 九维评审要求 `git rm`) | ☐ | ☐ | ☐ | |
|
||||
| POST-11.2 | 提交前已确认无进程/流程副产品混入暂存区(如 `.claim` 空文件、claim carrier、临时 pid/日志)——`git status` 逐条核对,`git add -A` 前先看 untracked 清单([TT-3169] 教训:`.claim` 空文件随 iter-0 混入,round-1 九维评审要求 `git rm`) | ☐ | ☐ | ☐ | |
|
||||
| POST-12 | 无注释掉的代码块或 `console.log` 调试语句 | ☐ | ☐ | ☐ | |
|
||||
| POST-13 | 无 `as any` 类型断言绕过类型检查(生产代码必须保有完整类型安全) | ☐ | ☐ | ☐ | |
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Upstream Artifact Existence 与 Upstream Review Convergence 检查
|
||||
`success`(替代 design-space + iteration-plan 双门;任务工单
|
||||
不重跑单门,只核对其已收敛)
|
||||
- [ ] (仅任务工单)票 body `## 父级 / Parent` 指向 DAG 父级
|
||||
(`Kind/Epic` 或 `Kind/Feature`,[org-internal #3061] 阶段 2),
|
||||
(`Kind/Epic` 或 `Kind/Feature`,[TT-3061] 阶段 2),
|
||||
Step 0 解析到 `dag.task_route`(entry `implement`),不继承
|
||||
`dag.route`
|
||||
- [ ] 跨节点依赖由 DAG 拓扑承担:节点 ready 以其全部跨 session 上游
|
||||
@@ -34,7 +34,7 @@ review-dag)直至收敛;DAG 副本缺失或未冻结 → 回到 `analyze-dag
|
||||
- [ ] standalone bugfix:repro notes wiki page `{slug}/repro-notes` 存在且含环境快照(via `wiki 读写 API(见 TERMINOLOGY)`)
|
||||
- [ ] 验收条件可解析:来自请求/工单 body 或节点 AC(等价的验收条件文档,via `wiki 读写 API(见 TERMINOLOGY)` / `工单 API(见 TERMINOLOGY)get`)
|
||||
|
||||
> Legacy([org-internal #3072] phase 3,2026-08-21 归档):requirements/design/plan baseline
|
||||
> Legacy([TT-3072] phase 3,2026-08-21 归档):requirements/design/plan baseline
|
||||
> 页(`{slug}/02-requirements-index` / `{slug}/03-design-index` /
|
||||
> `{slug}/04-plan-index` / `{slug}/04-plan-05-acceptance-criteria`)与
|
||||
> design-space / iteration-plan 双门收敛检查随 legacy 管线归档
|
||||
@@ -65,10 +65,10 @@ review-dag)直至收敛;DAG 副本缺失或未冻结 → 回到 `analyze-dag
|
||||
|
||||
## PR 准入(pr-admission)
|
||||
|
||||
> 纪律:`core/rules/ticket-lifecycle.md` PR 准入节(TD-678 / [org-internal #3881] / [org-internal #4425])。
|
||||
> 纪律:`core/rules/ticket-lifecycle.md` PR 准入节(TD-678 / [TT-3881] / [TT-4425])。
|
||||
|
||||
- [ ] PR 标题符合 `[slug][iter-N] type(scope): 描述` 格式
|
||||
- [ ] PR 正文含变更清单 + 自测结果 + 关联合规(关联 issue 引用,如 `Closes #N`;数字后须接 ASCII 标点或行尾——紧跟全角标点会破坏 Gitea 自动关闭,PR [org-internal #3882] 实例)
|
||||
- [ ] PR 正文含变更清单 + 自测结果 + 关联合规(关联 issue 引用,如 `Closes #N`;数字后须接 ASCII 标点或行尾——紧跟全角标点会破坏 Gitea 自动关闭,PR [TT-3882] 实例)
|
||||
- [ ] 交付推送前本地验证已绿:`<harness-package>` 下 `bun run test:changed` 全绿 + `bun typecheck` 0 error(WIP 备份推送不受此门约束——分支裸推零 CI,交付信号是完成回报而非推送)
|
||||
- [ ] 分支已推送 origin;PR **未**由本会话自行创建(由编排按容量串行开启,一次一张、双绿并入再开下一张)
|
||||
- [ ] 交付报告已发(branch= 分支名 / 改动文件清单 / 自测结果 / verify 与 risk 回执)
|
||||
@@ -81,7 +81,7 @@ review-dag)直至收敛;DAG 副本缺失或未冻结 → 回到 `analyze-dag
|
||||
> 状态跃迁),不得等到技能退出边界。规则:`core/rules/issue-checklist-sync.md`。
|
||||
|
||||
- [ ] 若存在 source issue:其 checklist 已按同步点表渐进勾选(DAG 冻结、iteration commit、PR 创建、review PASS、CI 跃迁、verify 终扫),无陈旧 `- [ ]` 项
|
||||
- [ ] 若为 incident / standalone-bugfix 流程:issue 含 `## 当前状态` live-status 小节,且 PR / review / CI 行已随跃迁更新([org-internal #1689])
|
||||
- [ ] 若为 incident / standalone-bugfix 流程:issue 含 `## 当前状态` live-status 小节,且 PR / review / CI 行已随跃迁更新([TT-1689])
|
||||
- [ ] 过程性 AC(如"连续 N 次绿")的进度注记已更新(带 run 编号)
|
||||
- [ ] 遗留项(未勾选)均有 `(Deferred: ...)` 或 `(Pending: ...)` 注记
|
||||
- [ ] verify PASS 时 `## 当前状态` 小节已折叠进 checklist 注记并移除
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
| 2.1 | 重构目标明确(哪种变换,为什么) | ☐ | ☐ | |
|
||||
| 2.2 | 步骤分解 ≤ 10 步 | ☐ | ☐ | |
|
||||
| 2.3 | 不存在范围蔓延(未在同一重构中混入新功能或 Bug 修复) | ☐ | ☐ | |
|
||||
| 2.4 | 若重构涉及身份/owner token 改名(org、账号、邮箱、域名前缀):已先产出"不改清单"——OS 账号、个人邮箱、历史记录归属、dummy fixture 等非组织身份引用逐类明确保留,再执行机械替换([org-internal #3169] 教训:D1 缺此边界 → round-1 15 MAJOR) | ☐ | ☐ | |
|
||||
| 2.4 | 若重构涉及身份/owner token 改名(org、账号、邮箱、域名前缀):已先产出"不改清单"——OS 账号、个人邮箱、历史记录归属、dummy fixture 等非组织身份引用逐类明确保留,再执行机械替换([TT-3169] 教训:D1 缺此边界 → round-1 15 MAJOR) | ☐ | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
| 4.4 | 测试覆盖率未下降(±1%) | ☐ | ☐ | |
|
||||
| 4.5 | 无新增或修改的测试(重构不应改变测试中的断言逻辑) | ☐ | ☐ | |
|
||||
| 4.6 | 若重构改变了对外可见字符串(stage 名称、tool description、错误消息等),对应的 snapshot 已通过 `bun test --update-snapshots` 更新 | ☐ | ☐ | |
|
||||
| 4.7 | 若重构变更了身份/owner token:残留扫描守卫(如 `script/verify-urls.ts`)已做**语义正反验证**——搜索模式指向**旧** token(旧 owner 前缀的 URL 形态),且已知新 token(新 owner 前缀的 URL 形态)与真实旧残留各跑一次,确认守卫对"合规新 URL"不误报、对"真实残留"不漏报([org-internal #3169] 教训:D5 模式被翻转 → 守卫对新 URL 误报、对旧残留失明) | ☐ | ☐ | |
|
||||
| 4.7 | 若重构变更了身份/owner token:残留扫描守卫(如 `script/verify-urls.ts`)已做**语义正反验证**——搜索模式指向**旧** token(旧 owner 前缀的 URL 形态),且已知新 token(新 owner 前缀的 URL 形态)与真实旧残留各跑一次,确认守卫对"合规新 URL"不误报、对"真实残留"不漏报([TT-3169] 教训:D5 模式被翻转 → 守卫对新 URL 误报、对旧残留失明) | ☐ | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
| 1.11 | 已检查 merged workflow/* 分支与关联 worktree 在合并后已清理(本地分支删除 + worktree 移除) | ☐ | ☐ | |
|
||||
| 1.12 | 周期时长和团队规模已记录(压缩周期 = 质量风险,单点故障) | ☐ | ☐ | |
|
||||
| 1.13 | 范围估算验证:triage/scope 声明前已统计各标签下的 issue 数量(如 `Status/Blocked`、`Kind/*`、`Priority/*`),并与之前声明对比,偏差 >20% 标注为估算偏差 | ☐ | ☐ | |
|
||||
| 1.14 | 门缺陷逃逸分析已运行(§2.8 escape-rate 单指标,[org-internal #3061]):各 gate 的 clean runs / escapes / escape_rate 已统计,UNDER-POWERED(≥0.3)门已标注并回馈 §2.9 pre-flight(gate-trim 元进程已退役,[org-internal #3072] phase 3) | ☐ | ☐ | |
|
||||
| 1.14 | 门缺陷逃逸分析已运行(§2.8 escape-rate 单指标,[TT-3061]):各 gate 的 clean runs / escapes / escape_rate 已统计,UNDER-POWERED(≥0.3)门已标注并回馈 §2.9 pre-flight(gate-trim 元进程已退役,[TT-3072] phase 3) | ☐ | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -119,9 +119,9 @@
|
||||
| # | 检查项 | 通过 | 不通过 | 备注 |
|
||||
| --- | --------------------------------------------------------------------- | ---- | ------ | ---- |
|
||||
| 8.1 | 本迭代全部 UNVERIFIABLE / ACCEPTED_RISK / `[OPEN]` 项均已登记为源票 `## TD 登记` 评论中的行(registry-first,`ticket-lifecycle.md`;`filing.sprint-mode: true` 期间禁止升格独立票) | ☐ | ☐ | |
|
||||
| 8.2 | 每行含 `TD-NNN`、type、Severity、origin、一句话摘要与可客观验证的 Reactivation Trigger;TD-NNN 为注册期分配——经 `script/td-alloc.sh` 从号段台账(TD allocation ledger,常设 tracker)取号,任何分配必须先落台账 td-alloc 评论([org-internal #3322] 互斥) | ☐ | ☐ | |
|
||||
| 8.2 | 每行含 `TD-NNN`、type、Severity、origin、一句话摘要与可客观验证的 Reactivation Trigger;TD-NNN 为注册期分配——经 `script/td-alloc.sh` 从号段台账(TD allocation ledger,常设 tracker)取号,任何分配必须先落台账 td-alloc 评论([TT-3322] 互斥) | ☐ | ☐ | |
|
||||
| 8.3 | 两处登记的 `TD-NNN` 标识一致,且每项都有可客观验证的 Reactivation Trigger | ☐ | ☐ | |
|
||||
| 8.4 | 邻近配额复核([org-internal #3002] G3):报告含本迭代触碰区域的登记册带走情况(consumed/applicable,或 `0 applicable`);与本 run 的债务配额记录一致(legacy roadmap 状态追踪表已归档,[org-internal #3072] phase 3) | ☐ | ☐ | |
|
||||
| 8.4 | 邻近配额复核([TT-3002] G3):报告含本迭代触碰区域的登记册带走情况(consumed/applicable,或 `0 applicable`);与本 run 的债务配额记录一致(legacy roadmap 状态追踪表已归档,[TT-3072] phase 3) | ☐ | ☐ | |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## Artifact-Index Guards (mandatory)
|
||||
|
||||
> Check-mechanized (injection-budget batch-3, [org-internal #3699]): guards
|
||||
> Check-mechanized (injection-budget batch-3, [TT-3699]): guards
|
||||
> 1-3's checkable invariants run in the repo's artifact-index-check script
|
||||
> (`<artifact-index-check-cmd> <ticket>`, see the term mapping; exit 4 =
|
||||
> violation, `--json` summary; tolerant of wild archive-marker dialects).
|
||||
@@ -16,7 +16,7 @@
|
||||
Before creating a `## 工件索引` comment, scan the issue's existing comments
|
||||
for the legacy prefix `## Pipeline 工件追踪表`. If found, UPGRADE it
|
||||
in place (edit, not create) and rename. NEVER create a second index comment
|
||||
(DEFECT-1 / [org-internal #1924]). Mechanized: reports the comment_id to edit.
|
||||
(DEFECT-1 / [TT-1924]). Mechanized: reports the comment_id to edit.
|
||||
|
||||
### 2. Never-duplicate invariant (single-comment)
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ UI's "auto-accept permissions" toggle (browser-local, not the project
|
||||
> fix this table. `merge-pr` is excluded from default/preset `stages` arrays
|
||||
> (not structurally blocked; explicitly adding it is not recommended).
|
||||
> Legacy stage retirement (12 → 5): the phase-3 retirement ruling doc
|
||||
> (Tier-2 reference, reachable via the ticket backend).
|
||||
> (instance detail (in the consuming instance)).
|
||||
|
||||
Config shape: `"auto_approve": { "stages": ["review-code", "verify"], "stageless": false }` — `stages` empty (`[]`) = all manual; `stageless: true` also auto-approves questions called without a stage. Absent block defaults to `{ stages: ["review-code", "verify", "audit-process"], stageless: false }`; the removed `enabled` field migrates on load (mapping: Tier-2 reference page `rules/auto-approve-detail`). Presets (`safe`/`full`/`off`/`show`): same reference page — `full` never includes `merge-pr`.
|
||||
Config shape: `"auto_approve": { "stages": ["review-code", "verify"], "stageless": false }` — `stages` empty (`[]`) = all manual; `stageless: true` also auto-approves questions called without a stage. Absent block defaults to `{ stages: ["review-code", "verify", "audit-process"], stageless: false }`; the removed `enabled` field migrates on load (mapping: instance detail page `rules/auto-approve-detail`). Presets (`safe`/`full`/`off`/`show`): same reference page — `full` never includes `merge-pr`.
|
||||
|
||||
### Stage matching behavior
|
||||
|
||||
@@ -55,7 +55,7 @@ Config shape: `"auto_approve": { "stages": ["review-code", "verify"], "stageless
|
||||
Check logic: the harness 内建的问询与自动批准判定模块
|
||||
(resolveAutoApproveDecision).
|
||||
|
||||
### Live-gate degradation chain ([org-internal #3531])
|
||||
### Live-gate degradation chain ([TT-3531])
|
||||
|
||||
An auto-approved question is NOT consumed instantly: L1 — a live human
|
||||
watching the session (SSE declaration / fresh presence ping) answers within
|
||||
@@ -73,7 +73,7 @@ before the gate runs (iron law).
|
||||
|
||||
### Mandatory destructive list (业务决策类问询强制清单)
|
||||
|
||||
Origin: [org-internal #3223] — a stage whitelist auto-answered two
|
||||
Origin: [TT-3223] — a stage whitelist auto-answered two
|
||||
irreversible production data changes because nothing marked them
|
||||
`destructive`. A stage whitelist grants "execution gates may proceed
|
||||
uninterrupted"; it must NEVER grant "business decisions may be
|
||||
@@ -87,8 +87,7 @@ is never a substitute for human confirmation of these categories.**
|
||||
1. **Merge / release landing** — merging a PR to main, cutting a tag or
|
||||
release, deploying/promoting to production (server-side auto-merge is a
|
||||
human-configured policy robot, never agent self-answer latitude; kill
|
||||
switch: the auto-merge-low-risk runbook, Tier-2 reference via the ticket
|
||||
backend).
|
||||
switch: the auto-merge-low-risk runbook, instance detail (in the consuming instance)).
|
||||
2. **Production database writes** — upsert/update/delete against production
|
||||
data stores, production data migrations, live-data backfills.
|
||||
3. **Billing / plan changes** — plan or tier migration, pricing/concurrency
|
||||
|
||||
@@ -52,7 +52,7 @@ plausible-looking result to fill the gap.
|
||||
contents, API responses, search hits, metrics. If the tool did not return
|
||||
it, you do not know it — say so.
|
||||
|
||||
Origin: [org-internal #2115] root cause 5 / [org-internal #2118] — deepseek-v4-flash reviewers fabricated
|
||||
Origin: [TT-2115] root cause 5 / [TT-2118] — deepseek-v4-flash reviewers fabricated
|
||||
full review JSON when the wiki tool surface (MCP tooling at the time, now
|
||||
retired) was unavailable to subagents.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ NOT grep + read whole files to reconstruct relationships.
|
||||
The main checkout's `.codegraph/` indexes ONLY that tree. A git worktree lives
|
||||
outside the repo path, so nearest-`.codegraph/` resolution finds nothing under
|
||||
it — graph queries in a workflow worktree silently degrade to grep+read
|
||||
(the [org-internal #2561] / TD-006 gap).
|
||||
(the [TT-2561] / TD-006 gap).
|
||||
|
||||
- `script/session-worktree.sh create` and `script/scratch-worktree.sh create`
|
||||
build a per-worktree index automatically: `codegraph init -i <path>` runs in
|
||||
|
||||
@@ -6,13 +6,13 @@ Context compaction keeps long pipelines inside the model's context window.
|
||||
Two mechanisms exist:
|
||||
|
||||
1. **Stage-boundary compaction** (main session / orchestrator) —
|
||||
capacity-driven [org-internal #2601]: compact at a clean stage boundary
|
||||
capacity-driven [TT-2601]: compact at a clean stage boundary
|
||||
ONLY when a capacity trigger holds (below), not merely because the
|
||||
boundary was reached.
|
||||
2. **Round-boundary compaction** (multi-round reviews) — compact at every
|
||||
review round ≥ 2, after the round's state is persisted.
|
||||
|
||||
### Stage-boundary compaction (capacity-driven, [org-internal #2601])
|
||||
### Stage-boundary compaction (capacity-driven, [TT-2601])
|
||||
|
||||
The main session orchestrates the whole pipeline while delegating stages to
|
||||
subagents, but still accumulates their result summaries, planning reasoning,
|
||||
@@ -35,16 +35,16 @@ A trigger holding → compact at the NEAREST clean boundary. No trigger → KEEP
|
||||
the context: preserved working context is worth more than the tokens it costs.
|
||||
|
||||
**Mixed capacity threshold — min(water_level, absolute cap)
|
||||
[org-internal #3321] / TD-434]**: the capacity threshold is
|
||||
[TT-3321] / TD-434]**: the capacity threshold is
|
||||
`min(context × water_level, compaction.max_context_tokens)` — whichever is
|
||||
LOWER (`max_context_tokens` default 100_000; `0` restores pure water_level
|
||||
semantics [org-internal #3342]). On large windows the 100k cap binds first.
|
||||
semantics [TT-3342]). On large windows the 100k cap binds first.
|
||||
Measurement basis: the provider's REAL reported usage (input tokens), not
|
||||
local estimates; the rendered guidance and the Trigger A/B overflow paths
|
||||
resolve the same normalized values (harness 内建的压缩引导模块, see the
|
||||
instance term mapping).
|
||||
|
||||
**Sub-session posture [org-internal #3321]**: Explorers compact by returning
|
||||
**Sub-session posture [TT-3321]**: Explorers compact by returning
|
||||
promptly, persisting only what their skill protocol REQUIRES (review findings
|
||||
JSON to the run workspace reviews directory). Workers persist outputs to
|
||||
Tier 1 BEFORE finishing. The parent context is where the mixed threshold
|
||||
@@ -52,8 +52,7 @@ applies. Tier 1 boundary: two-tier-artifacts rule.
|
||||
|
||||
**Short runs target zero intra-run compaction** — an implement →
|
||||
review-code → verify run fits one window; clean boundaries do not compact
|
||||
without a trigger. (Rationale + retired legacy stages: Tier-2 reference page
|
||||
`rules/compact-detail`, reachable via the ticket backend.)
|
||||
without a trigger. (Rationale + retired legacy stages: instance detail page `rules/compact-detail`, reachable via the ticket backend.)
|
||||
|
||||
Clean boundaries where triggers are evaluated (live skills):
|
||||
|
||||
@@ -74,7 +73,7 @@ DAG-routed runs, the latest review pages, or the DoD matrix
|
||||
(`{slug}/05-verify-*`) — to recover the current slug, stage, and outstanding
|
||||
items. Do not rely on the compacted summary alone.
|
||||
|
||||
**Identity verification precedes re-orientation [org-internal #2459].**
|
||||
**Identity verification precedes re-orientation [TT-2459].**
|
||||
Every compacted summary opens with a harness-injected `### Session Identity`
|
||||
card (agent, role/mode/ticket, CORE artifact rows, role re-read set),
|
||||
rendered from role-yaml `compact.preserve` lists and issue CORE rows by the
|
||||
@@ -99,7 +98,7 @@ The `compact` tool rejects calls made too soon after the previous one
|
||||
turns); no boundary type is exempt. Beyond `insufficient_turns` the tool has
|
||||
more guard outcomes (`min_interval`, `no_model`, `circuit_breaker_open`,
|
||||
`disabled` — rejected; `compaction_in_progress`, `deduplicated` — deferred;
|
||||
full table: Tier-2 reference page `rules/compact-detail`, reachable via the
|
||||
full table: instance detail page `rules/compact-detail`, reachable via the
|
||||
ticket backend). All are accept-and-continue: never retry past a guard,
|
||||
never work around the dedup/breaker state. A boundary whose compaction was
|
||||
rejected or deferred simply keeps its context; the persisted artifacts still
|
||||
|
||||
@@ -11,16 +11,16 @@ point and see exactly what is done, in progress, and deferred.
|
||||
|
||||
| When | Who | What |
|
||||
|------|-----|------|
|
||||
| After the DAG artifact is frozen (`review-dag` PASS + freeze confirmation per `analyze-dag/SKILL.md` §Output & Lifecycle step 2, [org-internal #3379]) | Aggregator agent | Convert the source Epic's draft acceptance criteria into a formal checklist; annotate requirement-covered items `_(DAG frozen: {epic-slug}/dag v1)_` |
|
||||
| After the DAG artifact is frozen (`review-dag` PASS + freeze confirmation per `analyze-dag/SKILL.md` §Output & Lifecycle step 2, [TT-3379]) | Aggregator agent | Convert the source Epic's draft acceptance criteria into a formal checklist; annotate requirement-covered items `_(DAG frozen: {epic-slug}/dag v1)_` |
|
||||
| After each iteration commit (`implement` Phase 4.5) | Developer | Check off items delivered by this iteration |
|
||||
| After a PR is created | Developer | Append a `## 当前状态` live-status section (or update it) with PR number + mergeable; in an Epic task list, append the PR reference to the corresponding row |
|
||||
| After code review converges (`review-code` PASS, Phase E) | Orchestrator | Check off review-related items; annotate `_(reviewed: round N PASS)_`; update the `## 当前状态` review row; label the PR `ready-to-merge` — keep-mergeable automation takes over (hand-written keep-mergeable commits are retired) |
|
||||
| On CI key state transitions (first green / failure / cumulative goal reached) | Verifier or Developer | Update the process-type AC (e.g. "N consecutive green runs") progress note in the issue; record the run number |
|
||||
| At `verify` Phase 5.6 (final sweep before PASS) / issue close | Closing agent (Verifier on the primary path; otherwise the last role that closes the issue) | Final sweep — every remaining item gets annotated; **archive-at-close**: fold `## 当前状态`, then mark the `## 工件索引` comment archived per the artifact-index-guards rule guard #3 (see「归档动作」below) |
|
||||
|
||||
> Historical ([org-internal #3072] phase 3): the requirements/design/plan exit sync points
|
||||
> were archived with their skills (detail: Tier-2 reference page
|
||||
> `rules/issue-checklist-sync-detail`, reachable via the ticket backend).
|
||||
> Historical ([TT-3072] phase 3): the requirements/design/plan exit sync points
|
||||
> were archived with their skills (detail: instance detail page
|
||||
> `rules/issue-checklist-sync-detail`, in the consuming instance).
|
||||
|
||||
Between sync points the checklist stays as-is. **PR / review / CI
|
||||
transitions** MUST also be visible via the live status note below — the
|
||||
@@ -32,12 +32,12 @@ For flows with externally visible transitions between skill exits —
|
||||
standalone bugfix, incident response, long-running reviews — maintain a short
|
||||
live status table near the top of the issue body, updated in place via the
|
||||
ticket-backend issue-update API at the transition moment (closes the
|
||||
stale-issue gap [org-internal #1668]/[org-internal #1689]]).
|
||||
stale-issue gap [TT-1668]/[TT-1689]]).
|
||||
|
||||
All roles use the literal heading `## 当前状态` (no suffix). If an issue carries
|
||||
a legacy variant (e.g. `## 当前状态 (live)` from [org-internal #1668]), normalize it to
|
||||
a legacy variant (e.g. `## 当前状态 (live)` from [TT-1668]), normalize it to
|
||||
`## 当前状态` at the first transition touched. Example table + legacy-variant
|
||||
list: Tier-2 reference page `rules/issue-checklist-sync-detail`, reachable
|
||||
list: instance detail page `rules/issue-checklist-sync-detail`, reachable
|
||||
via the ticket backend.
|
||||
|
||||
Rules:
|
||||
@@ -57,15 +57,15 @@ Rules:
|
||||
- At verify PASS / issue close, fold the table's content into checklist
|
||||
annotations and remove the section (see the「归档动作」section below).
|
||||
|
||||
### Automated sync ([org-internal #1833], timer-polled since [org-internal #2813])
|
||||
### Automated sync ([TT-1833], timer-polled since [TT-2813])
|
||||
|
||||
PR / review / CI status-row transitions are automated by the `status-sync`
|
||||
poller (deployed as a host timer, every 5 min; event sources + latency table
|
||||
on the Tier-2 reference page `rules/issue-checklist-sync-detail`, reachable
|
||||
on the instance detail page `rules/issue-checklist-sync-detail`, reachable
|
||||
via the ticket backend). Roles do NOT hand-write those three row types. A PR
|
||||
body may carry several close refs (batch PRs, [org-internal #3731]
|
||||
body may carry several close refs (batch PRs, [TT-3731]
|
||||
`land-batch`): rows fan out to EVERY referenced issue
|
||||
(`parseClosesFixesWide` — [org-internal #3867], merged 2026-08-31) — Chinese 关闭/修复 refs
|
||||
(`parseClosesFixesWide` — [TT-3867], merged 2026-08-31) — Chinese 关闭/修复 refs
|
||||
drive rows too, even though the ticket backend never auto-closes those
|
||||
keywords. The remaining sync points (checklist annotations at skill exits,
|
||||
`## 当前状态` creation, deferral/pending marking, section fold-at-close) are
|
||||
@@ -80,8 +80,7 @@ deduplicated `[status-sync-cron]` issue.
|
||||
Pipeline mode has natural sync points at skill exits; standalone bugfix and
|
||||
incident flows do NOT — the only boundaries are commit → PR → review → CI →
|
||||
merge, and EACH is a sync point with the same annotations as the progressive
|
||||
table above (full table: Tier-2 reference page
|
||||
`rules/issue-checklist-sync-detail`, reachable via the ticket backend): fix
|
||||
table above (full table: instance detail page `rules/issue-checklist-sync-detail`, reachable via the ticket backend): fix
|
||||
commit → tick fix-delivered ACs `_(commit {sha}: file)_`; PR → open/update
|
||||
`## 当前状态`; review convergence → tick review ACs + review row; CI
|
||||
transitions → process-AC progress with run number; verify PASS / close →
|
||||
@@ -108,7 +107,7 @@ For tickets routed through the DAG pipeline (see workflow-routing rule
|
||||
comment (single-comment invariant). The body aggregator table is kept as a
|
||||
historical snapshot at close and does NOT carry ARCHIVE.
|
||||
|
||||
### Kind/MVP tickets — exemption ([org-internal #3061])
|
||||
### Kind/MVP tickets — exemption ([TT-3061])
|
||||
|
||||
`Kind/MVP` tickets run the interactive no-pipeline mode: no stage exits →
|
||||
**nothing to sync**, no `## 当前状态` section (no PR/review/CI rows until
|
||||
@@ -137,7 +136,7 @@ non-checklist content. PR / review / CI transitions ALSO go into the
|
||||
|
||||
### 归档动作(issue 关闭 = 归档)
|
||||
|
||||
**生命周期 = 工单生命周期**([org-internal #1929]):文档生命周期与源 issue 绑定 —— verify PASS → issue 关闭 = 归档。Tier-2 工件库无独立生命周期。
|
||||
**生命周期 = 工单生命周期**([TT-1929]):文档生命周期与源 issue 绑定 —— verify PASS → issue 关闭 = 归档。Tier-2 工件库无独立生命周期。
|
||||
|
||||
归档是 **显式动作**,由关闭 issue 的 agent 执行:主路径为 Verifier 在 `verify` Phase 5.6;路径跳过 verify 时(audit-only、文档类、standalone/bugfix)由关闭 issue 的 role 代为执行。无论哪个 actor,均遵循 artifact-index-guards 规则 guard #3(机制以共享 write-patterns Pattern 10 为准)。动作序列:
|
||||
|
||||
@@ -146,7 +145,7 @@ non-checklist content. PR / review / CI transitions ALSO go into the
|
||||
3. **标记 `## 工件索引` 归档**:按共享 write-patterns Pattern 10 Archive-at-close 原位 edit(机制以 Pattern 10 为准)。横幅日期以实际关闭日为准。
|
||||
4. **关闭 issue**:PR body 的 `Closes #N` 在 merge 时自动关闭;无 PR 的流程由 **关闭 issue 的 agent** 执行工单后端的 issue-close API 完成闭环。
|
||||
|
||||
约束([org-internal #1928] 设计约束;机制细节以共享 write-patterns Pattern 10 Archive-at-close 为准,此处不重复):
|
||||
约束([TT-1928] 设计约束;机制细节以共享 write-patterns Pattern 10 Archive-at-close 为准,此处不重复):
|
||||
|
||||
- **L 级大件(>~300 行)留 Tier-2 工件库不删除** —— 页面与位置列 URL 保持不动(稳定 URL 供历史与共享契约引用)。
|
||||
- **索引/状态/归档判定全部收敛到 issue** —— Tier-2 工件库无独立生命周期;归档标记只落在 `## 工件索引` 评论。
|
||||
|
||||
@@ -14,7 +14,7 @@ regression-test follow-up, or any parent/child breakdown — the issues MUST be
|
||||
cross-linked:
|
||||
|
||||
- **Parent issue**: after creating all children, update the parent body so its
|
||||
task list references each child by `#<number>` (e.g. `- [ ] [org-internal #1556] — [P0] ...`).
|
||||
task list references each child by `#<number>` (e.g. `- [ ] [TT-1556] — [P0] ...`).
|
||||
The ticket backend renders these as clickable links and auto-generates a
|
||||
back-reference on each child's timeline.
|
||||
- **Child issue**: its body MUST contain a `## 父级 / Parent` section referencing
|
||||
@@ -25,7 +25,7 @@ cross-linked:
|
||||
### Issue ↔ Tier-2 artifact (pipeline traceability)
|
||||
|
||||
When a production skill (`analyze-dag`, publishing the `{epic-slug}/dag`
|
||||
artifact; historically the pre-[org-internal #3072] producer skills) publishes
|
||||
artifact; historically the pre-[TT-3072] producer skills) publishes
|
||||
an artifact to the Tier-2 artifact library, the link to the source issue is
|
||||
only **half-built** — the library's index page links forward to the issue,
|
||||
but the issue has no link back to the library. A stakeholder opening the
|
||||
@@ -44,7 +44,7 @@ After publishing, the skill MUST complete the reverse link on the source issue:
|
||||
reads the 工件索引 comment and fetches every CORE row's 位置 (shared
|
||||
read-patterns doc Pattern 6), instead of hard-coded library paths. Skills'
|
||||
re-read instructions therefore point at the index.
|
||||
- **Archive-at-close(归档动作, [org-internal #1929]/[org-internal #1928])** — issue 关闭即归档;Tier-2 工件库无独立
|
||||
- **Archive-at-close(归档动作, [TT-1929]/[TT-1928])** — issue 关闭即归档;Tier-2 工件库无独立
|
||||
生命周期。`ARCHIVE` is not just a per-row re-read priority: at issue close the
|
||||
whole index is marked archived by the closing agent (Verifier at `verify`
|
||||
Phase 5.6 on the primary path; otherwise the Orchestrator / last-role that
|
||||
@@ -56,11 +56,11 @@ After publishing, the skill MUST complete the reverse link on the source issue:
|
||||
- **Sync the issue's checklist** per the issue-checklist-sync rule for the
|
||||
matching exit point (live: the DAG-freeze sync point after `review-dag`
|
||||
PASS; the legacy requirements-exit / design-exit / plan-exit points were
|
||||
retired with their skills, [org-internal #3072] phase 3).
|
||||
retired with their skills, [TT-3072] phase 3).
|
||||
- Skip if no source issue exists (no `Closes #N` / `Fixes #N` / roadmap chunk
|
||||
mapping ties this slug to an issue).
|
||||
|
||||
**Size/S & Size/M exception ([org-internal #1832]) — RETIRED (2026-08-21, [org-internal #3072]
|
||||
**Size/S & Size/M exception ([TT-1832]) — RETIRED (2026-08-21, [TT-3072]
|
||||
phase 3)**: retired with the legacy producer skills and the `sizing:` block.
|
||||
Historical indexes pointing at in-issue artifacts (`位置 = #comment-{id}`)
|
||||
remain valid, readable locations; new artifacts publish where their live
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## Session Scope Guard (mandatory)
|
||||
|
||||
> Enforcement layer: precheck-mechanized (injection-budget batch-2,
|
||||
> [org-internal #3667]) — pre-flight sources 1-3 below live in the repo's
|
||||
> [TT-3667]) — pre-flight sources 1-3 below live in the repo's
|
||||
> session-conflicts script, source 4 in the claim script's compare-and-swap.
|
||||
> This file is the normative definition, NOT part of any `agents_md`
|
||||
> injection whitelist since 2026-08-29 — do not re-add; the checks run at
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
Standalone and ticket-seeded sessions run without a pipeline around them —
|
||||
no plan, no reviewer keeping them inside their work item. When such a
|
||||
session hits a test failure NOT caused by its own change ([org-internal
|
||||
[org-internal #1803]], via [org-internal #1753]/[[org-internal #1744]]), it tends to fix the foreign
|
||||
session hits a test failure NOT caused by its own change ([TT-1803], via [TT-1753]/[TT-1744]), it tends to fix the foreign
|
||||
failure in place (drifting off-task), and sessions seeded for the same issue
|
||||
collide on the same shared flaky test.
|
||||
|
||||
@@ -48,17 +47,17 @@ on ANY source → the ticket is already owned: ABORT (or, for a DEAD claim,
|
||||
take over via the mechanized channel below; otherwise coordinate on the
|
||||
issue), never silently start a second owner.
|
||||
|
||||
**Mechanized ([org-internal #3667])**: the repo's session-conflicts script
|
||||
**Mechanized ([TT-3667])**: the repo's session-conflicts script
|
||||
(`<session-conflicts-cmd> <ticket>`) scans sources 1-3 in one read-only pass
|
||||
(exit 4 = conflict, matching the claim script; source 1 fail-opens visibly
|
||||
when the app API is down — the backend hard guard [org-internal #1989]
|
||||
when the app API is down — the backend hard guard [TT-1989]
|
||||
backstops); source 4 IS the claim script's compare-and-swap. Dead-claim
|
||||
takeover is mechanized in the claim script (see below); manual recipes:
|
||||
the headless-session-ops skill's ticket-recipe reference §0.
|
||||
|
||||
**Dead-claim takeover ([org-internal #3668]).** A claim whose session is
|
||||
**Dead-claim takeover ([TT-3668]).** A claim whose session is
|
||||
gone (404 on the app API) and whose branch was never pushed is a DEAD claim
|
||||
— the [org-internal #3419] shape. Do NOT hand-edit the dead claim comment
|
||||
— the [TT-3419] shape. Do NOT hand-edit the dead claim comment
|
||||
(the retired admin workaround — unauditable); run the claim script's
|
||||
takeover subcommand (`<claim-takeover-cmd> <ticket> <branch> --session-id
|
||||
<id>`) instead. Evidence rule (the claim script's header is normative): a
|
||||
@@ -77,8 +76,7 @@ ticket-driven work is to claim the ticket — one atomic action of THREE
|
||||
steps, valid ONLY when all complete: (1) set the issue assignee to the
|
||||
working account, (2) post a claim comment naming the workflow branch and
|
||||
session id, (3) push the workflow branch to remote (even an empty commit —
|
||||
a purely local branch is invisible to other sessions, [org-internal
|
||||
[org-internal #2280]/[org-internal #2282]]). Use the repo's claim wrappers (staged-transaction claim
|
||||
a purely local branch is invisible to other sessions, [TT-2280]/[TT-2282]). Use the repo's claim wrappers (staged-transaction claim
|
||||
script; exit codes and CAS semantics in its header; non-zero = NOT claimed)
|
||||
and the provision wrapper (adds the worktree + Tier-1 runs scaffold). The
|
||||
manual 3-step is the fallback where the scripts are unavailable, same
|
||||
@@ -88,7 +86,7 @@ re-verification.
|
||||
branch's recent commits for `#<ticket>` — surfacing an equivalent
|
||||
implementation already on main *before* the merge rejection.
|
||||
|
||||
**Merge-time review gate ([org-internal #2345]).** `pipeline/review-code` is
|
||||
**Merge-time review gate ([TT-2345]).** `pipeline/review-code` is
|
||||
a required status: merge needs it green OR the route-based exemption
|
||||
(Kind/* close routes skip review-code — posted by the repo's
|
||||
review-gate-exemption script). Read the commit-status endpoint for the PR
|
||||
@@ -102,7 +100,7 @@ your chunk before starting.
|
||||
|
||||
Two sessions owning the same issue or code area is never faster — it is the
|
||||
exact collision this rule prevents. If a collision HAS happened, follow the
|
||||
failure-path playbook at the ownership-collision runbook (Tier-2 reference
|
||||
failure-path playbook at the ownership-collision runbook (instance detail page
|
||||
page, reachable via the ticket backend).
|
||||
|
||||
### Scope
|
||||
|
||||
@@ -13,8 +13,8 @@ each other's entries and one session's `pop` returns the other session's
|
||||
content — or `drop`/`clear` wipes uncommitted work belonging to a session in
|
||||
a different worktree.
|
||||
|
||||
This failure mode has already destroyed completed work in production ([org-internal #1655] /
|
||||
[org-internal #1629] — a finished 25-test implementation overwritten on the shared stack).
|
||||
This failure mode has already destroyed completed work in production ([TT-1655] /
|
||||
[TT-1629] — a finished 25-test implementation overwritten on the shared stack).
|
||||
|
||||
**Iron Law: NEVER use `git stash` (or `git stash pop` / `push` / `drop` /
|
||||
`clear` / `apply`) inside an octopus worktree.**
|
||||
@@ -70,7 +70,7 @@ If you must `git checkout <base>` to reproduce a failure but the worktree is
|
||||
dirty, do **not** reach for stash. Instead:
|
||||
|
||||
- WIP-commit first (option 1), or
|
||||
- Use the lifecycle-managed scratch-worktree script ([org-internal #2790]) to materialise
|
||||
- Use the lifecycle-managed scratch-worktree script ([TT-2790]) to materialise
|
||||
the base commit in a *separate* worktree and run the failing test there:
|
||||
|
||||
```bash
|
||||
@@ -82,7 +82,7 @@ dirty, do **not** reach for stash. Instead:
|
||||
classification check. The script registers the worktree, symlinks
|
||||
`node_modules` from the source checkout when `bun.lock` matches, and the
|
||||
`sweep` backstop reclaims worktrees abandoned by dying sessions — bare
|
||||
`git worktree add /tmp/octopus/...` has no such recovery ([org-internal #2790]).
|
||||
`git worktree add /tmp/octopus/...` has no such recovery ([TT-2790]).
|
||||
|
||||
### Exceptions
|
||||
|
||||
@@ -110,4 +110,4 @@ dirty, do **not** reach for stash. Instead:
|
||||
If a parallel-session stash collision happens again despite this rule, treat
|
||||
it as a Sev-2 process incident: stop work, recover via
|
||||
`git fsck --unreachable` / `git log -g --walk-reflogs stash`, open a follow-up
|
||||
referencing [org-internal #1655].
|
||||
referencing [TT-1655].
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
- Test actual implementation, do not duplicate logic into tests
|
||||
- Tests cannot run from repo root (guard: `do-not-run-tests-from-root`); run from package dirs.
|
||||
- **Local pre-check: run `<test-cmd:changed>`** from the owning package after editing source. It selects only tests affected by your uncommitted + branch changes (path-mapping ∪ CodeGraph direct dependents) and runs them in a single process — seconds, machine stays responsive. Use `--print` to see the selection without running, `--all` to scan beyond the home package.
|
||||
- **Before a delivery push: `<test-cmd:changed>` green + `<typecheck-cmd>` clean** — same selector as CI's PR side (local parity, [org-internal #4425]). The full suite (`<test-cmd:parallel>`) stays with nightly / `run-full-tests` / manual pre-merge runs. 实例命令绑定见 core/adapters/TERMINOLOGY.md。
|
||||
- **Before a delivery push: `<test-cmd:changed>` green + `<typecheck-cmd>` clean** — same selector as CI's PR side (local parity, [TT-4425]). The full suite (`<test-cmd:parallel>`) stays with nightly / `run-full-tests` / manual pre-merge runs. 实例命令绑定见 core/adapters/TERMINOLOGY.md。
|
||||
- Never use the bare single-process test runner for the full suite; `<test-cmd:parallel>` shards it and process-isolates known-corrupting files. Parallelism is controlled by `TEST_SHARDS` (default 3; raise it on beefy CI runners, e.g. `TEST_SHARDS=7`).
|
||||
|
||||
### Pre-existing test failures must be filed, not silently logged
|
||||
@@ -18,7 +18,7 @@ problem" and do NOT bury it in a report body.
|
||||
|
||||
- Classify it: run the failing test on the base commit (see `verify` Phase 2.6).
|
||||
Fails there too → pre-existing (BF); passes there → regression you must fix.
|
||||
- De-duplicate BEFORE filing (retro [org-internal #2696]): search existing
|
||||
- De-duplicate BEFORE filing (retro [TT-2696]): search existing
|
||||
`baseline-failure` tickets — open AND closed — by test/file name to surface
|
||||
candidates, then match by **failure signature** (error signature + affected
|
||||
surface — one root-cause family may span several tests; see the
|
||||
@@ -40,7 +40,7 @@ it is a **flaky test**. Do NOT silently re-run until it passes and move on.
|
||||
|
||||
- Detect: re-run the suite (or use the project's flaky detector). Record every
|
||||
test that shows intermittent behavior — name, failure rate, and run count.
|
||||
- De-duplicate BEFORE filing (retro [org-internal #2696]): same
|
||||
- De-duplicate BEFORE filing (retro [TT-2696]): same
|
||||
signature-based procedure as baseline failures above, against existing
|
||||
`flaky-test` tickets.
|
||||
- File it: the Verifier registers every un-tracked flaky test as a
|
||||
@@ -55,7 +55,7 @@ it is a **flaky test**. Do NOT silently re-run until it passes and move on.
|
||||
NOT fix it in place — classify, file, and return to your task per the
|
||||
session-scope-guard rule. A repository-wide flaky test is a shared magnet —
|
||||
fixing it in place drifts off-task and collides with its owner
|
||||
([org-internal #1803]).
|
||||
([TT-1803]).
|
||||
|
||||
### Testing Kobalte components with happydom
|
||||
|
||||
@@ -74,7 +74,7 @@ render reliably.
|
||||
|
||||
A single component MUST NOT carry both a `.test.ts` and a `.test.tsx` test
|
||||
file — the two-file split duplicated ~3300 lines of overlapping assertions
|
||||
across one UI package [org-internal #1712]. Use exactly one file per
|
||||
across one UI package [TT-1712]. Use exactly one file per
|
||||
component, chosen by test style:
|
||||
|
||||
| Test style | Extension | When to use |
|
||||
@@ -129,17 +129,17 @@ expect(source).not.toContain(`@${NAMESPACE}`)
|
||||
Each package MUST have exactly ONE test root — no parallel tracks
|
||||
(`src/**/__tests__/`, a `tests/` dir alongside colocated `src/`, or a `test/`
|
||||
alongside `tests/`); a second root drifts and breaks test discovery
|
||||
([org-internal #1711], extended to all packages by [org-internal #1821]).
|
||||
([TT-1711], extended to all packages by [TT-1821]).
|
||||
|
||||
Rules:
|
||||
|
||||
- New tests: create them at the package's single root from the start.
|
||||
- Do NOT create `src/**/__tests__/` directories in any package — parallel
|
||||
tracks drift (residuals eliminated by [org-internal #1821]).
|
||||
tracks drift (residuals eliminated by [TT-1821]).
|
||||
- For `test/`-root packages: mirror the `src/` path (`test/<src-relative>.test.ts`);
|
||||
type-level tests live alongside the behavioral suites in the config area.
|
||||
- For colocated-root packages: keep tests next to the source file; one test
|
||||
file per component [org-internal #1712].
|
||||
file per component [TT-1712].
|
||||
|
||||
Per-package root tables live in the instance layer (they name concrete
|
||||
package paths); the invariant itself — ONE root per package — is universal.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
> Core 中立版(Increment 2 改写)。术语对照见 core/adapters/TERMINOLOGY.md;本组织实例表述见 dogfood 对应文件。
|
||||
|
||||
## Ticket Lifecycle — registry-first filing, claim-to-promote ([org-internal #3002] G1)
|
||||
## Ticket Lifecycle — registry-first filing, claim-to-promote ([TT-3002] G1)
|
||||
|
||||
Bugs worth fixing start life as a **registry row**, not an independent ticket.
|
||||
This extends the two-tier-artifacts philosophy to the ticket queue: a
|
||||
@@ -25,20 +25,20 @@ is how the 2026-08 backlog formed.)
|
||||
```
|
||||
|
||||
- **TD-NNN** is allocated at REGISTRATION via the ledger mutex
|
||||
[org-internal #3322]: the 配额账本脚本 (`td-alloc` 形态, `bash <alloc-script>
|
||||
[TT-3322]: the 配额账本脚本 (`td-alloc` 形态, `bash <alloc-script>
|
||||
<count> <source-slug> [--ticket N]`) takes a contiguous range from the TD
|
||||
allocation ledger (a standing tracker issue) — append-only `**td-alloc**`
|
||||
comments, earliest-comment-id wins on collision. **ANY allocation — manual
|
||||
included — must land a td-alloc comment on the ledger BEFORE the registry
|
||||
row is written** (script, tool API, or web UI). Hand-computed `max + 1`
|
||||
without a ledger comment is FORBIDDEN (parallel-session races,
|
||||
[org-internal #3322]). The id is **reserved for life**: promotion reuses
|
||||
[TT-3322]). The id is **reserved for life**: promotion reuses
|
||||
it, never renumbers. Run the alloc script's `--check` (reconciliation)
|
||||
when the last check predates this batch, and in retrospectives.
|
||||
- **De-duplication** queries the TD index (same-source rows) plus open
|
||||
promoted issues (cross-source); index matching replaces title-keyword
|
||||
matching (keyword dedup once produced 18 fragments from one source).
|
||||
- **Query-failure ruling ([org-internal #3383]: fail-open, visible)**: if the
|
||||
- **Query-failure ruling ([TT-3383]: fail-open, visible)**: if the
|
||||
dedup query itself errors (backend API failure — NOT "queried and found no
|
||||
match"), retry once; on second failure file anyway, marking the comment
|
||||
`dedup-unverified` for retro/reconciliation sweep. Fail-closed rejected:
|
||||
@@ -63,7 +63,7 @@ source.
|
||||
### PR 准入(pr-admission,TD-678)
|
||||
|
||||
会话交付物 = 分支 + 报告;开 PR 属编排职权,按容量串行一次一张、双绿并入
|
||||
再开下一张([org-internal #3864] 管合并出口、本节管 PR 入口)。交付推送前置
|
||||
再开下一张([TT-3864] 管合并出口、本节管 PR 入口)。交付推送前置
|
||||
本地验证(`<test-cmd:changed>` + `<typecheck-cmd>` 绿;实例命令绑定见
|
||||
core/adapters/TERMINOLOGY.md)。编排不可达可自开,PR 正文标
|
||||
`uncoordinated`。细则与门控项:pipeline-gate 清单 PR 准入节。
|
||||
@@ -75,7 +75,7 @@ occurrence: evidence (run, commit, failing output, failure rate) attaches as
|
||||
comments on the family's **umbrella ticket** (ticket-backend issue), keyed by
|
||||
failure signature (error signature + affected surface, not just
|
||||
`file::test-name` — one root-cause family may span several tests; precedents
|
||||
[org-internal #2585], [org-internal #2925]). Filing a new ticket when the
|
||||
[TT-2585], [TT-2925]). Filing a new ticket when the
|
||||
signature already matches an existing family (open or closed) is forbidden —
|
||||
attach evidence instead. A family umbrella is closed when its signature no
|
||||
longer reproduces.
|
||||
|
||||
@@ -53,8 +53,7 @@ Tier 1 is an optimization an artifact opts INTO, not out of.
|
||||
### Common classifications
|
||||
|
||||
Per-artifact table (review findings, prompt files, working drafts, draft/frozen
|
||||
contracts, issue checklist, 工件索引, `index.json` …): Tier-2 reference page
|
||||
`rules/two-tier-artifacts-detail` (reachable via the ticket backend); the
|
||||
contracts, issue checklist, 工件索引, `index.json` …): instance detail page `rules/two-tier-artifacts-detail` (reachable via the ticket backend); the
|
||||
decision rule above classifies anything unlisted.
|
||||
|
||||
### Two indexes, parallel not replacement
|
||||
@@ -74,14 +73,13 @@ Closed by the **Verifier** at verify PASS (or the Orchestrator when no
|
||||
verify). The archive step is the ONLY point active-run Tier 1 content enters
|
||||
git history:
|
||||
|
||||
1. Generate the bundle [org-internal #3604]:
|
||||
1. Generate the bundle [TT-3604]:
|
||||
the run-bundle generator script with `--slug {slug} [--ticket N] [--pr N]`
|
||||
— flips meta to "archived", hashes the workspace into the `sha256_16`
|
||||
manifest, writes `archive/{ticket}-{slug}.json`, validates.
|
||||
2. Commit the bundle on the workflow branch (rides into main via `--no-ff`).
|
||||
Direct pushes to main stay blocked by branch protection [org-internal
|
||||
[org-internal #3604]]; do not bypass.
|
||||
3. **归档前置校验** [org-internal #2727]: the generator validates by default
|
||||
Direct pushes to main stay blocked by branch protection [TT-3604]; do not bypass.
|
||||
3. **归档前置校验** [TT-2727]: the generator validates by default
|
||||
(`--no-validate` must not reach a merge); red exit = fix before close.
|
||||
The L0 merge gate rejects non-compliant bundles at merge anyway.
|
||||
|
||||
@@ -109,7 +107,7 @@ reproducibility trace — enough to reconstruct what a run produced.
|
||||
the designated re-read entry — after `compact`, read `runs/{slug}/index.json`,
|
||||
not conversation memory.
|
||||
|
||||
### Gate furlough([org-internal #3607])
|
||||
### Gate furlough([TT-3607])
|
||||
|
||||
强制门的唯一退出通道是 gate 台账(furlough ledger)的 furlough 条目
|
||||
(测量证据 + reopen 条件);无台账条目的减门/跳过改动一律拒绝,台账
|
||||
|
||||
@@ -24,7 +24,7 @@ On every substantive request that is tied to a ticket, run Step 0:
|
||||
`Kind/*` label when known; omit `kind` when not yet read (the tool returns
|
||||
the default route plus a read-ticket-then-re-invoke instruction). Agents
|
||||
with the route-gate option enabled enforce this mechanically
|
||||
[org-internal #3328]: other tool calls are dispatch-rejected until the
|
||||
[TT-3328]: other tool calls are dispatch-rejected until the
|
||||
路由解析工具 runs. Do not hand-read the routing table when the tool is
|
||||
available.
|
||||
3. **Read the ticket's `Kind/*` label** from the issue body or via the issue
|
||||
@@ -38,7 +38,7 @@ On every substantive request that is tied to a ticket, run Step 0:
|
||||
`skip` / `keep_gates` downstream. Never drop a gate the route lists in
|
||||
`keep_gates`; never add back a stage the route lists in `skip`.
|
||||
|
||||
### Degradation — label missing, unknown, or wrong ([org-internal #1828] AC)
|
||||
### Degradation — label missing, unknown, or wrong ([TT-1828] AC)
|
||||
|
||||
- **No ticket / no `Kind/*` label / label not in the table** → `default`
|
||||
route (natural-language matching). State this in one line ("no Kind/\*
|
||||
@@ -64,15 +64,14 @@ On every substantive request that is tied to a ticket, run Step 0:
|
||||
|
||||
### Runtime growth signals (post-sizing)
|
||||
|
||||
Two live growth mechanisms (narrative: Tier-2 reference page
|
||||
`rules/workflow-routing-detail`, reachable via the ticket backend; retired
|
||||
Two live growth mechanisms (narrative: instance detail page `rules/workflow-routing-detail`, reachable via the ticket backend; retired
|
||||
Size/* history: the instance rules-history archive). Canonical key:
|
||||
`dag.size_derivation.oversize_signals` (TD/DUP-F009).
|
||||
|
||||
- **DAG-routed tickets** (DAG Epic, DAG-routed `Kind/Feature`, their
|
||||
`Kind/Task` children — no `Size/*` tier): runtime growth fires the
|
||||
oversize signals → response is **re-derivation + review-dag re-run**.
|
||||
- **Bug tickets (big-bug relabel rule, [org-internal #3061])**: a `Kind/Bug`
|
||||
- **Bug tickets (big-bug relabel rule, [TT-3061])**: a `Kind/Bug`
|
||||
hitting a design-level trigger (design-decision root cause, shared-contract /
|
||||
public-API change, data migration) has outgrown the bug type — mandatory
|
||||
action is **relabel `Kind/Feature`** (Step 0 reroutes into the DAG
|
||||
@@ -87,10 +86,10 @@ never quietly override.
|
||||
|
||||
The DAG ticket pipeline (`analyze-dag` → task DAG → single gate `review-dag`)
|
||||
is the **default** route for `Kind/Epic` and `Kind/Feature`
|
||||
([org-internal #3061] Phase 2 / TD-388). Both resolve via the routes table
|
||||
([TT-3061] Phase 2 / TD-388). Both resolve via the routes table
|
||||
directly — **no trigger/marker check** (route rollback = revert PR).
|
||||
Authoritative definition: the `dag:` block in the workflow-routing table;
|
||||
narrative + history: Tier-2 reference page `rules/workflow-routing-detail`.
|
||||
narrative + history: instance detail page `rules/workflow-routing-detail`.
|
||||
|
||||
1. **`Kind/Epic` or `Kind/Feature` → `dag.route`**: entry `analyze-dag`,
|
||||
single gate `review-dag` (replaces review-design-space +
|
||||
@@ -126,12 +125,12 @@ rules archive; rulings in the phase-3 retirement ruling doc (Tier-2
|
||||
reference, reachable via the ticket backend). Nothing trims gates —
|
||||
`never_trim` is structural.
|
||||
|
||||
### 立案降档 — filing/sprint-mode([org-internal #3002] G5 / [org-internal #3007])
|
||||
### 立案降档 — filing/sprint-mode([TT-3002] G5 / [TT-3007])
|
||||
|
||||
Sprint 期间债务侧显式降档,不靠纪律。开关:routing table `filing.sprint-mode`
|
||||
(默认 `false`)。`true`(冲刺期)时 verify Phase 5.5 registry-only 不分严重度
|
||||
(登记行照写、零丢失;独立工单创建冻结至开关回 `false`,已登记行按
|
||||
ticket-lifecycle 规则正常认领升票;期间 HIGH/MEDIUM 行不被 reaper 触碰,
|
||||
[org-internal #3004])。BF/FT(5.55/5.56)不受影响。谁翻转:冲刺负责人(人),
|
||||
[TT-3004])。BF/FT(5.55/5.56)不受影响。谁翻转:冲刺负责人(人),
|
||||
在冲刺跟踪单记一行;开关值即 routing table 当前值,verify 每次运行时读取。
|
||||
动机与细节:Tier-2 参考页(经 ticket backend)`rules/workflow-routing-detail`。
|
||||
动机与细节:instance detail page `rules/workflow-routing-detail`。
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/review-status.schema.json",
|
||||
"title": "Review Status",
|
||||
"description": "Schema for tracking the lifecycle state of a review session. This file lives at runs/{slug}/reviews/{stage}/status.json: initialized by the Orchestrator at Phase A (step 0.5) with the full required set, appended by the Synthesizer at Phase B (history[] + current_round), and finalized with `converged` by the Orchestrator at Phase E (see skills/_shared/review-pipeline-phases.md). Reader: the retrospective token-telemetry probe (retrospective/scripts/token-telemetry.ts) walks runs/**/reviews/*/status.json (canonical) and the legacy .artifacts/**/reviews/*/status.json, reading `history[]` (code-level legacy alias `rounds[]`, both handled) and `current_round`. For CLOSED runs (active workspace removed at archive-at-close), the probe reconstructs per-stage round counts from reviews/{stage}/round{N}/ artifact paths in the committed archive bundle runs/archive/{slug}.json ([org-internal #2591]). Since TD/TRC-F006 ([org-internal #2688]) the archive bundle can also embed an explicit digest of this history[] (top-level review_history: {stage, rounds, final_verdict, per_round[]}) so round counts and verdicts stay verifiable offline, without path reconstruction.",
|
||||
"description": "Schema for tracking the lifecycle state of a review session. This file lives at runs/{slug}/reviews/{stage}/status.json: initialized by the Orchestrator at Phase A (step 0.5) with the full required set, appended by the Synthesizer at Phase B (history[] + current_round), and finalized with `converged` by the Orchestrator at Phase E (see skills/_shared/review-pipeline-phases.md). Reader: the retrospective token-telemetry probe (retrospective/scripts/token-telemetry.ts) walks runs/**/reviews/*/status.json (canonical) and the legacy .artifacts/**/reviews/*/status.json, reading `history[]` (code-level legacy alias `rounds[]`, both handled) and `current_round`. For CLOSED runs (active workspace removed at archive-at-close), the probe reconstructs per-stage round counts from reviews/{stage}/round{N}/ artifact paths in the committed archive bundle runs/archive/{slug}.json ([TT-2591]). Since TD/TRC-F006 ([TT-2688]) the archive bundle can also embed an explicit digest of this history[] (top-level review_history: {stage, rounds, final_verdict, per_round[]}) so round counts and verdicts stay verifiable offline, without path reconstruction.",
|
||||
"type": "object",
|
||||
"required": ["slug", "started_at", "current_round", "max_rounds", "converged", "history"],
|
||||
"properties": {
|
||||
@@ -19,7 +19,7 @@
|
||||
"max_rounds": {
|
||||
"type": "integer",
|
||||
"default": 3,
|
||||
"description": "Per-skill bound: `review-artifact` skill (process target) = 3 (the roadmap/design/plan targets were archived 2026-08-21, [org-internal #3072] phase 3); `review-code` = 2 default / 3 high-risk (`workflow-routing.yaml` `review.max_rounds`, [org-internal #3567]). `review-dag` (the review-artifact skill's DAG single-gate target) binds per depth from `dag_metrics.review_depth`: D1 ≤2, D2 ≤3, D3 ≤3, D4 ≤4 — D4 reaches round 4, exceeding the shared `review-artifact` default, so the DAG per-depth cap takes precedence (see review-artifact/SKILL.md review-dag Phase D MAX_ROUNDS). Set explicitly by the skill; default 3 is a fallback only."
|
||||
"description": "Per-skill bound: `review-artifact` skill (process target) = 3 (the roadmap/design/plan targets were archived 2026-08-21, [TT-3072] phase 3); `review-code` = 2 default / 3 high-risk (`workflow-routing.yaml` `review.max_rounds`, [TT-3567]). `review-dag` (the review-artifact skill's DAG single-gate target) binds per depth from `dag_metrics.review_depth`: D1 ≤2, D2 ≤3, D3 ≤3, D4 ≤4 — D4 reaches round 4, exceeding the shared `review-artifact` default, so the DAG per-depth cap takes precedence (see review-artifact/SKILL.md review-dag Phase D MAX_ROUNDS). Set explicitly by the skill; default 3 is a fallback only."
|
||||
},
|
||||
"converged": {
|
||||
"type": "boolean"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/reviewer-output.schema.json",
|
||||
"title": "Reviewer Output",
|
||||
"description": "Schema for a single reviewer's output for one review dimension. Also the Tier 1 review-findings schema ([org-internal #1988]): migrated skills (review-code) write each dimension's finding as a JSON file at runs/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json validated by this schema; the index.json row for that file carries type=review-findings, schema=this $id. When a dimension has multiple reviewers (dim_split > 1, e.g. D3 TOPO:2 / D4 TOPO:2), each writes its OWN slot file findings-{DIMENSION_CODE}-r{k}.json with reviewer_slot/reviewer_count set. See templates/runs-layout.md and rules/two-tier-artifacts.md.",
|
||||
"description": "Schema for a single reviewer's output for one review dimension. Also the Tier 1 review-findings schema ([TT-1988]): migrated skills (review-code) write each dimension's finding as a JSON file at runs/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json validated by this schema; the index.json row for that file carries type=review-findings, schema=this $id. When a dimension has multiple reviewers (dim_split > 1, e.g. D3 TOPO:2 / D4 TOPO:2), each writes its OWN slot file findings-{DIMENSION_CODE}-r{k}.json with reviewer_slot/reviewer_count set. See templates/runs-layout.md and rules/two-tier-artifacts.md.",
|
||||
"type": "object",
|
||||
"required": ["dimension", "dimension_label", "verdict", "quantitative_summary", "findings", "reviewed_files"],
|
||||
"properties": {
|
||||
@@ -17,7 +17,7 @@
|
||||
"reviewer_slot": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"description": "1-based slot of this reviewer WITHIN its dimension, when dim_split assigns >1 reviewer to the dimension (e.g. review-dag D3 TOPO:2, D4 TOPO:2 — dim_split per `workflow-routing.yaml` dag.size_derivation.review_depth). Multi-reviewer dimensions write one file per slot: findings-{DIMENSION_CODE}-r{k}.json. Omitted for single-reviewer dimensions (file stays findings-{DIMENSION_CODE}.json). Preserves per-reviewer attribution for the retrospective overlap analysis ([org-internal #2996] step 1a)."
|
||||
"description": "1-based slot of this reviewer WITHIN its dimension, when dim_split assigns >1 reviewer to the dimension (e.g. review-dag D3 TOPO:2, D4 TOPO:2 — dim_split per `workflow-routing.yaml` dag.size_derivation.review_depth). Multi-reviewer dimensions write one file per slot: findings-{DIMENSION_CODE}-r{k}.json. Omitted for single-reviewer dimensions (file stays findings-{DIMENSION_CODE}.json). Preserves per-reviewer attribution for the retrospective overlap analysis ([TT-2996] step 1a)."
|
||||
},
|
||||
"reviewer_count": {
|
||||
"type": "integer",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://eightarms.net/octopus-workflow/schemas/runs-bundle.schema.json",
|
||||
"title": "Tier 1 Run Archive Bundle",
|
||||
"description": "Composite archive bundle committed at close: runs/archive/{slug}.json = {meta, index}. Dual-profile by schema_version: >= 2 strict (closed core field set + free-form context bag), 1 or absent legacy (structural typing only; historical drift normalized by repair-run-bundles.ts, see [org-internal #2588]). Validated by validate-run-bundles.ts; CI wiring: .gitea/workflows/octopus-schemas.yml. Authoritative layout: templates/runs-layout.md. Boundary rule: rules/two-tier-artifacts.md.",
|
||||
"description": "Composite archive bundle committed at close: runs/archive/{slug}.json = {meta, index}. Dual-profile by schema_version: >= 2 strict (closed core field set + free-form context bag), 1 or absent legacy (structural typing only; historical drift normalized by repair-run-bundles.ts, see [TT-2588]). Validated by validate-run-bundles.ts; CI wiring: .gitea/workflows/octopus-schemas.yml. Authoritative layout: templates/runs-layout.md. Boundary rule: rules/two-tier-artifacts.md.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["meta", "index"],
|
||||
@@ -11,11 +11,11 @@
|
||||
"index": true,
|
||||
"working_notes": {
|
||||
"type": "string",
|
||||
"description": "Final content of runs/{slug}/working-notes.md ([org-internal #2600]), inlined at archive time when the file exists. The one Tier 1 artifact whose CONTENT (not just digest) rides in the bundle — the run's narrative memory (decisions, dead ends, reviewer feedback), consumed by later retro probes and the notes-injection degradation path ([org-internal #2601]). Absent when the run kept no working notes."
|
||||
"description": "Final content of runs/{slug}/working-notes.md ([TT-2600]), inlined at archive time when the file exists. The one Tier 1 artifact whose CONTENT (not just digest) rides in the bundle — the run's narrative memory (decisions, dead ends, reviewer feedback), consumed by later retro probes and the notes-injection degradation path ([TT-2601]). Absent when the run kept no working notes."
|
||||
},
|
||||
"review_history": {
|
||||
"type": "array",
|
||||
"description": "Offline-verifiability digest of the run's review rounds (TD/TRC-F006, [org-internal #2688]): one entry per review stage the run executed, each derived from that stage's live reviews/{stage}/status.json history[] at archive time. Lets closed-run probes reconstruct round counts and verdicts from the bundle alone, without the (removed) live workspace or path reconstruction ([org-internal #2591]). Absent when the run kept no review rounds.",
|
||||
"description": "Offline-verifiability digest of the run's review rounds (TD/TRC-F006, [TT-2688]): one entry per review stage the run executed, each derived from that stage's live reviews/{stage}/status.json history[] at archive time. Lets closed-run probes reconstruct round counts and verdicts from the bundle alone, without the (removed) live workspace or path reconstruction ([TT-2591]). Absent when the run kept no review rounds.",
|
||||
"items": { "$ref": "#/$defs/reviewHistoryEntry" }
|
||||
}
|
||||
},
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"browser-evidence",
|
||||
"other"
|
||||
],
|
||||
"description": "Artifact category. 'meta'/'index' for the manifest files themselves; stage categories for produced artifacts. 'review-synthesis' marks a synthesis result artifact (round verdict) as distinct from 'synthesis-prompt' (the Phase B task prompt) and 'review-status' (the lifecycle file). 'precondition-gate' marks the review-code mechanical-green gate log. 'working-notes' is the cross-stage narrative memory file ([org-internal #2600]) — one file per run, appended by every role at close, registered once (stage/produced_by null: multi-stage, multi-role). 'browser-evidence' marks a browser evidence pack manifest ([org-internal #4497] N-03, browser/{session-id}/manifest.json — shared/pack-manifest-v1)."
|
||||
"description": "Artifact category. 'meta'/'index' for the manifest files themselves; stage categories for produced artifacts. 'review-synthesis' marks a synthesis result artifact (round verdict) as distinct from 'synthesis-prompt' (the Phase B task prompt) and 'review-status' (the lifecycle file). 'precondition-gate' marks the review-code mechanical-green gate log. 'working-notes' is the cross-stage narrative memory file ([TT-2600]) — one file per run, appended by every role at close, registered once (stage/produced_by null: multi-stage, multi-role). 'browser-evidence' marks a browser evidence pack manifest ([TT-4497] N-03, browser/{session-id}/manifest.json — shared/pack-manifest-v1)."
|
||||
},
|
||||
"schema": {
|
||||
"type": ["string", "null"],
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"$defs": {
|
||||
"stage": {
|
||||
"type": "string",
|
||||
"description": "A pipeline stage identifier — the 5 live gates (post-[org-internal #3072] phase 3, 2026-08-21): review-dag, review-code, verify, audit-process, merge-pr. Production-phase names (requirements, design, roadmap, implement) and the 7 retired stage ids (roadmap-exit, review-roadmap, requirements-exit, design-exit, review-design-space, review-iteration-plan, plan-iterations) are no longer valid anywhere — the sizing block that consumed the phase names was retired the same ruling.",
|
||||
"description": "A pipeline stage identifier — the 5 live gates (post-[TT-3072] phase 3, 2026-08-21): review-dag, review-code, verify, audit-process, merge-pr. Production-phase names (requirements, design, roadmap, implement) and the 7 retired stage ids (roadmap-exit, review-roadmap, requirements-exit, design-exit, review-design-space, review-iteration-plan, plan-iterations) are no longer valid anywhere — the sizing block that consumed the phase names was retired the same ruling.",
|
||||
"enum": ["review-dag", "review-code", "verify", "audit-process", "merge-pr"]
|
||||
},
|
||||
"entry": {
|
||||
@@ -33,7 +33,7 @@
|
||||
"skill": {
|
||||
"type": ["string", "null"],
|
||||
"enum": ["implement", "review-artifact", "review-code", "verify", "analyze-dag", null],
|
||||
"description": "Skill name to enter, or null for natural-language routing. The legacy roadmap / requirements-elicitation / design / plan-iterations entries were removed when those skills were archived ([org-internal #3072] phase 3, 2026-08-21 - the instance archive)."
|
||||
"description": "Skill name to enter, or null for natural-language routing. The legacy roadmap / requirements-elicitation / design / plan-iterations entries were removed when those skills were archived ([TT-3072] phase 3, 2026-08-21 - the instance archive)."
|
||||
},
|
||||
"mode": {
|
||||
"type": ["string", "null"],
|
||||
@@ -56,7 +56,7 @@
|
||||
"preflight": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/preflightItem" },
|
||||
"description": "Evidence-based producer pre-flight checklist ([org-internal #2599]) — landed by a human from retrospective PRE-FLIGHT PROPOSAL rows. Absent/empty = no injection. Cap is governed by preflight.max_items (policy), not the schema."
|
||||
"description": "Evidence-based producer pre-flight checklist ([TT-2599]) — landed by a human from retrospective PRE-FLIGHT PROPOSAL rows. Absent/empty = no injection. Cap is governed by preflight.max_items (policy), not the schema."
|
||||
},
|
||||
"notes": { "type": "string" },
|
||||
"effort": {
|
||||
@@ -69,7 +69,7 @@
|
||||
"preflightPolicy": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Thresholds for the retro → routes.{Kind}.preflight evidence loop ([org-internal #2599]). Authoritative values live here; the retrospective consults this block, it does not restate the numbers.",
|
||||
"description": "Thresholds for the retro → routes.{Kind}.preflight evidence loop ([TT-2599]). Authoritative values live here; the retrospective consults this block, it does not restate the numbers.",
|
||||
"properties": {
|
||||
"max_items": { "type": "integer", "minimum": 1 },
|
||||
"min_sample": { "type": "integer", "minimum": 0 },
|
||||
@@ -86,7 +86,7 @@
|
||||
"item": { "type": "string", "description": "One checklist line the Producer verifies before implementing." },
|
||||
"evidence": {
|
||||
"type": "string",
|
||||
"description": "Retro reference justifying the item, e.g. 'retro [org-internal #2599]: COR × unhandled-null, 5/8 first-round FAILs on Kind/Bug'."
|
||||
"description": "Retro reference justifying the item, e.g. 'retro [TT-2599]: COR × unhandled-null, 5/8 first-round FAILs on Kind/Bug'."
|
||||
},
|
||||
"added_cycle": {
|
||||
"type": "string",
|
||||
@@ -97,23 +97,23 @@
|
||||
"filing": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Filing policy (立案/登记策略). sprint-mode ([org-internal #3007]): when true, verify Phase 5.5 promotes registry rows to tickets in sprint mode only. work-ticket-wip-cap ([org-internal #3005] G3): open non-TD work tickets beyond this count require scheduling evidence, else they stay registry rows.",
|
||||
"description": "Filing policy (立案/登记策略). sprint-mode ([TT-3007]): when true, verify Phase 5.5 promotes registry rows to tickets in sprint mode only. work-ticket-wip-cap ([TT-3005] G3): open non-TD work tickets beyond this count require scheduling evidence, else they stay registry rows.",
|
||||
"properties": {
|
||||
"sprint-mode": {
|
||||
"type": "boolean",
|
||||
"description": "Sprint-mode filing downgrade switch ([org-internal #3007])."
|
||||
"description": "Sprint-mode filing downgrade switch ([TT-3007])."
|
||||
},
|
||||
"work-ticket-wip-cap": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"description": "WIP cap on open non-TD work tickets (Kind/* without assignee) before new filings require scheduling evidence ([org-internal #3005] G3)."
|
||||
"description": "WIP cap on open non-TD work tickets (Kind/* without assignee) before new filings require scheduling evidence ([TT-3005] G3)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"review": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"description": "Review round budget (process-diet P0b, [org-internal #3567]/TD-564): a tail cut, not the norm — at budget without convergence, STOP; residual findings flow to the TD registry. High risk = a BLOCKER survived a round or the diff touches a frozen cross-session contract.",
|
||||
"description": "Review round budget (process-diet P0b, [TT-3567]/TD-564): a tail cut, not the norm — at budget without convergence, STOP; residual findings flow to the TD registry. High risk = a BLOCKER survived a round or the diff touches a frozen cross-session contract.",
|
||||
"required": ["max_rounds"],
|
||||
"properties": {
|
||||
"max_rounds": {
|
||||
@@ -152,7 +152,7 @@
|
||||
"preflight": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/$defs/preflightItem" },
|
||||
"description": "Evidence-based pre-flight checklist for the DAG route ([org-internal #2905] 方案 3) — same item shape as routes.{Kind}.preflight ([org-internal #2599]). Landed by a human from retrospective PRE-FLIGHT PROPOSAL rows, including the 'REQ × late-discovery' root cause (requirements found only after the DAG froze: DAG oversize signals, demo-period feedback). Consumed by analyze-dag (the route's entry skill) before decomposition. Absent/empty = no injection. Optional — deliberately NOT in dagRoute.required (spec-02 §2.8 frozen required array unchanged). Cap governed by preflight.max_items (policy), not the schema."
|
||||
"description": "Evidence-based pre-flight checklist for the DAG route ([TT-2905] 方案 3) — same item shape as routes.{Kind}.preflight ([TT-2599]). Landed by a human from retrospective PRE-FLIGHT PROPOSAL rows, including the 'REQ × late-discovery' root cause (requirements found only after the DAG froze: DAG oversize signals, demo-period feedback). Consumed by analyze-dag (the route's entry skill) before decomposition. Absent/empty = no injection. Optional — deliberately NOT in dagRoute.required (spec-02 §2.8 frozen required array unchanged). Cap governed by preflight.max_items (policy), not the schema."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -183,7 +183,7 @@
|
||||
"replaces": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Historical documentation of which legacy gates the single gate replaced ([org-internal #3072] phase 3 retired them) — free-form strings, not the live stage vocabulary."
|
||||
"description": "Historical documentation of which legacy gates the single gate replaced ([TT-3072] phase 3 retired them) — free-form strings, not the live stage vocabulary."
|
||||
},
|
||||
"depth_from": { "type": "string", "enum": ["size_derivation"] },
|
||||
"never_trim": { "type": "boolean" }
|
||||
@@ -201,7 +201,7 @@
|
||||
"items": { "type": "string", "enum": ["Kind/Epic", "Kind/Feature"] },
|
||||
"uniqueItems": true,
|
||||
"minItems": 1,
|
||||
"description": "Ticket kinds whose DAG children reference them as ## 父级 / Parent ([org-internal #3061] Phase 2 / TD-388: Kind/Feature added alongside Kind/Epic)."
|
||||
"description": "Ticket kinds whose DAG children reference them as ## 父级 / Parent ([TT-3061] Phase 2 / TD-388: Kind/Feature added alongside Kind/Epic)."
|
||||
},
|
||||
"parent_aggregator": { "type": "boolean" }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
> - `frontend/SKILL.md`
|
||||
>
|
||||
> (The `roadmap`, `requirements-elicitation`, `design`, and `plan-iterations`
|
||||
> referencing skills were archived 2026-08-21, [org-internal #3072] phase 3 — see
|
||||
> referencing skills were archived 2026-08-21, [TT-3072] phase 3 — see
|
||||
> `.octopus/archive/skills/`; their copies of this directive moved with them.)
|
||||
>
|
||||
> **When editing:** update this file only. Each skill references this file via a
|
||||
|
||||
@@ -70,6 +70,6 @@
|
||||
`review-dag` (review-artifact targets — same id feeds the
|
||||
`pipeline/{REVIEW_TYPE}` commit-status context; see review-artifact Phase
|
||||
Bindings). (The design-space/plan targets were archived 2026-08-21,
|
||||
[org-internal #3072] phase 3.)
|
||||
[TT-3072] phase 3.)
|
||||
- `{DIMENSION_COUNT}` — 10 (code review; 9 in standalone-bugfix mode), 3 (review-dag single gate), or 10 (process audit); used in
|
||||
the skill's SKILL.md reference text, not inside this template body
|
||||
|
||||
@@ -113,7 +113,7 @@ Each skill references this base template via `core/skills/_shared/review-orchest
|
||||
rather than inlining the JSON array. This centralization ensures the base
|
||||
permission surface stays consistent across all review/audit skills.
|
||||
|
||||
**Tier-1 local exception** ([org-internal #1988]): migrated skills that write raw per-dimension
|
||||
**Tier-1 local exception** ([TT-1988]): migrated skills that write raw per-dimension
|
||||
findings to `<runs-root>/**` (e.g. `review-code`) add ONE scoped `edit` allow
|
||||
to the base set — `{ permission: "edit", pattern: "<runs-root>/**", action:
|
||||
"allow" }` — so the reviewer can write its OWN finding file. This is a
|
||||
@@ -122,7 +122,7 @@ edit on the code under review, so rule #7 (auditor independence) holds. See
|
||||
`_shared/review-pipeline-phases.md` Phase A step 4 and `review-code/SKILL.md`
|
||||
Phase A step 3 for the inline extended array.
|
||||
|
||||
Residual risk — accepted trade-off (TD/STD-F004, [org-internal #2688]): the grant is scoped
|
||||
Residual risk — accepted trade-off (TD/STD-F004, [TT-2688]): the grant is scoped
|
||||
to `<runs-root>/**`, wider than the reviewer's own findings file. Per-file
|
||||
narrowing was considered and rejected: findings paths are round- and
|
||||
dimension-dependent (`{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json`),
|
||||
@@ -132,7 +132,7 @@ residual exposure — a misbehaving reviewer could overwrite a sibling stage's
|
||||
Tier 1 files — is recorded here as accepted; auditor independence is
|
||||
unaffected (code under review lives outside `runs/`).
|
||||
|
||||
### No bash for Explorer sub-agents (deliberate boundary, [org-internal #2115] RC4 / [org-internal #2126])
|
||||
### No bash for Explorer sub-agents (deliberate boundary, [TT-2115] RC4 / [TT-2126])
|
||||
|
||||
Explorer sub-agents (Reviewer / auditor / Tool roles) have **no bash**. The
|
||||
`explorer` agent is built deny-by-default at
|
||||
@@ -151,7 +151,7 @@ Synthesizer / Verifier's job (Worker sub-agents, which DO have bash via the
|
||||
`worker` agent defaults) — not the Reviewer's. Report the need in findings
|
||||
instead of attempting bash.
|
||||
|
||||
> **[org-internal #2126] Task 2 conclusion — keep + document.** The `deny **` pushed per-tool
|
||||
> **[TT-2126] Task 2 conclusion — keep + document.** The `deny **` pushed per-tool
|
||||
> at `<harness-package>/src/session/prompt.ts` is the **session tool-enable /
|
||||
> disable map** (it disables `todowrite` / `task` / `experimental.primary_tools`
|
||||
> for subagents and allows forwarded MCP tools). It is NOT the source of the
|
||||
@@ -165,4 +165,4 @@ instead of attempting bash.
|
||||
- `{REVISION_ROLE}` — "Developer" (code review), "Analyst" (review-dag single
|
||||
gate), or "Remediator" (process audit). The Worker role that revises
|
||||
artifacts between rounds. (The Architect/Planner revision roles belonged to
|
||||
the archived design-space / iteration-plan targets, [org-internal #3072] phase 3.)
|
||||
the archived design-space / iteration-plan targets, [TT-3072] phase 3.)
|
||||
|
||||
@@ -9,14 +9,14 @@ parameters and reference this doc rather than duplicating the shared mechanics.
|
||||
legitimately uses "auditor"/"Re-audit" terminology. All generic descriptions
|
||||
use `{REVIEWER_OR_AUDITOR}`.
|
||||
|
||||
**Output model — two findings sinks** ([org-internal #1988] Tier 1 migration): raw per-dimension
|
||||
**Output model — two findings sinks** ([TT-1988] Tier 1 migration): raw per-dimension
|
||||
reviewer findings have ONE of two sinks, chosen per skill. The **synthesis**
|
||||
(human gate) and **commit status** are ALWAYS Tier 2 (Gitea) regardless of the
|
||||
findings sink.
|
||||
|
||||
| Sink | Skills | Reviewer writes findings to | Synthesizer reads findings from |
|
||||
|---|---|---|---|
|
||||
| `tier1-local` (migrated) | `review-code`, `review-artifact` (live targets: review-dag, audit-process; the roadmap/design-space/plan targets were archived 2026-08-21, [org-internal #3072] phase 3) | `<runs-root>/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json` (validated by `core/schemas/reviewer-output.schema.json`) | the local finding files (no Gitea call) |
|
||||
| `tier1-local` (migrated) | `review-code`, `review-artifact` (live targets: review-dag, audit-process; the roadmap/design-space/plan targets were archived 2026-08-21, [TT-3072] phase 3) | `<runs-root>/{slug}/reviews/{stage}/round{N}/findings-{DIMENSION_CODE}.json` (validated by `core/schemas/reviewer-output.schema.json`) | the local finding files (no Gitea call) |
|
||||
| `tier2-comment` (fallback) | _(none — all targets migrated)_ | Gitea PR/issue comment via `工单评论 API(见 TERMINOLOGY)` (Pattern 5) | `工单评论 API(见 TERMINOLOGY)` (Pattern 3) |
|
||||
|
||||
Migration complete — every review/audit skill now outputs `tier1-local`; the
|
||||
@@ -61,7 +61,7 @@ in `_shared/gitea-write-patterns.md`.
|
||||
`stage` = `{REVIEW_TYPE}`, `produced_by` = `Orchestrator`, `schema` = the
|
||||
review-status `$id`).
|
||||
|
||||
1. **Tool-availability probe** (defense-in-depth, [org-internal #2115] RC1 / [org-internal #2126]). Before
|
||||
1. **Tool-availability probe** (defense-in-depth, [TT-2115] RC1 / [TT-2126]). Before
|
||||
dispatching any {REVIEWER_OR_AUDITOR}, verify reviewers will be able to read
|
||||
wiki artifacts (requirements / design / plan / prior-review reports). A
|
||||
reviewer that cannot read its inputs aborts or hallucinates — catch this ONCE
|
||||
@@ -74,7 +74,7 @@ in `_shared/gitea-write-patterns.md`.
|
||||
reachable; anything else — timeout, connection refused, 5xx — is
|
||||
unreachable). If reachable → continue to step 2.
|
||||
- **Fallback path** (when REST is unreachable, e.g. a
|
||||
cross-repo scenario [org-internal #2115]): verify the **local wiki clone** at
|
||||
cross-repo scenario [TT-2115]): verify the **local wiki clone** at
|
||||
`<wiki-clone-root>/{repo}-wiki/` is readable —
|
||||
`glob(pattern="*.md", path="<wiki-clone-root>/{repo}-wiki/")`. If the clone
|
||||
is readable → continue to step 2; reviewers use the local clone (see
|
||||
@@ -266,7 +266,7 @@ Otherwise:
|
||||
- The {REVISION_ROLE} MUST NOT receive the full text of all findings inline —
|
||||
use finding-file path / comment references only to avoid context explosion.
|
||||
- Convergence status: blockers/majors remaining vs. previous round.
|
||||
- **Revision survival ([org-internal #2601]) — primary path**: the task tool's completion
|
||||
- **Revision survival ([TT-2601]) — primary path**: the task tool's completion
|
||||
output includes a `task_id`; passing it back resumes the SAME
|
||||
{REVISION_ROLE} subagent session instead of creating a fresh one. Round 1:
|
||||
persist the returned `task_id` with the round's working-notes entry (it
|
||||
@@ -322,24 +322,24 @@ After the {REVISION_ROLE} completes revision:
|
||||
`core/schemas/review-status.schema.json`).
|
||||
- `review-code` skill: **2** default / **3** high-risk (a BLOCKER survived a
|
||||
round, or the diff touches a frozen cross-session contract) —
|
||||
`<instance-root>/workflow-routing.yaml` `review.max_rounds` ([org-internal #3567], process-diet
|
||||
`<instance-root>/workflow-routing.yaml` `review.max_rounds` ([TT-3567], process-diet
|
||||
P0b). At budget without convergence: STOP, register the remaining
|
||||
BLOCKER/MAJOR findings as TD registry rows, then compute the verdict
|
||||
with the shared three-tier ladder (`core/schemas/synthesis.schema.json`
|
||||
`overall_verdict` + `core/skills/_shared/review-orchestrator-rules.md`
|
||||
rule 3): FAIL if any BLOCKER or FAIL dimension remains, else WARN,
|
||||
PASS only if every remaining dimension is PASS ([org-internal #4786]:
|
||||
PASS only if every remaining dimension is PASS ([TT-4786]:
|
||||
the prior binary "else PASS" wording silently upgraded WARN-eligible
|
||||
outcomes to PASS; a PASS round has already stopped at the convergence
|
||||
table above, so the residual tail lands WARN or FAIL). The debt is
|
||||
carried by those TD registry rows
|
||||
(see `review-code/SKILL.md` Phase D). This
|
||||
supersedes the 2026-08-25 [org-internal #3380] calibration (p50=2, p95=5, n=66): the runs
|
||||
supersedes the 2026-08-25 [TT-3380] calibration (p50=2, p95=5, n=66): the runs
|
||||
past round 3 are the marathon tail this budget exists to cut; their residue
|
||||
flows to the TD registry instead of reviewer rounds. Ledger:
|
||||
`docs/workflow-refactor/thresholds-ledger.md`.
|
||||
|
||||
Rationale for `review-artifact` = 3 (evaluated in [org-internal #1969], replacing the prior blanket
|
||||
Rationale for `review-artifact` = 3 (evaluated in [TT-1969], replacing the prior blanket
|
||||
default of 5): (1) the Round-3 Escalation Guardrail below already detects
|
||||
non-convergence at the start of round 3; (2) the INFO-disposition rule below
|
||||
removes spurious WARN rounds previously caused by non-blocking INFO findings;
|
||||
@@ -350,8 +350,8 @@ reaches round 4 — its round budget is 2/3, see the binding above.)
|
||||
|
||||
**Provisional, not empirically validated**: the four safeguards make `review-artifact`=3
|
||||
defensible, but it has no fresh run-data yet. Treat it as a hypothesis to
|
||||
confirm via the retrospective signal ([org-internal #1834]; gate-trim's landing machinery was
|
||||
retired, [org-internal #3072] phase 3 — the check is observational, not a trim proposal): if
|
||||
confirm via the retrospective signal ([TT-1834]; gate-trim's landing machinery was
|
||||
retired, [TT-3072] phase 3 — the check is observational, not a trim proposal): if
|
||||
live `review-artifact` runs frequently hit round 3 still improving yet are
|
||||
forced to stop at WARN/FAIL, bump it back to 4.
|
||||
|
||||
@@ -379,8 +379,8 @@ block convergence and NEVER drive a reviser round.
|
||||
**Round-3 Escalation Guardrail** (applies to the `review-artifact` skill's
|
||||
live targets — the process audit target AND the review-dag single-gate
|
||||
target; the roadmap / design / plan targets were archived 2026-08-21,
|
||||
[org-internal #3072] phase 3). `review-code` does NOT use this guardrail; it uses its round
|
||||
budget ([org-internal #3567], see the `{MAX_ROUNDS}` binding above).
|
||||
[TT-3072] phase 3). `review-code` does NOT use this guardrail; it uses its round
|
||||
budget ([TT-3567], see the `{MAX_ROUNDS}` binding above).
|
||||
|
||||
At the start of round 3, if the combined blocker+major count is still >50% of
|
||||
round 1's count, STOP the loop and surface to the user:
|
||||
@@ -391,7 +391,7 @@ round 1's count, STOP the loop and surface to the user:
|
||||
> (a) Return to upstream — for the `process` audit target, escalate to the
|
||||
> octopus maintainer for a process-level redesign (the legacy producer skills
|
||||
> `roadmap` / `requirements-elicitation` / `design` / `plan-iterations` were
|
||||
> archived 2026-08-21, [org-internal #3072] phase 3 — `<instance-root>/archive/`), then restart this
|
||||
> archived 2026-08-21, [TT-3072] phase 3 — `<instance-root>/archive/`), then restart this
|
||||
> review at round 1.
|
||||
> (b) Continue iterating — accept that more rounds may be needed (capped by
|
||||
> `{MAX_ROUNDS}`).
|
||||
@@ -406,7 +406,7 @@ review and escalate to a human, or (b) continue into round 4 — via the
|
||||
`question` tool. The guard means "escalate with a choice", NOT "force-stop".
|
||||
The choice is UNCONDITIONAL at the round-3→4 transition — instance skills may
|
||||
narrow when an escalation *variant* (e.g. a design-level decision) fires, but
|
||||
never narrow the choice gate itself. The call MUST be optionized ([org-internal #3378]):
|
||||
never narrow the choice gate itself. The call MUST be optionized ([TT-3378]):
|
||||
two options — `Stop & escalate to a human` (first, when recommended) /
|
||||
`Continue into round 4` — with `stage` set to the running skill's stage so
|
||||
auto-approval applies in autonomous mode; free-text asking is a spec
|
||||
@@ -414,12 +414,12 @@ violation.
|
||||
Instance: review-dag D4 option-b (`review-artifact/SKILL.md` §"Round-3
|
||||
Escalation Guardrail interaction") — the sole live instance, its D4 round cap
|
||||
(≤4) being the only budget that reaches round 4 (`review-code` is capped 2/3,
|
||||
[org-internal #3567]).
|
||||
Rationale (retro 2026-08-21 / [org-internal #3050]): unattended late-round loops drift into
|
||||
[TT-3567]).
|
||||
Rationale (retro 2026-08-21 / [TT-3050]): unattended late-round loops drift into
|
||||
review marathons — the choice forces the design-level stall to surface to a
|
||||
human at round 4 instead of round 6.
|
||||
|
||||
**Efficiency optimization**: From round 2 onward ([org-internal #2598]), only spawn
|
||||
**Efficiency optimization**: From round 2 onward ([TT-2598]), only spawn
|
||||
{REVIEWER_OR_AUDITOR}s for dimensions that had FAIL, WARN, or UNRESOLVED in
|
||||
the previous round. Every 2 rounds, run a full {DIMENSION_COUNT}-reviewer
|
||||
sweep to catch regressions. From round 2 onward reviewer input is also
|
||||
@@ -486,7 +486,7 @@ not the round-1 full set.
|
||||
`REQUEST_REVIEW` registration to be recorded, and only THEN ask the human
|
||||
to approve. Approving before the reviewer is registered produces
|
||||
`official: false` on the approval — the gate treats the PR as unapproved
|
||||
and the approval must be re-done. ([org-internal #1931]: audit R2→R3 re-loop + re-approve,
|
||||
and the approval must be re-done. ([TT-1931]: audit R2→R3 re-loop + re-approve,
|
||||
~30min wasted on exactly this ordering.)
|
||||
|
||||
4. Present the final report to the user and obtain approval via the `question`
|
||||
|
||||
@@ -31,7 +31,7 @@ After revising, report a summary of changes made:
|
||||
- Findings waived as cosmetic MINOR (round 2+): {WAIVED-{id} → reason}
|
||||
|
||||
Persist that summary to `{RETURN_FILE}` as your LAST action, BEFORE
|
||||
returning it — worker-report persistence ([org-internal #2847], see
|
||||
returning it — worker-report persistence ([TT-2847], see
|
||||
`.octopus/skills/_shared/worker-report-persistence.md`). The persisted copy
|
||||
is the report of record; if your completion notification is lost, the
|
||||
Orchestrator recovers the revision outcome from this file.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
> Core 中立版(Increment 6a 改写,原 deferHard verbatim)。编号与条目结构严格不变(C-2 不变量);实例术语按 `core/adapters/TERMINOLOGY.md` 绑定。
|
||||
name: Coordinator
|
||||
purpose: >
|
||||
Pool dispatch coordinator (billing-v2 [org-internal #4041] §7, REQ-F-012): a wake-driven,
|
||||
Pool dispatch coordinator (billing-v2 [TT-4041] §7, REQ-F-012): a wake-driven,
|
||||
STATELESS decision-maker session living in the pool pod alongside workers.
|
||||
List eligible issues (Gitea API, scoped token) → produce DAG-aware dispatch
|
||||
proposals → commit each dispatch through the N-16 assignment API
|
||||
@@ -62,14 +62,14 @@ agents_md:
|
||||
#
|
||||
# Security posture (AC-5, see docs/security/threat-model.md §自治批处理):
|
||||
# the coordinator authenticates with a workspace-level API token
|
||||
# (TD-687/[org-internal #3898] owner-minted, jti-revocable, role claim org_role). TODAY'S
|
||||
# (TD-687/[TT-3898] owner-minted, jti-revocable, role claim org_role). TODAY'S
|
||||
# mint shape hardcodes org_role=viewer — read-capable only (assignment table
|
||||
# + pool surfaces); the editor-capable mint needed for dispatch submission is
|
||||
# an explicit deployment-time decision on the [org-internal #3898] channel (not landed with
|
||||
# an explicit deployment-time decision on the [TT-3898] channel (not landed with
|
||||
# N-19). Either way the token can NOT mint tokens, touch wallet internals, or
|
||||
# merge PRs — the merge gate stays human (E-4).
|
||||
#
|
||||
# Worker-report persistence ([org-internal #2847] — see
|
||||
# Worker-report persistence ([TT-2847] — see
|
||||
# core/skills/_shared/worker-report-persistence.md): a Coordinator
|
||||
# sub-agent persists its FINAL RETURN REPORT to disk as its LAST action,
|
||||
# before returning — <runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md
|
||||
|
||||
@@ -15,7 +15,7 @@ agents_md:
|
||||
- claim-discipline
|
||||
- compact
|
||||
|
||||
# Worker-report persistence ([org-internal #2847], retro-2696 AI#2 — see
|
||||
# Worker-report persistence ([TT-2847], retro-2696 AI#2 — see
|
||||
# core/skills/_shared/worker-report-persistence.md): every Producer
|
||||
# sub-agent persists its FINAL RETURN REPORT to disk as its LAST action,
|
||||
# before returning — <runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md
|
||||
@@ -23,7 +23,7 @@ agents_md:
|
||||
# else /tmp/octopus/{chunk-id}-worker-{seq}.md. The persisted copy is the
|
||||
# report of record; the task notification is a convenience copy.
|
||||
#
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): at stage exit the Producer appends ONE entry (≤30 lines:
|
||||
# decisions and why, dead ends, reviewer feedback that changed the work, hints
|
||||
# for the next stage) to <runs-root>/{slug}/working-notes.md, and registers
|
||||
|
||||
@@ -14,7 +14,7 @@ agents_md:
|
||||
- ticket-lifecycle
|
||||
- compact
|
||||
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): the Reviewer side appends ONE distilled entry via the
|
||||
# Synthesizer at review convergence — never per dimension dispatch (9
|
||||
# dimension dispatches = 1 entry) — to <runs-root>/{slug}/working-notes.md.
|
||||
|
||||
@@ -12,7 +12,7 @@ agents_md:
|
||||
- claim-discipline
|
||||
- compact
|
||||
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): Tool agents append to <runs-root>/{slug}/working-notes.md
|
||||
# ONLY when the task produced a load-bearing finding (e.g. image evidence that
|
||||
# changed a decision) — not for routine single-shot output.
|
||||
|
||||
@@ -15,7 +15,7 @@ agents_md:
|
||||
- claim-discipline
|
||||
- compact
|
||||
|
||||
# Worker-report persistence ([org-internal #2847], retro-2696 AI#2 — see
|
||||
# Worker-report persistence ([TT-2847], retro-2696 AI#2 — see
|
||||
# core/skills/_shared/worker-report-persistence.md): the Verifier
|
||||
# persists its FINAL RETURN REPORT (DoD verdict + evidence pointers) to disk
|
||||
# as its LAST action, before returning —
|
||||
@@ -23,7 +23,7 @@ agents_md:
|
||||
# else /tmp/octopus/{chunk-id}-worker-{seq}.md. The persisted copy is the
|
||||
# report of record; the task notification is a convenience copy.
|
||||
#
|
||||
# Working-notes contract ([org-internal #2600] — see core/templates/runs-layout.md §
|
||||
# Working-notes contract ([TT-2600] — see core/templates/runs-layout.md §
|
||||
# working-notes.md): the Verifier appends ONE entry at verify exit (what the
|
||||
# DoD sweep caught, flaky/deferral context the next run should know). The
|
||||
# Phase 5.5 archive step additionally inlines the final working-notes.md
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
- **Commit SHA**: `{SHA}` (the HEAD commit being reviewed).
|
||||
- **Review type**: `{REVIEW_TYPE}` — one of `review-code`, `review-dag`,
|
||||
`audit-process` (the `review-design-space` / `review-iteration-plan` /
|
||||
`review-roadmap` targets were archived 2026-08-21, [org-internal #3072] phase 3 — their
|
||||
`review-roadmap` targets were archived 2026-08-21, [TT-3072] phase 3 — their
|
||||
historical synthesis data remains readable).
|
||||
|
||||
## Your Job
|
||||
@@ -189,7 +189,7 @@
|
||||
9. Persist your return summary (the exact text from the Return Format
|
||||
below) to `<runs-root>/{slug}/reviews/{stage}/round{N}/synthesis-return.md`
|
||||
(Tier 1) as your LAST action, BEFORE returning it — worker-report
|
||||
persistence ([org-internal #2847], `_shared/worker-report-persistence.md`). The persisted
|
||||
persistence ([TT-2847], `_shared/worker-report-persistence.md`). The persisted
|
||||
copy is the report of record; if your completion notification is lost, the
|
||||
Orchestrator recovers the round verdict from this file.
|
||||
|
||||
@@ -211,7 +211,7 @@ synthesis JSON — it is already posted to the pipeline PR / source issue
|
||||
comment (for audit-process runs, the wiki page `audit/{date}/round{N}/synthesis`).
|
||||
Persist this summary verbatim to
|
||||
`<runs-root>/{slug}/reviews/{stage}/round{N}/synthesis-return.md` before
|
||||
returning (step 9 above — worker-report persistence [org-internal #2847]).
|
||||
returning (step 9 above — worker-report persistence [TT-2847]).
|
||||
|
||||
```
|
||||
## Synthesis Complete
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
> Canonical convention for every worker sub-agent dispatch (roles whose
|
||||
> `agent:` is `worker` — Producer sub-roles, Verifier, Synthesizer, …),
|
||||
> foreground or background (`task background=true`). Origin: retro WWW#5 /
|
||||
> [org-internal #2696] action item #2 ([org-internal #2847]) — at least one confirmed case where a
|
||||
> [TT-2696] action item #2 ([TT-2847]) — at least one confirmed case where a
|
||||
> background worker's completion report reached the orchestrating session
|
||||
> only via the task-tool notification; the notification was lost and the
|
||||
> report evaporated, leaving nothing but reverse-engineering from artifacts.
|
||||
|
||||
@@ -3,7 +3,7 @@ name: analyze-dag
|
||||
description: >
|
||||
Use ONLY when an Epic is routed to the DAG ticket pipeline (Kind/Epic or
|
||||
Kind/Feature — both resolve to analyze-dag via the routes table directly,
|
||||
[org-internal #3072] phase 3 / [org-internal #3061] Phase 2). The
|
||||
[TT-3072] phase 3 / [TT-3061] Phase 2). The
|
||||
Analyst decomposes the Epic into a single task-DAG artifact — merging
|
||||
roadmap+requirements+design+plan into one graph (nodes = acceptance
|
||||
criteria, edges = contracts, topology = plan).
|
||||
@@ -31,7 +31,7 @@ role: Producer
|
||||
analyze-dag is the **entry skill** of the DAG ticket pipeline
|
||||
(`dag.route.entry.skill`, spec-07 §2). For a DAG-routed Epic
|
||||
(`Kind/Epic`, or `Kind/Feature` — both resolve here via the routes table
|
||||
directly, [org-internal #3072] phase 3 / [org-internal #3061] Phase 2 / TD-388 —
|
||||
directly, [TT-3072] phase 3 / [TT-3061] Phase 2 / TD-388 —
|
||||
including BACKFILL mode for MVP graduates and big-bug relabels), it
|
||||
**replaces** `roadmap` + `requirements-elicitation` + `design` +
|
||||
`plan-iterations` and produces **ONE artifact**: the task DAG, published as
|
||||
@@ -66,12 +66,12 @@ a topological order (the plan), then publishes the single graph.
|
||||
| 设计主导 | 主要风险是一个有 ≥2 个可行选项的架构/平台决策,而非任务分解;需要先做一次探索 | 将开放问题转 `prototype`(THROWAWAY spike)或设计探索;决策记录后重入 |
|
||||
| 外部契约未决 | scope 依赖未决的外部契约(第三方 schema、上游 API 未定) | 按 External-System Rule(见下文)解析或围栏;不可拆的残余隔离后再重入 |
|
||||
|
||||
**反向拦截(Kind/MVP 降级建议,[org-internal #3061])**:一个 `Kind/Feature` 工单在分解预检中
|
||||
**反向拦截(Kind/MVP 降级建议,[TT-3061])**:一个 `Kind/Feature` 工单在分解预检中
|
||||
暴露"概念未稳"(scope 仍在探索、成功标准未定、决策日志会推翻节点划分)时,
|
||||
正确出口不是硬分解,而是建议改标签 `Kind/MVP` 先行交互式验证——概念稳定后
|
||||
经 backfill 模式(见下文)带着决策日志重入。
|
||||
|
||||
### Phase 0 需求澄清(disqualifier 的结构化扩展,[org-internal #3061])
|
||||
### Phase 0 需求澄清(disqualifier 的结构化扩展,[TT-3061])
|
||||
|
||||
预检不止于"能否分解",还须证明"需求已澄清到可分解"。两项强制检查:
|
||||
|
||||
@@ -217,7 +217,7 @@ Rules:
|
||||
- `refs_by` is derived from the REQMAP "every requirement ≥1 node" criterion
|
||||
(missing coverage = a requirement with no node).
|
||||
|
||||
## Breadth Coverage — 类目覆盖矩阵 + 排除账本 ([org-internal #2905] 方案 1)
|
||||
## Breadth Coverage — 类目覆盖矩阵 + 排除账本 ([TT-2905] 方案 1)
|
||||
|
||||
The four-stage fold that produced the single DAG artifact kept requirement
|
||||
**depth** (REQMAP three-path coverage + falsifiable AC) but dropped legacy
|
||||
@@ -271,7 +271,7 @@ sub-page `{epic-slug}/dag-coverage` using the same mechanics as AC sinking
|
||||
frozen copy) — purely organizational, NOT an oversize signal, no
|
||||
re-derivation.
|
||||
|
||||
### Breadth probe nodes (P2, [org-internal #2905] 方案 2)
|
||||
### Breadth probe nodes (P2, [TT-2905] 方案 2)
|
||||
|
||||
When a 待确认 category is cheapest to resolve empirically, a **probe node**
|
||||
is a legal task node at the granularity floor:
|
||||
@@ -306,12 +306,12 @@ is a legal task node at the granularity floor:
|
||||
冻结副本(新增需求必然改变节点集合或 `req_refs`;需要新节点时全额按
|
||||
node_split 建单传播)。
|
||||
|
||||
### Data layer — read `dag.route.preflight` BEFORE decomposition ([org-internal #2905] 方案 3)
|
||||
### Data layer — read `dag.route.preflight` BEFORE decomposition ([TT-2905] 方案 3)
|
||||
|
||||
Before starting decomposition, analyze-dag MUST read
|
||||
`<instance-root>/workflow-routing.yaml` `dag.route.preflight` and, when the list is
|
||||
non-empty, verify each item as a producer self-check (the same injection
|
||||
contract `implement` applies for `routes.{Kind}.preflight`, [org-internal #2599] — landed
|
||||
contract `implement` applies for `routes.{Kind}.preflight`, [TT-2599] — landed
|
||||
items carry their retro evidence in `evidence`):
|
||||
|
||||
1. Read the `dag:` block's `route.preflight` array (live yaml, repo root).
|
||||
@@ -407,7 +407,7 @@ external contract). This is what lets the REQMAP "需求覆盖" (requirement
|
||||
coverage) check mechanically verify that external-integration requirements map
|
||||
to nodes. (The `ARCH 1.1` system-context diagram is discarded only for
|
||||
process-infrastructure-type Epics; product Epics get this alternative rule
|
||||
instead.) [org-internal #2905]: this rule is the 外部系统集成 category of the breadth
|
||||
instead.) [TT-2905]: this rule is the 外部系统集成 category of the breadth
|
||||
coverage matrix held at its original strength — see Breadth Coverage above.
|
||||
|
||||
## Exec-Resource Configuration (spec-07 §4 — mechanical destination of folded checklist rows)
|
||||
@@ -433,7 +433,7 @@ observe:
|
||||
`> DAG 工件状态: draft`.
|
||||
2. After the single-gate (`review-dag`) PASS, the **aggregator agent** (main
|
||||
session / Orchestrator — not analyze-dag) asks the freeze confirmation
|
||||
question ([org-internal #3379]), then on confirmation flips the page to
|
||||
question ([TT-3379]), then on confirmation flips the page to
|
||||
`> DAG 工件状态: frozen` and stamps version `v1`. The confirmation is an
|
||||
OPTIONIZED `question` call (stage `review-dag`, never `destructive` —
|
||||
freeze is a process gate, not a business decision): options
|
||||
@@ -454,7 +454,7 @@ observe:
|
||||
the version stamp `vN → vN+1` (no re-confirmation — only the initial
|
||||
freeze gates on a decision).
|
||||
|
||||
## Backfill Input Mode (Kind/MVP graduation & big-bug relabels, [org-internal #3061])
|
||||
## Backfill Input Mode (Kind/MVP graduation & big-bug relabels, [TT-3061])
|
||||
|
||||
When a `Kind/MVP` ticket graduates (relabel → `Kind/Feature` → Step 0 → this
|
||||
skill), the DAG is derived from **what was actually built**, not from greenfield
|
||||
@@ -500,4 +500,4 @@ decomposition:
|
||||
- `dag-pipeline/spec-06` — dag_metrics derivation + thresholds
|
||||
- `dag-pipeline/spec-07` — dag.route landing row (entry skill, skip set, single-gate) + §4 landing list
|
||||
- `dag-pipeline/spec-08` — DAG artifact lifecycle / version stamp
|
||||
- `<instance-root>/archive/skills/roadmap/SKILL.md` — legacy route (archived 2026-08-21, [org-internal #3072] phase 3; this skill replaces it for all Epics)
|
||||
- `<instance-root>/archive/skills/roadmap/SKILL.md` — legacy route (archived 2026-08-21, [TT-3072] phase 3; this skill replaces it for all Epics)
|
||||
|
||||
@@ -185,7 +185,7 @@ When a `verify` work item has an E2E or UI DoD entry:
|
||||
## Session cleanup (mandatory)
|
||||
|
||||
A Playwright MCP browser is a real Chrome with a `/tmp` user-data-dir — its
|
||||
mode follows `mcp.playwright.headless` (`headless-field-v1`, [org-internal #4393]): the repo
|
||||
mode follows `mcp.playwright.headless` (`headless-field-v1`, [TT-4393]): the repo
|
||||
default `auto` spawns headed on desktop (win32/darwin; linux only with
|
||||
DISPLAY/WAYLAND_DISPLAY set) and headless otherwise; an explicit `true`/`false`
|
||||
or `OCTOPUS_MCP_HEADLESS=1|0` pins it. The mode is fixed per new session —
|
||||
@@ -194,7 +194,7 @@ stays alive as long as its MCP server runs, and the MCP server stays alive as
|
||||
long as its parent octopus backend runs. When a browser-debug session ends
|
||||
without an explicit `browser_close`, OR the octopus session times out mid-task,
|
||||
the Chrome + its MCP server are orphaned and accumulate across sessions —
|
||||
burning CPU and leaving dead profile dirs (issue [org-internal #1315]); in headed mode the
|
||||
burning CPU and leaving dead profile dirs (issue [TT-1315]); in headed mode the
|
||||
orphan is a visible stray window.
|
||||
|
||||
**Iron rule: every browser-debug session MUST close its browser before ending.**
|
||||
|
||||
@@ -171,7 +171,7 @@ Disable the watcher on slow filesystems (WSL2 `/mnt` drives, network mounts):
|
||||
codegraph serve --mcp --no-watch
|
||||
```
|
||||
|
||||
### Workflow worktrees get their own index ([org-internal #2561] / TD-006)
|
||||
### Workflow worktrees get their own index ([TT-2561] / TD-006)
|
||||
|
||||
The main checkout's `.codegraph/` does NOT cover git worktrees — they live
|
||||
outside the repo path, so nearest-`.codegraph/` resolution finds nothing under
|
||||
|
||||
@@ -315,7 +315,7 @@ Present the report to the user. Route to code review if > 20 lines or ≥ 3 file
|
||||
- `core/checklists/frontend.md` — Frontend self-check checklist
|
||||
- `core/skills/implement/SKILL.md` — General + pipeline implementation workflow
|
||||
- `core/skills/review-code/SKILL.md` — Code review (next step)
|
||||
- `<instance-root>/archive/skills/design/SKILL.md` — Design document production (legacy upstream, archived [org-internal #3072] phase 3)
|
||||
- `<instance-root>/archive/skills/design/SKILL.md` — Design document production (legacy upstream, archived [TT-3072] phase 3)
|
||||
- `core/skills/browser-debug/SKILL.md` — Interactive browser verification (invoke during Phase 3 / 4 for visual + interaction evidence)
|
||||
- `core/rules/testing.md`, `core/rules/type-checking.md` — Repository conventions (test commands, typecheck)
|
||||
- `core/rules/code-graph.md` — Code graph first
|
||||
|
||||
@@ -158,9 +158,9 @@ history. If a token leaks into a remote URL, rewrite the remote
|
||||
|
||||
**Create a release** — `POST .../releases {"tag_name":"v1.2.0","target":"main",...}`
|
||||
|
||||
**Create a wiki page** — `POST .../wiki/new {"title":"My Page","content_base64":"<b64>","message":"add page"}`. **`content_base64` is the ONLY field that writes body text** — this fork **silently ignores** the upstream-style `content` field on wiki create/update (no error, `201` returned, page saved 0 bytes; evidence [org-internal #3944]: commits f5eaf18/4f0217d/bad5880). `content` is valid only on the file API, never on wiki.
|
||||
**Create a wiki page** — `POST .../wiki/new {"title":"My Page","content_base64":"<b64>","message":"add page"}`. **`content_base64` is the ONLY field that writes body text** — this fork **silently ignores** the upstream-style `content` field on wiki create/update (no error, `201` returned, page saved 0 bytes; evidence [TT-3944]: commits f5eaf18/4f0217d/bad5880). `content` is valid only on the file API, never on wiki.
|
||||
|
||||
**Read / edit / delete a wiki page** — `GET|PATCH|DELETE .../wiki/page/{pageName}`. **Read by the mangled name, not the logical title**: this fork rewrites stored filenames for titles containing `/`, spaces, or `:` (slash percent-encoded into the filename + a `.-` suffix — see [org-internal #3218]), so `GET /wiki/page/bugfix-3204/bugfix-report` 404s. Always `GET .../wiki/pages` first and use the returned `sub_url` **verbatim** (it already carries the `%2F` encoding and `.-` suffix). PATCH/DELETE take the same mangled `pageName`. For PATCH, **omit `title` to keep the page name** and send only `content_base64`+`message` (fixed in gitea `dev-421-g7ff56aec08`, [org-internal #3510] — before that a title-less PATCH silently renamed the page to `unnamed.md` and later edits deleted target pages). Same trap as create: a PATCH carrying `content` instead of `content_base64` returns `200` with a **0-byte page** ([org-internal #3944]) — always base64-encode the body and verify non-empty via a follow-up `GET`.
|
||||
**Read / edit / delete a wiki page** — `GET|PATCH|DELETE .../wiki/page/{pageName}`. **Read by the mangled name, not the logical title**: this fork rewrites stored filenames for titles containing `/`, spaces, or `:` (slash percent-encoded into the filename + a `.-` suffix — see [TT-3218]), so `GET /wiki/page/bugfix-3204/bugfix-report` 404s. Always `GET .../wiki/pages` first and use the returned `sub_url` **verbatim** (it already carries the `%2F` encoding and `.-` suffix). PATCH/DELETE take the same mangled `pageName`. For PATCH, **omit `title` to keep the page name** and send only `content_base64`+`message` (fixed in gitea `dev-421-g7ff56aec08`, [TT-3510] — before that a title-less PATCH silently renamed the page to `unnamed.md` and later edits deleted target pages). Same trap as create: a PATCH carrying `content` instead of `content_base64` returns `200` with a **0-byte page** ([TT-3944]) — always base64-encode the body and verify non-empty via a follow-up `GET`.
|
||||
|
||||
## This fork's specifics
|
||||
|
||||
@@ -171,7 +171,7 @@ history. If a token leaks into a remote URL, rewrite the remote
|
||||
GET/PATCH/DELETE, `pages`, `revisions/{pageName}`). This fork has **no**
|
||||
upstream `raw/{pageName}` or `pages/{pageName}` single-page endpoints, and
|
||||
`page/{pageName}` only matches the mangled filename (see the wiki recipe
|
||||
above and [org-internal #3218]) — clone the wiki git repo (default branch `main`) only if
|
||||
above and [TT-3218]) — clone the wiki git repo (default branch `main`) only if
|
||||
you need history beyond `/wiki/revisions` or bulk filename surgery.
|
||||
- The authoritative route table is `routers/api/v1/api.go` in the Gitea
|
||||
source; the human-readable docs UI is `<BASE>/api/swagger`.
|
||||
|
||||
@@ -33,7 +33,7 @@ triggers:
|
||||
- launch session for issue
|
||||
- launch session for ticket
|
||||
- spawn session for ticket
|
||||
# English — patrol mode (delayed self-wake polling loops, [org-internal #3937]).
|
||||
# English — patrol mode (delayed self-wake polling loops, [TT-3937]).
|
||||
- patrol loop
|
||||
- patrol mode
|
||||
- delayed wake
|
||||
@@ -42,28 +42,28 @@ triggers:
|
||||
- 拉起会话
|
||||
- 自治会话
|
||||
- 无头会话
|
||||
# Chinese — patrol mode ([org-internal #3937]).
|
||||
# Chinese — patrol mode ([TT-3937]).
|
||||
- 巡检模式
|
||||
- 延迟唤醒
|
||||
- 会话不生成
|
||||
- 会话卡死
|
||||
- 为工单拉起会话
|
||||
- 工单拉起会话
|
||||
# English — lifecycle (hung rescue, stale-worldview correction, [org-internal #2459]).
|
||||
# English — lifecycle (hung rescue, stale-worldview correction, [TT-2459]).
|
||||
- abort session
|
||||
- revive session
|
||||
- session rescue
|
||||
- fact baseline
|
||||
# English — quota-wall recovery ([org-internal #3669]): worker killed by provider usage limit.
|
||||
# English — quota-wall recovery ([TT-3669]): worker killed by provider usage limit.
|
||||
- quota wall
|
||||
- usage limit reached
|
||||
- quota exhausted
|
||||
- switch provider
|
||||
# Chinese — lifecycle ops ([org-internal #2459]).
|
||||
# Chinese — lifecycle ops ([TT-2459]).
|
||||
- 唤醒会话
|
||||
- 会话挂死
|
||||
- 事实基线
|
||||
# Chinese — quota-wall recovery ([org-internal #3669]).
|
||||
# Chinese — quota-wall recovery ([TT-3669]).
|
||||
- 配额墙
|
||||
- 配额耗尽
|
||||
- 用量上限
|
||||
@@ -89,7 +89,7 @@ and worktree discipline are **orthogonal**: this skill only opens a session
|
||||
record pointed at a directory; whether the launched session later creates its
|
||||
own worktree is a _workflow_ decision (per the worktree-discipline rule) it
|
||||
makes when it starts actual work — not something the launcher does. One
|
||||
exception: the **ticket-driven recipe** below, where claim-first ([org-internal #2297])
|
||||
exception: the **ticket-driven recipe** below, where claim-first ([TT-2297])
|
||||
requires the launcher to push the workflow branch before launch, making a
|
||||
pre-built worktree the claim carrier + ready workspace (see Pitfall #10
|
||||
carve-out). So, unless a different repo / path is specifically targeted,
|
||||
@@ -122,7 +122,7 @@ carve-out). So, unless a different repo / path is specifically targeted,
|
||||
seed prompt, not the directory field (sidebar visibility, see bullet 1). The
|
||||
owner-check (`GET /session?directory=$DIR`) is scoped per directory, so
|
||||
rooting the session at the correct code checkout is also what makes the
|
||||
duplicate-session guard meaningful. Server-side backstop ([org-internal #3190]): creating a
|
||||
duplicate-session guard meaningful. Server-side backstop ([TT-3190]): creating a
|
||||
session whose directory IS a linked git worktree answers with an
|
||||
`X-Session-Directory-Warning` response header and a server warn log naming
|
||||
the owning main repo — if you see that header, the session will be invisible
|
||||
@@ -131,8 +131,8 @@ carve-out). So, unless a different repo / path is specifically targeted,
|
||||
|
||||
> **Authoritative reference:** `rules/headless-session-ops` wiki page
|
||||
> (<<instance-base-url>/Octopus/octopus/wiki/rules%2Fheadless-session-ops>).
|
||||
> This skill is its runtime carrier. Provenance: issue **[org-internal #1695]** (which
|
||||
> corrected the misdiagnosed [org-internal #1691], see comment 9205). Code citations below were
|
||||
> This skill is its runtime carrier. Provenance: issue **[TT-1695]** (which
|
||||
> corrected the misdiagnosed [TT-1691], see comment 9205). Code citations below were
|
||||
> verified against `<harness-package>` at HEAD.
|
||||
|
||||
## The `model` field — always provide a known-good model (read this first)
|
||||
@@ -166,7 +166,7 @@ section). Two reasons:
|
||||
`handlers/session.ts`) and never reaches the HTTP
|
||||
caller — so the session looks healthy (HTTP 204, user message persisted) yet
|
||||
**never generates**. This is exactly the "silent stall" observed empirically
|
||||
in [org-internal #1695]: a session with a 1-message transcript (user only) and frozen
|
||||
in [TT-1695]: a session with a 1-message transcript (user only) and frozen
|
||||
`time.updated`.
|
||||
|
||||
| payload | result |
|
||||
@@ -280,10 +280,10 @@ curl -s -X POST "$BASE/session/$SID/prompt_async?directory=$DIR" \
|
||||
queued behind a session that is generating with no live runner in this
|
||||
process (wedge/zombie shape — stored and re-driven on restart drain or the
|
||||
next runner), **202** when `delay_sec` defers delivery to an in-memory
|
||||
delayed wake ([org-internal #3937] A — see "巡检模式 / Patrol mode" below), and **409**
|
||||
delayed wake ([TT-3937] A — see "巡检模式 / Patrol mode" below), and **409**
|
||||
when the session is paused (message NOT stored) or the maintenance-mode
|
||||
hold queue is full.
|
||||
- **Global route alternative ([org-internal #4307]):** when the client only knows the
|
||||
- **Global route alternative ([TT-4307]):** when the client only knows the
|
||||
sessionID (no `?directory=` routing), `POST /prompt_async` (no path prefix)
|
||||
resolves the instance from the app database by the body's `sessionID` and
|
||||
delegates to the same delivery core — same 204/202/409 semantics, same
|
||||
@@ -294,17 +294,17 @@ curl -s -X POST "$BASE/session/$SID/prompt_async?directory=$DIR" \
|
||||
- `delay_sec` (optional, integer 0..86400, else 400) schedules the prompt for
|
||||
a one-shot delayed self-wake: the server holds the prompt in memory and
|
||||
fires it exactly once after `delay_sec` seconds, only for an idle session
|
||||
at intake. **Precedence ([org-internal #3937] review):** `delay_sec` applies only when the
|
||||
at intake. **Precedence ([TT-3937] review):** `delay_sec` applies only when the
|
||||
intake would otherwise start processing now (immediate class). For the
|
||||
queued-behind-wedge 202 member and under maintenance queue mode it is
|
||||
stripped — retention semantics win (the server logs the drop; the delay is
|
||||
NOT honored). Pending wakes are **in-memory only — a server restart abandons
|
||||
them**; a patrol loop must therefore tolerate a missed wake and re-arm.
|
||||
Never use `sleep <big>; curl ...` in a bash tool call to wait — that blocks
|
||||
the turn with zero output (the [org-internal #3937] incident shape); the bash tool now
|
||||
warns on bare sleeps > 120s (long-sleep guard, [org-internal #3937] C).
|
||||
the turn with zero output (the [TT-3937] incident shape); the bash tool now
|
||||
warns on bare sleeps > 120s (long-sleep guard, [TT-3937] C).
|
||||
- `model` is `{ providerID, modelID }` or the shorthand string
|
||||
`"providerID/modelID"` (split on the FIRST `/`; accepted since [org-internal #4307] —
|
||||
`"providerID/modelID"` (split on the FIRST `/`; accepted since [TT-4307] —
|
||||
e.g. `"zai-coding-plan/glm-5.2"`). **Do not omit it.** Fill the values from
|
||||
your own session's model (see "Reuse the current session's model" above) —
|
||||
never hardcode a specific model. A string without a `/` is rejected with
|
||||
@@ -335,7 +335,7 @@ curl -s "$BASE/session/$SID/message?directory=$DIR&limit=1" \
|
||||
Verdict: `latest_role == "assistant"` → the first generation completed (the
|
||||
seed is `user`; the newest message flips to `assistant` only once the model
|
||||
answered — an errored turn also persists an assistant message carrying the ⚠️
|
||||
usage-limit part, [org-internal #2912], so check the tail text before declaring success).
|
||||
usage-limit part, [TT-2912], so check the tail text before declaring success).
|
||||
Stays `user` across 2–3 polls spaced 10–30 s → **apparent silent stall**;
|
||||
almost certainly the model did not resolve to a usable one (fallback landed
|
||||
badly, or you omitted `model`). Redeliver Step 2 with an explicit known-good
|
||||
@@ -351,33 +351,33 @@ just never omit `limit`.
|
||||
|
||||
The common case: an agent (or cron/CI) spins up a fresh main session to work a
|
||||
tracked issue — seed prompt composed **from the issue body**, launched on the
|
||||
current session's model. **Step-0 owner check is MANDATORY ([org-internal #1803])**: four data
|
||||
current session's model. **Step-0 owner check is MANDATORY ([TT-1803])**: four data
|
||||
sources (session-title scan, assignee/claim, open PRs, remote branches); any
|
||||
live claim → ABORT the launch (`session-scope-guard.md` points here for that
|
||||
pre-step). Full recipe — owner-check scan script with `X-Total-Count` /
|
||||
`X-Has-More` pagination handling ([org-internal #3190]), claim-first atomic 3-step ([org-internal #2297],
|
||||
+ one-command provisioning via `script/claim-provision.sh`, [org-internal #3642]),
|
||||
seed-prompt MUSTs, backend duplicate-ticket hard guard ([org-internal #1989], on by default
|
||||
[org-internal #2350]), launch + poll commands: `reference/ticket-recipe.md` (read BEFORE
|
||||
`X-Has-More` pagination handling ([TT-3190]), claim-first atomic 3-step ([TT-2297],
|
||||
+ one-command provisioning via `script/claim-provision.sh`, [TT-3642]),
|
||||
seed-prompt MUSTs, backend duplicate-ticket hard guard ([TT-1989], on by default
|
||||
[TT-2350]), launch + poll commands: `reference/ticket-recipe.md` (read BEFORE
|
||||
creating any ticket-driven session).
|
||||
|
||||
## Completion-report protocol (完成回报协议, [org-internal #2374])
|
||||
## Completion-report protocol (完成回报协议, [TT-2374])
|
||||
|
||||
`prompt_async` is fire-and-forget **for the launcher too**: without this
|
||||
protocol the orchestrator has NO push channel and must poll forever ([org-internal #2366]).
|
||||
protocol the orchestrator has NO push channel and must poll forever ([TT-2366]).
|
||||
The worker actively reports `status=done|blocked|handoff` back into the
|
||||
orchestrator's session via `prompt_async`, with an issue-comment fallback.
|
||||
Default report format is `branch=<ref>`-based — workers never open PRs
|
||||
(TD-678/[org-internal #4425]); `pr=#N` appears only on `uncoordinated` self-opens.
|
||||
(TD-678/[TT-4425]); `pr=#N` appears only on `uncoordinated` self-opens.
|
||||
Hard constraints: a headless worker MUST NOT call the `question` tool
|
||||
([org-internal #2378] — directional/irreversible decisions are `status=blocked` reports,
|
||||
([TT-2378] — directional/irreversible decisions are `status=blocked` reports,
|
||||
then STOP), and MUST NOT self-merge its PR / self-close the issue / touch
|
||||
`main` ([org-internal #2386] — keep the PR open; the orchestrator merges and closes). Full
|
||||
`main` ([TT-2386] — keep the PR open; the orchestrator merges and closes). Full
|
||||
protocol — orchestrator-side seed block (verbatim template), worker-side
|
||||
steps, decision-authority layering: `reference/completion-report.md` (read
|
||||
BEFORE composing a seed prompt for any worker you need to hear back from).
|
||||
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([org-internal #2459])
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([TT-2459])
|
||||
|
||||
Launching is half the job — a headless worker can hang silently or wake with
|
||||
a stale worldview. Health check = two polls 30–60 s apart (`.state` + `progress`
|
||||
@@ -386,19 +386,19 @@ samples = hung → abort FIRST (`POST /session/:id/abort`), then re-wake with a
|
||||
known-good model + the anti-re-hang clause. Stale worldview → fact-baseline
|
||||
injection (only the CURRENT authority injects; if YOU might be the stale one,
|
||||
verify identity against the durable record first). Full runbooks — verdict
|
||||
table + [org-internal #3215] dual-sample rule, abort + re-wake sequence, fact-baseline
|
||||
table + [TT-3215] dual-sample rule, abort + re-wake sequence, fact-baseline
|
||||
structure, authorization asymmetry: `reference/lifecycle-ops.md` (read when
|
||||
managing a launched session). Quota wall — the worker's turn killed by a
|
||||
terminal usage-limit error (looks like silent completion: no report, ticket
|
||||
stalled) — has its own runbook: detection signals (finish=error ⚠️ tail,
|
||||
provider quota markers), provider-switch re-wake, fact-baseline template,
|
||||
pre-dispatch provider check: `reference/quota-wall-recovery.md` ([org-internal #3669], evidence
|
||||
[org-internal #3627]; read when a worker goes silent mid-task).
|
||||
pre-dispatch provider check: `reference/quota-wall-recovery.md` ([TT-3669], evidence
|
||||
[TT-3627]; read when a worker goes silent mid-task).
|
||||
|
||||
## 巡检模式 / Patrol mode (delayed self-wake, [org-internal #3937])
|
||||
## 巡检模式 / Patrol mode (delayed self-wake, [TT-3937])
|
||||
|
||||
A patrol loop periodically nudges a headless session without holding a
|
||||
connection or burning a turn on a blocking sleep. Since [org-internal #3937] A the server
|
||||
connection or burning a turn on a blocking sleep. Since [TT-3937] A the server
|
||||
supports this natively via `delay_sec` on `prompt_async`.
|
||||
|
||||
```sh
|
||||
@@ -427,16 +427,16 @@ Rules of the road:
|
||||
- **Restart abandons pending wakes.** They are in-memory server fibers — no
|
||||
persistence, no drain. After any server restart the patrol driver owns
|
||||
re-arming the next wake; treat a missed wake as expected, not as an error.
|
||||
- **Latest wake wins, per session ([org-internal #4069]).** Arming `delay_sec` on a session
|
||||
- **Latest wake wins, per session ([TT-4069]).** Arming `delay_sec` on a session
|
||||
that already has a pending wake SUPERSEDES it: the previous countdown is
|
||||
cancelled, only the latest wake fires. Re-arming each turn is the intended
|
||||
patrol pattern — a superseded wake never delivers its prompt and publishes
|
||||
no error. (Pre-[org-internal #4069] stacks both FIFO — on old binaries, re-arm only after
|
||||
no error. (Pre-[TT-4069] stacks both FIFO — on old binaries, re-arm only after
|
||||
the previous wake fired.)
|
||||
- **Never emulate a delay with the bash tool.** `sleep 900; curl ...` blocks
|
||||
the turn with zero output and gets manually aborted as a hang (the [org-internal #3937]
|
||||
the turn with zero output and gets manually aborted as a hang (the [TT-3937]
|
||||
incident). The bash tool now prepends a `<shell_warning>` on bare sleeps
|
||||
beyond 120s ([org-internal #3937] C) — treat that warning as a redirect to this section.
|
||||
beyond 120s ([TT-3937] C) — treat that warning as a redirect to this section.
|
||||
|
||||
## Do NOT use this skill when
|
||||
|
||||
@@ -461,15 +461,15 @@ Rules of the road:
|
||||
| 6 | Using synchronous `prompt` for headless launch | `prompt` blocks until done — wrong for fire-and-forget; use `prompt_async` |
|
||||
| 7 | Shell-escaping errors in a multi-line seed prompt | Build the payload with `jq -n --rawfile` from a file |
|
||||
| 8 | Verifying models via `GET /model` — no such endpoint (404) | Use `GET /provider` → `.connected` (provider live check); `list-models` tool also works. `GET /config/providers` lists _configured_ models only |
|
||||
| 9 | Launching a session for a ticket another live session already owns → conflicting diffs, duplicate work ([org-internal #1744]/[org-internal #1753]) | Run the Step-0 owner check (`GET /session` title scan + worktree/branch/PR scan); ABORT and report on conflict |
|
||||
| 10 | Creating a worktree / fresh checkout for the new session (unnecessary `bun install` + `.codegraph/` rebuild cost) | Don't — for _general_ launches: a session is a conversation pointed at a directory, so reuse the current workspace; worktree creation is a separate _workflow_ decision the launched session makes if/when it starts a workflow. **Ticket-recipe carve-out ([org-internal #2297]):** the ticket's work happens in a dedicated worktree anyway (worktree discipline), and claim-first pushes the workflow branch before launch — so the launcher pre-builds the worktree as the claim carrier + ready workspace, and the session reuses it (cost is front-loaded, not wasted). The worktree path goes in the claim comment + seed prompt; `?directory=` stays on the creator's workspace |
|
||||
| 11 | Launching a worker and never hearing back — orchestrator polls a few times, stops, loses visibility ([org-internal #2374]) | Append the completion-report block to the seed prompt (Completion-report protocol section): worker `prompt_async`s a one-line status back into the orchestrator session on done/blocked/handoff, with issue-comment fallback |
|
||||
| 12 | Headless worker calls the `question` tool → no attached client: the question deadlocks in a queue, or `auto_approve` silently auto-approves a direction-setting decision ([org-internal #2378]) | NEVER call `question` from a headless worker. Decision boundary (Completion-report protocol section): directional/irreversible decision → `status=blocked` report + one-line decision point, then STOP; the orchestrator is the sole human-decision entry point |
|
||||
| 13 | Headless worker self-merges its PR / self-closes the issue once the PR looks ready, despite a seed instruction to keep it open ([org-internal #2386]; N-02 [org-internal #2367] / N-03 [org-internal #2368], commits `d1565c99` / `040f21b7`) | Self-merge / self-close / touching `main` are irreversible directional actions → blocked by the Decision boundary. PR ready → keep it OPEN, report `status=done branch=<ref>`; the orchestrator opens/admits the PR, merges and closes uniformly |
|
||||
| 9 | Launching a session for a ticket another live session already owns → conflicting diffs, duplicate work ([TT-1744]/[TT-1753]) | Run the Step-0 owner check (`GET /session` title scan + worktree/branch/PR scan); ABORT and report on conflict |
|
||||
| 10 | Creating a worktree / fresh checkout for the new session (unnecessary `bun install` + `.codegraph/` rebuild cost) | Don't — for _general_ launches: a session is a conversation pointed at a directory, so reuse the current workspace; worktree creation is a separate _workflow_ decision the launched session makes if/when it starts a workflow. **Ticket-recipe carve-out ([TT-2297]):** the ticket's work happens in a dedicated worktree anyway (worktree discipline), and claim-first pushes the workflow branch before launch — so the launcher pre-builds the worktree as the claim carrier + ready workspace, and the session reuses it (cost is front-loaded, not wasted). The worktree path goes in the claim comment + seed prompt; `?directory=` stays on the creator's workspace |
|
||||
| 11 | Launching a worker and never hearing back — orchestrator polls a few times, stops, loses visibility ([TT-2374]) | Append the completion-report block to the seed prompt (Completion-report protocol section): worker `prompt_async`s a one-line status back into the orchestrator session on done/blocked/handoff, with issue-comment fallback |
|
||||
| 12 | Headless worker calls the `question` tool → no attached client: the question deadlocks in a queue, or `auto_approve` silently auto-approves a direction-setting decision ([TT-2378]) | NEVER call `question` from a headless worker. Decision boundary (Completion-report protocol section): directional/irreversible decision → `status=blocked` report + one-line decision point, then STOP; the orchestrator is the sole human-decision entry point |
|
||||
| 13 | Headless worker self-merges its PR / self-closes the issue once the PR looks ready, despite a seed instruction to keep it open ([TT-2386]; N-02 [TT-2367] / N-03 [TT-2368], commits `d1565c99` / `040f21b7`) | Self-merge / self-close / touching `main` are irreversible directional actions → blocked by the Decision boundary. PR ready → keep it OPEN, report `status=done branch=<ref>`; the orchestrator opens/admits the PR, merges and closes uniformly |
|
||||
| 14 | Trusting `state=generating` as "alive" — a hung stream goes unrescued (session A, 2026-08-16: `generating` 6+ min, count frozen at 478) | Poll state AND message count twice 30–60 s apart; frozen count = hung → abort + re-wake (Post-launch lifecycle section) |
|
||||
| 15 | Re-sending a wake prompt to a hung session and waiting — queued prompts are never consumed while the stream is dead | Abort FIRST (`POST /session/:id/abort` → 200, verify `idle`), THEN re-send; a prompt queued before the abort may still never fire — always re-deliver |
|
||||
| 16 | A worker woken from restart / long idle acts on its stale worldview — re-dispatches superseded work or claims authority it no longer holds (2026-08-16: revived worker re-ran an already-published FAIL verify; ops session announced an inherited "orchestrator" takeover) | Fact-baseline injection (Post-launch lifecycle section): authoritative facts + invalidated assumptions + one concrete re-assignment. Only the CURRENT authority injects; a session that suspects IT is stale verifies identity against the durable record first (`rules/compact.md` identity clause) |
|
||||
| 17 | Worker goes silent mid-task: provider quota wall killed the turn (usage limit / 429) — no completion-report, no blocked report; from the issue side indistinguishable from silent completion (2026-08-29 [org-internal #3627]: opencode-go `weekly usage limit reached` after the 13:18 Round-1 FAIL; ticket stalled until manually re-woken) | Detect via tail probe (`finish=error` + ⚠️ usage-limit part, `metadata.reason` in the quota family) + `GET /provider` quota markers; re-wake on a known-good provider with the fact-baseline template — `reference/quota-wall-recovery.md` ([org-internal #3669]). Prevent: pre-dispatch provider check + the seed's 配额自报 clause (`reference/completion-report.md`, [org-internal #3669]) — quota exhaustion is a `status=blocked reason=quota-exhausted` report, not a silent death |
|
||||
| 17 | Worker goes silent mid-task: provider quota wall killed the turn (usage limit / 429) — no completion-report, no blocked report; from the issue side indistinguishable from silent completion (2026-08-29 [TT-3627]: opencode-go `weekly usage limit reached` after the 13:18 Round-1 FAIL; ticket stalled until manually re-woken) | Detect via tail probe (`finish=error` + ⚠️ usage-limit part, `metadata.reason` in the quota family) + `GET /provider` quota markers; re-wake on a known-good provider with the fact-baseline template — `reference/quota-wall-recovery.md` ([TT-3669]). Prevent: pre-dispatch provider check + the seed's 配额自报 clause (`reference/completion-report.md`, [TT-3669]) — quota exhaustion is a `status=blocked reason=quota-exhausted` report, not a silent death |
|
||||
|
||||
## Known limitation (separate from this workaround)
|
||||
|
||||
@@ -482,9 +482,9 @@ catches that cause (`forkPromptDelivery` in `handlers/session.ts`) so the HTTP
|
||||
caller never sees it. The proper fix is to surface the error (or reject unusable
|
||||
models at the boundary) so a stalled session is diagnosable. Until then, **always
|
||||
provide an explicit known-good `model`** — this skill is the documented
|
||||
workaround (see [org-internal #1695] "遗留 minor").
|
||||
workaround (see [TT-1695] "遗留 minor").
|
||||
|
||||
**Update ([org-internal #2912], 2026-08-20)**: usage-limit turn failures (HTTP 429 /
|
||||
**Update ([TT-2912], 2026-08-20)**: usage-limit turn failures (HTTP 429 /
|
||||
FreeUsageLimitError / GoUsageLimitError) are no longer silent shells. When such
|
||||
a turn terminates (retry schedule ends or the spin is aborted), the errored
|
||||
assistant message persists `finish=error` plus a human-readable ⚠️ text part
|
||||
@@ -494,23 +494,23 @@ the web UI like any assistant text. Pitfall #14's double-poll is still the
|
||||
liveness check while a 429 retry spin is IN progress (the spin itself retries
|
||||
with backoff until interrupted); the explicit error part only appears once the
|
||||
turn ends. The general async-path observability gap above remains tracked by
|
||||
[org-internal #1695].
|
||||
[TT-1695].
|
||||
|
||||
## See also
|
||||
|
||||
- Source issue / full manual: **[org-internal #1695]** (this skill adds the ticket-driven recipe
|
||||
- Source issue / full manual: **[TT-1695]** (this skill adds the ticket-driven recipe
|
||||
- current-model reuse, and corrects the endpoint/claim against current code).
|
||||
- Completion-report protocol: **[org-internal #2374]** (worker-side active report back to the
|
||||
- Completion-report protocol: **[TT-2374]** (worker-side active report back to the
|
||||
launching orchestrator session; fallback to issue comment).
|
||||
- Quota-wall recovery recipe: **[org-internal #3669]** (evidence instance [org-internal #3627]) — detect a
|
||||
- Quota-wall recovery recipe: **[TT-3669]** (evidence instance [TT-3627]) — detect a
|
||||
worker killed by a provider usage limit, re-wake on a known-good provider,
|
||||
pre-dispatch prevention.
|
||||
- Decision boundary: **[org-internal #2378]** (headless worker MUST NOT call `question`;
|
||||
- Decision boundary: **[TT-2378]** (headless worker MUST NOT call `question`;
|
||||
directional decisions go through `status=blocked` reports to the
|
||||
orchestrator) and **[org-internal #2386]** (the worker MUST NOT self-merge its PR,
|
||||
orchestrator) and **[TT-2386]** (the worker MUST NOT self-merge its PR,
|
||||
self-close the issue, or touch `main` — the orchestrator merges and closes
|
||||
uniformly).
|
||||
- Correction of the prior misdiagnosis: **[org-internal #1691]** (closed Invalid), comment 9205.
|
||||
- Correction of the prior misdiagnosis: **[TT-1691]** (closed Invalid), comment 9205.
|
||||
- Synchronous client always sends `model`:
|
||||
`packages/app/src/components/prompt-input/submit.ts:158-165`.
|
||||
- Code citations: `<harness-package>/src/session/prompt.ts:858,804-822,1399`,
|
||||
@@ -525,15 +525,15 @@ turn ends. The general async-path observability gap above remains tracked by
|
||||
specific ticket (#N)`): read BEFORE creating any session for issue #N —
|
||||
Step-0 owner check, seed-prompt composition, launch + poll commands.
|
||||
- `reference/completion-report.md` — completion-report protocol (完成回报协议,
|
||||
[org-internal #2374]): read BEFORE composing a seed prompt for a worker you need to hear
|
||||
[TT-2374]): read BEFORE composing a seed prompt for a worker you need to hear
|
||||
back from — orchestrator block template, worker-side report steps, decision
|
||||
boundary ([org-internal #2378] / [org-internal #2386]), quota self-report clause ([org-internal #3669]).
|
||||
- `reference/lifecycle-ops.md` — post-launch lifecycle ([org-internal #2459]): read when
|
||||
boundary ([TT-2378] / [TT-2386]), quota self-report clause ([TT-3669]).
|
||||
- `reference/lifecycle-ops.md` — post-launch lifecycle ([TT-2459]): read when
|
||||
managing a launched session — health-check polling, hung-stream diagnosis
|
||||
(state=generating + frozen counters), abort + re-wake rescue,
|
||||
fact-baseline injection, authorization asymmetry.
|
||||
- `reference/quota-wall-recovery.md` — quota-wall recovery ([org-internal #3669], evidence
|
||||
[org-internal #3627]): read when a worker goes silent mid-task (suspected provider usage
|
||||
- `reference/quota-wall-recovery.md` — quota-wall recovery ([TT-3669], evidence
|
||||
[TT-3627]): read when a worker goes silent mid-task (suspected provider usage
|
||||
limit) or BEFORE dispatching a long-running worker — detection signals
|
||||
(finish=error ⚠️ tail, provider quota markers, log grep patterns),
|
||||
provider-switch re-wake + fact-baseline template, pre-dispatch provider
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
> Extracted from headless-session-ops/SKILL.md (Completion-report protocol (完成回报协议, [org-internal #2374])) — moved verbatim 2026-08-26, ticket [org-internal #3480].
|
||||
> Extracted from headless-session-ops/SKILL.md (Completion-report protocol (完成回报协议, [TT-2374])) — moved verbatim 2026-08-26, ticket [TT-3480].
|
||||
|
||||
## Completion-report protocol (完成回报协议, [org-internal #2374])
|
||||
## Completion-report protocol (完成回报协议, [TT-2374])
|
||||
|
||||
`prompt_async` is fire-and-forget **for the launcher too**: once the worker
|
||||
session starts generating, the orchestrator receives NO event when it finishes
|
||||
@@ -8,8 +8,8 @@ or blocks. The `task` tool auto-returns `task_result` for subagents; a
|
||||
`prompt_async`-launched independent main session has no equivalent — the
|
||||
orchestrator's only built-in channel is bare polling of
|
||||
`GET /session/:id/message?limit=1` (tail probe — the no-`limit` form loads the
|
||||
whole transcript server-side), which it eventually stops doing ([org-internal #2366]: worker ran
|
||||
~1h past the orchestrator's last poll, merged PR [org-internal #2371] and closed [org-internal #2366] while
|
||||
whole transcript server-side), which it eventually stops doing ([TT-2366]: worker ran
|
||||
~1h past the orchestrator's last poll, merged PR [TT-2371] and closed [TT-2366] while
|
||||
the orchestrator had zero visibility).
|
||||
|
||||
The protocol below closes that gap WITHOUT changing server semantics: the
|
||||
@@ -24,21 +24,21 @@ parallel chunk work, any long-running delegated ticket), append a
|
||||
completion-report block to the seed prompt. It MUST state:
|
||||
|
||||
- the orchestrator's **session id** (`$LAUNCHER_SID`) and **directory**;
|
||||
- the report endpoint: `POST $BASE/session/$LAUNCHER_SID/prompt_async?directory=$DIR` (or, when the directory is unknown to the worker, the global route `POST $BASE/prompt_async` with the sessionID in the body — [org-internal #4307]);
|
||||
- the report endpoint: `POST $BASE/session/$LAUNCHER_SID/prompt_async?directory=$DIR` (or, when the directory is unknown to the worker, the global route `POST $BASE/prompt_async` with the sessionID in the body — [TT-4307]);
|
||||
- the exact report format (one-line, machine-greppable);
|
||||
- the fallback (issue comment) if the report call fails.
|
||||
|
||||
Template (include verbatim in `seed.txt` when you are the launcher):
|
||||
|
||||
```text
|
||||
## 完成回报协议 (mandatory, [org-internal #2374])
|
||||
## 完成回报协议 (mandatory, [TT-2374])
|
||||
|
||||
你由编排会话 (orchestrator) 启动。完成、阻塞、或将工单移交他人时,必须向编排会话回报:
|
||||
POST <BASE>/session/<LAUNCHER_SID>/prompt_async?directory=<DIR>
|
||||
body: {"agent":"builder","model":{...},"parts":[{"type":"text","text":"<report>"}]}
|
||||
<report> 格式(单行,machine-greppable):
|
||||
[#<ticket>] [<node-or-slug>] status=done|blocked|handoff branch=<ref> [pr=#<N>] verify=<changed+typecheck> risk=<high|low> summary=<one line>
|
||||
默认(TD-678 / [org-internal #4425]):worker 只推分支不开 PR——交付推送前置本地验证
|
||||
默认(TD-678 / [TT-4425]):worker 只推分支不开 PR——交付推送前置本地验证
|
||||
(<harness-package> 下 test:changed 全绿 + typecheck 0 error,verify 字段回执);
|
||||
risk 按 risk-classifier 冻结表(HIGH_RISK_GLOBS)自报。PR 由编排按容量串行开
|
||||
1:1(正文携 worker 报告),或 batch 模式 epic 经 land-batch 技能按迭代统一合成
|
||||
@@ -46,15 +46,15 @@ risk 按 risk-classifier 冻结表(HIGH_RISK_GLOBS)自报。PR 由编排按
|
||||
若回报调用失败(HTTP 非 2xx / 连接拒绝 — orchestrator 会话可能已结束或实例重启),
|
||||
退而在源 issue(或父 Epic)发同内容评论作为兜底(fallback, 非主通道)。
|
||||
回报是你的 mandatory step,与 issue-checklist-sync 并列;不得静默结束。
|
||||
决策边界([org-internal #2378]):headless worker 禁止调用 `question` 工具 —— 遇方向性/不可逆
|
||||
决策边界([TT-2378]):headless worker 禁止调用 `question` 工具 —— 遇方向性/不可逆
|
||||
决策点 → `status=blocked` + 一行决策点描述后 STOP,勿调 question(无人应答死锁 /
|
||||
被 auto_approve 静默自动批准)。
|
||||
配额自报([org-internal #3669]):若收到配额/用量上限错误(usage limit / 429 / 402
|
||||
配额自报([TT-3669]):若收到配额/用量上限错误(usage limit / 429 / 402
|
||||
insufficient_quota),立即回报 status=blocked reason=quota-exhausted
|
||||
summary=<provider 与 ⚠️ 部分中的重置提示>(branch=<ref> 必带)后停止
|
||||
——勿自行换模型重试;换供应商重唤醒由编排者执行
|
||||
(reference/quota-wall-recovery.md)。
|
||||
PR 就绪后保持 open:不自行合并 PR、不关闭 issue、不动 main([org-internal #2386]);
|
||||
PR 就绪后保持 open:不自行合并 PR、不关闭 issue、不动 main([TT-2386]);
|
||||
合并与 issue 关闭由编排者统一执行。
|
||||
```
|
||||
|
||||
@@ -73,7 +73,7 @@ final step (before idling):
|
||||
done); `pr=#N` only for an `uncoordinated` self-open; use
|
||||
`status=blocked` + the blocker description when stuck; use
|
||||
`status=handoff` when deliberately transferring the ticket.
|
||||
1. **Quota exhaustion is a blocked report, not a silent death ([org-internal #3669]).** A
|
||||
1. **Quota exhaustion is a blocked report, not a silent death ([TT-3669]).** A
|
||||
worker whose turn is killed by a usage-limit error (429 / 402 quota
|
||||
family) cannot finish the turn — but per the seed's 配额自报 clause it
|
||||
reports `status=blocked reason=quota-exhausted summary=<provider +
|
||||
@@ -93,7 +93,7 @@ final step (before idling):
|
||||
remains the stakeholder-facing record; the report is the
|
||||
orchestrator-facing wake-up signal.
|
||||
|
||||
### Orchestrator side — serial PR admission on done reports ([org-internal #4425])
|
||||
### Orchestrator side — serial PR admission on done reports ([TT-4425])
|
||||
|
||||
On a `status=done branch=<ref> verify=… risk=…` report:
|
||||
|
||||
@@ -103,16 +103,16 @@ On a `status=done branch=<ref> verify=… risk=…` report:
|
||||
code; keep the queue shallow.
|
||||
2. Open the 1:1 PR (title from the ticket node, body carrying the worker
|
||||
report: branch / files / self-test / verify), apply the `Risk/*` label
|
||||
from the report's `risk=` hint, merge via `script/pr-merge.sh` ([org-internal #3864]).
|
||||
Batch-mode epics: one `land-batch` PR per iteration instead ([org-internal #3731]).
|
||||
from the report's `risk=` hint, merge via `script/pr-merge.sh` ([TT-3864]).
|
||||
Batch-mode epics: one `land-batch` PR per iteration instead ([TT-3731]).
|
||||
3. A first red on the opened PR goes back through the report fallback
|
||||
channel (issue comment) — the worker may already be idle; the issue
|
||||
comment is the durable re-entry point.
|
||||
|
||||
Prose discipline on the orchestrator session only — no new daemon, no
|
||||
mergeable-state automation (merge-coordinator retired, [org-internal #4385]).
|
||||
mergeable-state automation (merge-coordinator retired, [TT-4385]).
|
||||
|
||||
### Decision boundary (决策边界, [org-internal #2378])
|
||||
### Decision boundary (决策边界, [TT-2378])
|
||||
|
||||
The report channel defines how the worker *answers*; this subsection defines
|
||||
the boundary of what it may *ask*. A headless worker session has NO attached
|
||||
@@ -134,15 +134,15 @@ authority is layered instead:
|
||||
point, then STOPs. The orchestrator is the sole human-decision entry point:
|
||||
it interacts with the user, then replies to the worker (or acts on its
|
||||
behalf).
|
||||
- **No self-merge / no self-close / never touch main ([org-internal #2386])**: a headless
|
||||
- **No self-merge / no self-close / never touch main ([TT-2386])**: a headless
|
||||
worker MUST NOT merge its own PR, close the source issue, or rebase /
|
||||
force-push `main`. These are irreversible directional actions of exactly
|
||||
the class this boundary blocks — even when the seed prompt's instruction
|
||||
to "keep the PR open" is absent or the worker judges the PR ready. When
|
||||
the PR is ready the worker keeps it OPEN and reports
|
||||
`status=done pr=#N` to the orchestrator; the orchestrator performs the
|
||||
merge and the issue close uniformly. (Counter-example: N-02 [org-internal #2367] /
|
||||
N-03 [org-internal #2368] self-merged their PRs — commits `d1565c99` / `040f21b7` —
|
||||
merge and the issue close uniformly. (Counter-example: N-02 [TT-2367] /
|
||||
N-03 [TT-2368] self-merged their PRs — commits `d1565c99` / `040f21b7` —
|
||||
despite a seed instruction to keep them open.)
|
||||
- **Local implementation decisions within the AC scope** (pattern choice,
|
||||
helper extraction, test shape) → the worker decides autonomously and notes
|
||||
@@ -150,7 +150,7 @@ authority is layered instead:
|
||||
|
||||
Rule of thumb: the worker's only way to "ask" is a `status=blocked` report.
|
||||
A genuine ambiguity left by the seed prompt that would change scope is a
|
||||
blocked report, NOT a `question` call. (Field sample: N-04 [org-internal #2369] — the
|
||||
blocked report, NOT a `question` call. (Field sample: N-04 [TT-2369] — the
|
||||
worker spontaneously did NOT merge its own PR and left merging to the
|
||||
orchestrator; this subsection codifies that behavior.)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
> Extracted from headless-session-ops/SKILL.md (Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([org-internal #2459])) — moved verbatim 2026-08-26, ticket [org-internal #3480].
|
||||
> Extracted from headless-session-ops/SKILL.md (Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([TT-2459])) — moved verbatim 2026-08-26, ticket [TT-3480].
|
||||
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([org-internal #2459])
|
||||
## Post-launch lifecycle: health check, hung rescue, stale-worldview correction ([TT-2459])
|
||||
|
||||
Launching is half the job — a headless worker can hang silently or wake up
|
||||
with an outdated worldview. All three failure modes below were observed in
|
||||
production on 2026-08-16 during Epic [org-internal #2459] (ops-restart window); the runbooks
|
||||
production on 2026-08-16 during Epic [TT-2459] (ops-restart window); the runbooks
|
||||
are extracted from that incident record.
|
||||
|
||||
### Health check — three states, one poll pattern
|
||||
@@ -24,7 +24,7 @@ server-side:
|
||||
| idle | `state=idle` AND `progress` absent-or-stale across both polls | turn ended — read the LAST message (same `limit=1` fetch): task unfinished → wake prompt; `status=done` report → harvest |
|
||||
| **hung** | `state=generating` AND `progress.stepCount`/`lastStepAt` AND newest message id ALL frozen across both polls | the generation stream is dead; queued prompts will NEVER be consumed — rescue required |
|
||||
|
||||
`state` alone lies in BOTH directions ([org-internal #3215]): a hung session still reports
|
||||
`state` alone lies in BOTH directions ([TT-3215]): a hung session still reports
|
||||
`generating` (field sample: session A, 2026-08-16 — `state=generating` for 6+
|
||||
minutes with the message count frozen at 478), and a healthy mid-step worker
|
||||
can read `idle`/empty message tails in a single snapshot (2026-08-23 W3 wave:
|
||||
@@ -32,7 +32,7 @@ can read `idle`/empty message tails in a single snapshot (2026-08-23 W3 wave:
|
||||
discriminator; a single snapshot is NEVER an abort basis.**
|
||||
|
||||
`progress` (`stepCount` cumulative LLM-round counter, `lastStepAt` epoch-ms
|
||||
heartbeat — [org-internal #3215]) moves on every round even when message tails are
|
||||
heartbeat — [TT-3215]) moves on every round even when message tails are
|
||||
transiently empty or `state` flickers; it is absent for sessions that never
|
||||
ran since instance start (treat absent = no signal, fall back to count
|
||||
deltas). `lastStepAt` freshness alone does NOT prove liveness (a long tool
|
||||
@@ -77,7 +77,7 @@ claim authority it does not hold (field samples, 2026-08-16: a revived worker
|
||||
re-ran an M-01 verify another session had already published as FAIL —
|
||||
deduplicated via flag #comment-21590; an ops-notification session inherited an
|
||||
"orchestrator" identity from a compaction summary and announced a takeover —
|
||||
corrected via 勘误 #comment-21654/[org-internal #21668]).
|
||||
corrected via 勘误 #comment-21654/[TT-21668]).
|
||||
|
||||
When you detect a stale-worldview session, do not wait for it to finish being
|
||||
wrong — inject a fact-baseline prompt immediately (regular `prompt_async`),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
> Added from headless-session-ops/SKILL.md (triggers `quota wall` / `配额墙`,
|
||||
> Post-launch lifecycle section, pitfall #17, References) — new runbook
|
||||
> 2026-08-29, ticket [org-internal #3669] (evidence instance [org-internal #3627]). Companion runbooks:
|
||||
> 2026-08-29, ticket [TT-3669] (evidence instance [TT-3627]). Companion runbooks:
|
||||
> `lifecycle-ops.md` (hung rescue, fact-baseline structure) and
|
||||
> `completion-report.md` §"Orchestrator side" (the quota self-report clause);
|
||||
> §Prevention is this file's own closing section.
|
||||
@@ -14,15 +14,15 @@ it looks EXACTLY like silent completion: no completion-report, no
|
||||
equals the orchestrator's polling interval, and without this runbook the
|
||||
recovery was improvised.
|
||||
|
||||
**Evidence instance ([org-internal #3627], 2026-08-29)** — the shapes below are field-verified:
|
||||
**Evidence instance ([TT-3627], 2026-08-29)** — the shapes below are field-verified:
|
||||
|
||||
|时刻 (+08)| 事件 |
|
||||
|---|---|
|
||||
| 08-29 13:18 | review-code Round-1 synthesis (FAIL) posted on [org-internal #3627]; worker session `ses_fb46e705bffe9kYbSoHayoJ1OQ` (builder, opencode-go model, branch `workflow/session/3627-wedge-promptasync`) entered its revision loop |
|
||||
| 08-29 13:18 | review-code Round-1 synthesis (FAIL) posted on [TT-3627]; worker session `ses_fb46e705bffe9kYbSoHayoJ1OQ` (builder, opencode-go model, branch `workflow/session/3627-wedge-promptasync`) entered its revision loop |
|
||||
| ~13:18–16:00 | worker hit the provider's `weekly usage limit reached` mid-revision — turn killed, **no** completion-report, **no** blocked report; issue side silent |
|
||||
| detection | orchestrator noticed the `/session` state stall, then confirmed via the quota error in the session log (message tail carries the ⚠️ usage-limit part, [org-internal #2912]) |
|
||||
| detection | orchestrator noticed the `/session` state stall, then confirmed via the quota error in the session log (message tail carries the ⚠️ usage-limit part, [TT-2912]) |
|
||||
| recovery | re-wake via `prompt_async` on a known-good provider (`zhipuai-coding-plan`/glm-5.3 — since renamed `zai-coding-plan`) **plus a fact-baseline injection** (what happened / what is done / where to resume) |
|
||||
| 16:26 / 16:51 | Round-2 synthesis PASS; `status=done pr=[org-internal #3675]` report received |
|
||||
| 16:26 / 16:51 | Round-2 synthesis PASS; `status=done pr=[TT-3675]` report received |
|
||||
|
||||
## Detection — three signals, in this order
|
||||
|
||||
@@ -35,7 +35,7 @@ SID=<worker session id>
|
||||
```
|
||||
|
||||
**Signal 1 — tail probe (primary; survives restarts, lives in the DB).** Since
|
||||
[org-internal #2912]/[org-internal #3190] a quota-killed turn persists an assistant message with
|
||||
[TT-2912]/[TT-3190] a quota-killed turn persists an assistant message with
|
||||
`finish=error` plus a human-readable ⚠️ text part whose metadata names the
|
||||
quota family. Probe the TAIL (`limit=1`, never the no-`limit` full transcript):
|
||||
|
||||
@@ -52,10 +52,10 @@ rate_limit}` (metadata also carries `provider`). The ⚠️ text is one of — a
|
||||
strings observed in this repo's runtime (`session/retry.ts`):
|
||||
|
||||
- `` `weekly usage limit` reached. It will reset in … `` / `Go limit reached`
|
||||
(GoUsageLimitError — the [org-internal #3627] shape; `weekly` is the body's `limitName`)
|
||||
(GoUsageLimitError — the [TT-3627] shape; `weekly` is the body's `limitName`)
|
||||
- `Free limit reached` (FreeUsageLimitError)
|
||||
- `Account-level usage limit — switching API keys does not reset it. You can
|
||||
continue after HH:mm.` ([org-internal #3407], zhipu/zai code 1308 — account-level)
|
||||
continue after HH:mm.` ([TT-3407], zhipu/zai code 1308 — account-level)
|
||||
- `Provider <id> rate limited (HTTP 429)` (generic 429)
|
||||
- `Generation failed — …` with a 402 `insufficient_quota` body (balance, not
|
||||
window — recovery is top-up, not provider switch)
|
||||
@@ -73,9 +73,9 @@ curl -s "$BASE/session?directory=$DIR" | jq -r --arg s "$SID" \
|
||||
30–60 s apart → the 429 retry spin is still running (it retries with backoff
|
||||
until the schedule ends) OR the stream is hung — treat exactly like the hung
|
||||
shape in `lifecycle-ops.md`: abort FIRST, then re-wake. A single snapshot is
|
||||
never an abort basis ([org-internal #3215]).
|
||||
never an abort basis ([TT-3215]).
|
||||
|
||||
**Signal 3 — provider-level confirmation ([org-internal #2911] quota markers).** `GET
|
||||
**Signal 3 — provider-level confirmation ([TT-2911] quota markers).** `GET
|
||||
/provider` overlays active usage-limit cooldowns, so the dead provider is
|
||||
visible without reading logs:
|
||||
|
||||
@@ -86,7 +86,7 @@ date -d @$(($(curl -s "$BASE/provider?directory=$DIR" | jq '[.all[].quota.resetA
|
||||
```
|
||||
|
||||
**Log grep (fallback; the dev log is restart-truncated).** Patterns actually
|
||||
seen in the wild — [org-internal #3627] produced the first:
|
||||
seen in the wild — [TT-3627] produced the first:
|
||||
|
||||
```sh
|
||||
grep -E "usage limit reached|Go limit reached|Free limit reached|Account-level usage limit|GoUsageLimitError|FreeUsageLimitError|rate limited \(HTTP 429\)|insufficient_quota" \
|
||||
@@ -96,7 +96,7 @@ grep -E "usage limit reached|Go limit reached|Free limit reached|Account-level u
|
||||
```
|
||||
|
||||
The wall is only terminal after failover has exhausted the same-name pools
|
||||
([org-internal #2911] failover); the `retrying … on …` WARNs above tell you the pool was
|
||||
([TT-2911] failover); the `retrying … on …` WARNs above tell you the pool was
|
||||
already draining before it died.
|
||||
|
||||
## Recovery — abort (only if needed), re-wake on a known-good provider, inject facts
|
||||
@@ -130,7 +130,7 @@ curl -s "$BASE/provider?directory=$DIR" | jq -r \
|
||||
# own current model — it is generating by definition).
|
||||
```
|
||||
|
||||
([org-internal #3627]: opencode-go dead → re-woken on zhipuai-coding-plan/glm-5.3, since
|
||||
([TT-3627]: opencode-go dead → re-woken on zhipuai-coding-plan/glm-5.3, since
|
||||
renamed `zai-coding-plan`. Do NOT "wait for reset" as the default — weekly
|
||||
windows mean days.)
|
||||
|
||||
@@ -159,9 +159,9 @@ curl -s "$BASE/provider?directory=$DIR" | jq -r \
|
||||
**Step 3 — re-wake with a fact-baseline prompt.** Build the payload from a file
|
||||
(`jq --rawfile`, SKILL.md pitfall #7), same wake shape as
|
||||
`lifecycle-ops.md` but with the quota facts. The template also restates the
|
||||
completion-report protocol ([org-internal #2374]) so the recovery is self-contained: it
|
||||
completion-report protocol ([TT-2374]) so the recovery is self-contained: it
|
||||
assumes the original seed still contains the protocol block — if you are
|
||||
unsure it does (e.g. the worker was dispatched before [org-internal #3669] added the quota
|
||||
unsure it does (e.g. the worker was dispatched before [TT-3669] added the quota
|
||||
clause), the template's own block below carries it; fill
|
||||
`<BASE>`/`<LAUNCHER_SID>`/`<DIR>` with the orchestrator session's values:
|
||||
|
||||
@@ -176,7 +176,7 @@ cat > wake.txt <<'EOF'
|
||||
3. 从哪继续:<一件具体的下一步任务>。
|
||||
4. 证据规则:逐条到引用来源(issue 评论 / PR / 工件)核实后再行动,
|
||||
勿仅凭本基线行动。
|
||||
## 完成回报协议(重申 [org-internal #2374]/[org-internal #3669];不确定原始 seed 是否含协议块时以本节为准)
|
||||
## 完成回报协议(重申 [TT-2374]/[TT-3669];不确定原始 seed 是否含协议块时以本节为准)
|
||||
完成、阻塞或移交时,必须回报编排会话(你的唤醒者):
|
||||
POST <BASE>/session/<LAUNCHER_SID>/prompt_async?directory=<DIR>
|
||||
body: {"agent":"builder","model":{...},"parts":[{"type":"text","text":"<report>"}]}
|
||||
@@ -195,7 +195,7 @@ jq -n --rawfile p wake.txt '{agent:"builder",
|
||||
Then poll the tail (`limit=1`) until an assistant message appears, and keep
|
||||
expecting the completion-report per protocol — the re-woken worker owes you
|
||||
`status=done|blocked` like any other (the restated block in the template
|
||||
makes this hold even when the original seed predates [org-internal #3669]).
|
||||
makes this hold even when the original seed predates [TT-3669]).
|
||||
|
||||
## Prevention — before dispatch, and in the seed
|
||||
|
||||
@@ -213,7 +213,7 @@ If the intended provider is already quota-marked, dispatch on a different one
|
||||
|
||||
**Quota self-report clause (turns a silent death into a harvestable
|
||||
blocked).** The canonical clause text lives in `completion-report.md`
|
||||
§"Orchestrator side" (配额自报, [org-internal #3669]) — append it VERBATIM to the seed
|
||||
§"Orchestrator side" (配额自报, [TT-3669]) — append it VERBATIM to the seed
|
||||
prompt's completion-report block. Single source of truth: do not fork or
|
||||
restate the clause here; its blocked payload already follows the one-line
|
||||
key=value spec (`status=blocked reason=quota-exhausted summary=<provider +
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from headless-session-ops/SKILL.md (Launch a session for a specific ticket (#N)) — moved verbatim 2026-08-26, ticket [org-internal #3480].
|
||||
> Extracted from headless-session-ops/SKILL.md (Launch a session for a specific ticket (#N)) — moved verbatim 2026-08-26, ticket [TT-3480].
|
||||
|
||||
## Launch a session for a specific ticket (#N)
|
||||
|
||||
@@ -7,13 +7,13 @@ work a tracked issue. Compose the seed prompt **from the issue itself** so the
|
||||
new session starts with real context, and launch it on **the current session's
|
||||
model**.
|
||||
|
||||
0. **Owner check (MANDATORY pre-step, [org-internal #1803]).** Before creating anything,
|
||||
0. **Owner check (MANDATORY pre-step, [TT-1803]).** Before creating anything,
|
||||
verify no other live session already owns this ticket or code area —
|
||||
duplicate ownership is how [org-internal #1744]/[org-internal #1753] collided. The check spans four
|
||||
duplicate ownership is how [TT-1744]/[TT-1753] collided. The check spans four
|
||||
data sources; any live claim → **ABORT the launch and report the
|
||||
conflict**.
|
||||
|
||||
**Mechanized ([org-internal #3667])**: `bash script/session-conflicts.sh <N>` runs the
|
||||
**Mechanized ([TT-3667])**: `bash script/session-conflicts.sh <N>` runs the
|
||||
session-title scan (a), the branch scan (d), and the open-PR check (c)
|
||||
in one read-only pass (exit 4 = conflict, `--json` for a machine
|
||||
summary); the assignee/claim check (b) is `claim.sh`'s compare-and-swap
|
||||
@@ -23,7 +23,7 @@ model**.
|
||||
**a. Session-title scan (live session check).** The listing endpoint
|
||||
returns at most `limit` (default 100) sessions — on busy repos (300+ live
|
||||
sessions in one directory) that silently truncates and the scan misses
|
||||
owners ([org-internal #3190]). Non-range listing responses carry `X-Total-Count` (full
|
||||
owners ([TT-3190]). Non-range listing responses carry `X-Total-Count` (full
|
||||
filter population, untruncated) and `X-Has-More: true` (only when the
|
||||
page is truncated). Scan procedure: fetch page 1, and when
|
||||
`X-Has-More: true` is present re-fetch once with `limit=$TOTAL` — treat
|
||||
@@ -57,7 +57,7 @@ model**.
|
||||
the launch and report the conflict** (issue comment naming the owning
|
||||
session id). Do not launch a second session for the same ticket.
|
||||
|
||||
**b. Assignee / claim check ([org-internal #2297]).** Read the issue via
|
||||
**b. Assignee / claim check ([TT-2297]).** Read the issue via
|
||||
`工单 API(见 TERMINOLOGY)get(owner, repo, index: N)` (or `GET /api/v1/repos/$OWNER/$REPO/issues/$N`):
|
||||
- If `assignee` is set and is **not** the launching agent → **ABORT** and
|
||||
report (the ticket is already claimed).
|
||||
@@ -68,7 +68,7 @@ model**.
|
||||
`GET <gitea-base-url>/api/v1/repos/issues/search?q="#N"&type=pulls&state=open`
|
||||
(API source) — and **ABORT** if an open PR already covers the ticket.
|
||||
|
||||
**d. Remote branch check ([org-internal #2297]).** A local branch is invisible to other
|
||||
**d. Remote branch check ([TT-2297]).** A local branch is invisible to other
|
||||
sessions — check the remote too:
|
||||
`git ls-remote origin 'workflow/*'` and scan for a branch tail covering `#N`.
|
||||
Also check the repo side locally: `git worktree list` +
|
||||
@@ -76,7 +76,7 @@ model**.
|
||||
|
||||
- A stale hit (session idle for hours / clearly abandoned) → do NOT
|
||||
hand-post a takeover comment (retired admin workaround — unauditable);
|
||||
dead-claim takeover is mechanized ([org-internal #3668]): `bash script/claim.sh
|
||||
dead-claim takeover is mechanized ([TT-3668]): `bash script/claim.sh
|
||||
takeover <ticket> <branch> --session-id <id>`. It enforces the
|
||||
evidence gate (branch ABSENT on origin AND (session 404 OR comment at
|
||||
least CLAIM_TAKEOVER_STALE_DAYS old)) and exits 10 when the evidence
|
||||
@@ -87,13 +87,13 @@ model**.
|
||||
§"Dead-claim takeover" (claim.sh header is normative).
|
||||
The runtime counterpart of this check is `core/rules/session-scope-guard.md`
|
||||
("One task, one owner"), injected into every session's prompt.
|
||||
- **Backend hard guard ([org-internal #1989]):** `POST /session` hard-rejects duplicate-ticket
|
||||
session creation with HTTP 400. The backend guard is **on by default ([org-internal #2350])**;
|
||||
- **Backend hard guard ([TT-1989]):** `POST /session` hard-rejects duplicate-ticket
|
||||
session creation with HTTP 400. The backend guard is **on by default ([TT-2350])**;
|
||||
set `enabled: false` in config to opt out. It fails open ONLY on defect
|
||||
paths (DB / config errors), never as a configured disable. The front-end
|
||||
soft check above is now backed by this backend hard check for defense in
|
||||
depth.
|
||||
- **Claim-first ([org-internal #2297]).** Claiming a ticket is one atomic 3-step action:
|
||||
- **Claim-first ([TT-2297]).** Claiming a ticket is one atomic 3-step action:
|
||||
(1) set the issue assignee to the working account, (2) post a claim comment
|
||||
naming the workflow branch and session id, (3) push the workflow branch to
|
||||
remote (`git push -u origin workflow/...`). The claim is valid ONLY when all
|
||||
@@ -101,7 +101,7 @@ model**.
|
||||
session until all three steps are done (see
|
||||
`core/rules/session-scope-guard.md` §"Claim-first"). If a collision HAS
|
||||
already happened, follow `rules/ownership-collision-runbook` (wiki, L2 on-demand).
|
||||
- **Provisioning after claim ([org-internal #3642]) is ONE command** — claim + worktree +
|
||||
- **Provisioning after claim ([TT-3642]) is ONE command** — claim + worktree +
|
||||
Tier-1 runs scaffold:
|
||||
`bash script/claim-provision.sh <N> workflow/<branch>` (runs claim.sh with
|
||||
exit codes passed through, attaches the session worktree to the claimed
|
||||
@@ -123,7 +123,7 @@ model**.
|
||||
- restate the **goal** in one sentence;
|
||||
- list the **constraints** and **acceptance criteria**;
|
||||
- cite every **wiki artifact path** / related issue referenced in the body
|
||||
(e.g. `{epic-slug}/dag`, `{epic-slug}/dag-nodes/{node-id}`, `[org-internal #1691]`);
|
||||
(e.g. `{epic-slug}/dag`, `{epic-slug}/dag-nodes/{node-id}`, `[TT-1691]`);
|
||||
- tell the new agent to follow the right pipeline skill for the work type
|
||||
(implement / bugfix / design / …).
|
||||
Write it to a file (handles newlines):
|
||||
@@ -141,16 +141,16 @@ your change — classify (pre-existing/flaky), file a BF/FT issue per
|
||||
core/rules/session-scope-guard.md, and continue this task. Do NOT fix
|
||||
unrelated failing tests in place.
|
||||
|
||||
## 完成回报协议 (mandatory, [org-internal #2374])
|
||||
## 完成回报协议 (mandatory, [TT-2374])
|
||||
|
||||
完成、阻塞、或移交时,向编排会话回报:
|
||||
POST <BASE>/session/<LAUNCHER_SID>/prompt_async?directory=<DIR>
|
||||
(编排目录未知时可用全局路由 POST <BASE>/prompt_async,body 携 sessionID,[org-internal #4307])
|
||||
(编排目录未知时可用全局路由 POST <BASE>/prompt_async,body 携 sessionID,[TT-4307])
|
||||
body: {"agent":"builder","model":{...},"parts":[{"type":"text","text":"<report>"}]}
|
||||
<report>: [#N] [<node-or-slug>] status=done|blocked|handoff branch=<ref> [pr=#<PR>] verify=<changed+typecheck> risk=<high|low> summary=<one line>
|
||||
约束:worker 只推分支不开 PR(PR 由编排串行开);交付推送前 test:changed+typecheck 须绿。若再遇配额/用量上限错误,立即回报 status=blocked reason=quota-exhausted summary=<provider 与重置提示>(branch=<ref> 必带)后停止,勿自行换模型重试。
|
||||
回报失败(非 2xx / 连接拒绝)→ 在本 issue(或父 Epic)发同内容评论兜底。
|
||||
决策边界([org-internal #2378]):遇方向性决策点 → status=blocked 回报,勿调 question。
|
||||
决策边界([TT-2378]):遇方向性决策点 → status=blocked 回报,勿调 question。
|
||||
EOF
|
||||
```
|
||||
|
||||
@@ -179,4 +179,4 @@ EOF
|
||||
|
||||
6. **Add the completion-report block to the seed prompt** (see next section) so
|
||||
the worker reports back when it finishes or blocks — without it, this
|
||||
orchestrator has no push channel and must poll forever ([org-internal #2374]).
|
||||
orchestrator has no push channel and must poll forever ([TT-2374]).
|
||||
|
||||
@@ -8,7 +8,7 @@ description: >
|
||||
self-checks against the relevant checklist before handing off to code
|
||||
review.
|
||||
# `stage` is intentionally omitted: `implement` is a production-phase name the
|
||||
# stage registry rules invalid post-[org-internal #3072] phase 3 (see
|
||||
# stage registry rules invalid post-[TT-3072] phase 3 (see
|
||||
# core/schemas/workflow-routing.schema.json stage enum — production-phase
|
||||
# names are "no longer valid anywhere"). The implement skill has no registry
|
||||
# gate id; the gates it feeds into are `review-code` and `verify`.
|
||||
@@ -77,7 +77,7 @@ In **pipeline mode** (work item from iteration plan), follow the standard precon
|
||||
|
||||
**On-demand references**: each mode's phase-by-phase detail (templates, prompts, orchestration flows, historical notes) lives in `reference/{mode}-mode.md`, NOT injected — read it at mode entry. Full read-timing table: References section.
|
||||
|
||||
> **Progressive disclosure ([org-internal #3734])**: when dispatching a Developer scoped to
|
||||
> **Progressive disclosure ([TT-3734])**: when dispatching a Developer scoped to
|
||||
> one mode, pass `skills: ["implement:mode-bugfix"]` (preamble + that
|
||||
> mode's workflow only) instead of the full body; pipeline-mode dispatches
|
||||
> should also carry `pipeline-detection`
|
||||
@@ -97,12 +97,12 @@ The Developer is responsible for:
|
||||
- Writing code that faithfully implements the design.
|
||||
- Running typecheck, lint, and tests to self-verify.
|
||||
- Self-checking against the relevant checklist before handoff.
|
||||
- Persisting the final report to disk before returning — worker-report persistence ([org-internal #2847], see `../_shared/worker-report-persistence.md`).
|
||||
- Persisting the final report to disk before returning — worker-report persistence ([TT-2847], see `../_shared/worker-report-persistence.md`).
|
||||
- Writing no more and no less than the work item scope — no opportunistic refactoring of unrelated code.
|
||||
|
||||
The Builder's role is to validate the implementation output and pass it to code review. The Builder MUST NOT write or revise implementation code.
|
||||
|
||||
### Pre-flight checklist injection ([org-internal #2599])
|
||||
### Pre-flight checklist injection ([TT-2599])
|
||||
|
||||
Before dispatching ANY Developer (or Tester) sub-agent — in every mode (implement / bugfix / refactor / port; pipeline or standalone) — the orchestrator resolves the ticket's route (the Process Assessment Gate Step 0 already resolves the Kind/* route) and reads `<instance-root>/workflow-routing.yaml` `routes.{Kind}.preflight`. When the list is non-empty, prepend it to the sub-agent's task prompt as:
|
||||
|
||||
@@ -162,7 +162,7 @@ Standard workflow for work items from an approved iteration plan. Full phase det
|
||||
>
|
||||
> At Phase 6 handoff, pass `mode: "dag-task"` to review-code (its DAG Task Mode keys off the same frozen-DAG-copy detection).
|
||||
|
||||
> **Legacy pipeline preconditions retired ([org-internal #3072] phase 3, 2026-08-21)**: tiered artifact-existence and review-convergence checks belonged to the archived legacy pipeline. Live input modes: DAG task mode (above) and standalone modes (the request itself is the spec). Historical tiered publish targets: `reference/implement-mode.md` § Legacy notes.
|
||||
> **Legacy pipeline preconditions retired ([TT-3072] phase 3, 2026-08-21)**: tiered artifact-existence and review-convergence checks belonged to the archived legacy pipeline. Live input modes: DAG task mode (above) and standalone modes (the request itself is the spec). Historical tiered publish targets: `reference/implement-mode.md` § Legacy notes.
|
||||
|
||||
Before starting implementation, confirm:
|
||||
|
||||
@@ -186,13 +186,13 @@ Every gate below is hard — agents rationalize skipping exactly these. Full det
|
||||
4. **Phase 4 — Self-Check** (all mandatory):
|
||||
1. `bun typecheck` (or project-equivalent) — zero errors.
|
||||
2. `bun oxlint --deny-warnings` (repo root — the review-code mechanical gate's canonical lint invocation; `bun lint` is the package-script alias) — zero errors.
|
||||
3. `bun run test:changed` (or project-equivalent; full suite `bun run test:parallel` is verify's job, not a per-revision gate, [org-internal #2598]) — all tests pass.
|
||||
3. `bun run test:changed` (or project-equivalent; full suite `bun run test:parallel` is verify's job, not a per-revision gate, [TT-2598]) — all tests pass.
|
||||
4. Post-deletion cleanup (when any code was removed): re-run lint + typecheck to catch orphaned imports/variables/type references.
|
||||
Then self-check `core/checklists/implementation.md`; every new function/method/exported API has ≥ 1 test; interface promises cross-checked against the node's edge contracts. **Review-readiness GATE**: self-attest `core/checklists/code-review.md` (COR, DGN, SEC, PERF, TST, STY, DBT, A11Y, DOC, TRC), record pass/fail per dimension in the Phase 5 report; handoff requires **0 BLOCKERs and 0 MAJORs** — if you can find a MAJOR, the formal review will too; fix it now.
|
||||
5. **Phase 4.5 — Iteration Completion Commit**: after ALL work items in the iteration pass Phase 4, commit with format `[{chunk-id}][{iteration}] {summary}`; commit body REQUIRED for non-trivial commits (> 1 file or > 20 LOC): What (files + purpose + the `WI-{NNN}` ID — code-review TRC 10.1), Why (design/REQ motivation), Evidence (test names / verification commands). Full rules: `reference/implement-mode.md` § Phase 4.5.
|
||||
6. **Phase 4.6 — Issue Checklist Sync (progressive)**: after committing, mark items this iteration delivered `- [x]` + `_(commit {sha}: file/component)_` per the `issue-checklist-sync` L1 rule; do NOT touch items outside this iteration's scope.
|
||||
7. **Phase 4.7 — PR-Creation Sync**: the session pushes its branch and reports `status=done branch=<ref> verify=… risk=…` — the orchestrator opens the PR (serially per TD-678/[org-internal #4425]) and applies the `Risk/*` label from the report's `risk=` hint, computed per the risk-classifier frozen table (`HIGH_RISK_GLOBS` in `.gitea/scripts/risk-classifier.ts`: core/migrations/deploy/`core/rules/**`/`.gitea/workflows/**` → `Risk/High`, else `Risk/Low`); `Risk/High` PRs merge manually by design. Once the PR exists, ensure `## 当前状态` exists (PR / 代码评审 / CI rows are written by the `status-sync` poller, NOT by hand); append the PR reference to the matching Epic task-list row. **Never hand-sync main into the PR branch** — that is the keep-mergeable workflow's job. Detail: `reference/implement-mode.md` § Phase 4.6 / § Phase 4.7.
|
||||
8. **Phase 5 — Report**: implementation report with AC → test traceability (template: `reference/implement-mode.md` § Phase 5). **Persist before returning ([org-internal #2847])** — the Developer's LAST action before returning the report: write it to `<runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md` (Tier 1 run workspace) else `/tmp/octopus/{chunk-id}-worker-{seq}.md` (`../_shared/worker-report-persistence.md`). The persisted copy is the report of record — applies to EVERY mode's report phase.
|
||||
7. **Phase 4.7 — PR-Creation Sync**: the session pushes its branch and reports `status=done branch=<ref> verify=… risk=…` — the orchestrator opens the PR (serially per TD-678/[TT-4425]) and applies the `Risk/*` label from the report's `risk=` hint, computed per the risk-classifier frozen table (`HIGH_RISK_GLOBS` in `.gitea/scripts/risk-classifier.ts`: core/migrations/deploy/`core/rules/**`/`.gitea/workflows/**` → `Risk/High`, else `Risk/Low`); `Risk/High` PRs merge manually by design. Once the PR exists, ensure `## 当前状态` exists (PR / 代码评审 / CI rows are written by the `status-sync` poller, NOT by hand); append the PR reference to the matching Epic task-list row. **Never hand-sync main into the PR branch** — that is the keep-mergeable workflow's job. Detail: `reference/implement-mode.md` § Phase 4.6 / § Phase 4.7.
|
||||
8. **Phase 5 — Report**: implementation report with AC → test traceability (template: `reference/implement-mode.md` § Phase 5). **Persist before returning ([TT-2847])** — the Developer's LAST action before returning the report: write it to `<runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md` (Tier 1 run workspace) else `/tmp/octopus/{chunk-id}-worker-{seq}.md` (`../_shared/worker-report-persistence.md`). The persisted copy is the report of record — applies to EVERY mode's report phase.
|
||||
9. **Phase 6 — Handoff to Code Review**: present the report; signal readiness via `signal_stage_done`. Do NOT mark the work item complete until code review passes.
|
||||
|
||||
#### Tester focus & Common Rationalizations
|
||||
@@ -216,7 +216,7 @@ The regression test MUST fail before the fix — the Tester dispatches between P
|
||||
2. **Phase 2 — Isolate Root Cause**: trace symptom → proximate cause → root cause (RCA template: `reference/bugfix-mode.md` § Phase 2); fixing a symptom → stop, go deeper; not found after 3 levels of indirection → pause and report, no surface-level patch. Then evaluate routing (below).
|
||||
3. **Phase 3 — Write a Regression Test**: exercise the exact bug path with the failing inputs; it MUST fail with the bug's symptom NOW, before the fix (already passing → the test does not cover the bug, rewrite it; no failing test possible → most targeted test, marked `[flaky]`).
|
||||
4. **Phase 4 — Fix**: minimum change resolving the root cause; one conceptual change per fix — no bundled refactoring, style changes, or "while I'm here" improvements (root cause in a different file → fix it there). Run the regression test (MUST pass) + relevant unit tests.
|
||||
5. **Phase 5 — Self-Check & Report**: `bun typecheck`; `bun oxlint --deny-warnings`; `bun run test:changed` (all pass; full suite belongs to verify); verify `core/checklists/bugfix.md`; publish the bugfix report as wiki page `{slug}/bugfix-report` (template: `reference/bugfix-mode.md` § Bugfix Report); persist per the Phase 5 persistence rule (Mode: implement, [org-internal #2847]).
|
||||
5. **Phase 5 — Self-Check & Report**: `bun typecheck`; `bun oxlint --deny-warnings`; `bun run test:changed` (all pass; full suite belongs to verify); verify `core/checklists/bugfix.md`; publish the bugfix report as wiki page `{slug}/bugfix-report` (template: `reference/bugfix-mode.md` § Bugfix Report); persist per the Phase 5 persistence rule (Mode: implement, [TT-2847]).
|
||||
6. **Phase 5.5 — Issue Checklist Sync (standalone bugfix)**: sync the source issue at each transition (commit / PR / review / CI / close) per the `issue-checklist-sync` L1 rule and its standalone-flow table.
|
||||
7. **Phase 6 — Approval**: present the report (prompt: `reference/bugfix-mode.md` § Phase 6 — Approval).
|
||||
|
||||
@@ -224,14 +224,14 @@ The regression test MUST fail before the fix — the Tester dispatches between P
|
||||
|
||||
Full escalate/stay criteria: `reference/bugfix-mode.md` § Routing Decision. In short — **escalate to pipeline** on ANY of: ≥ 5 files · ≥ 2 modules/components · design-level root cause · data migration / schema change · public-API / contract change · dependency change · > 50 lines · user requests full-process; **stay standalone** only when ALL the opposites hold. If uncertain, escalate — a false escalation costs review rounds; a false standalone decision skips quality gates.
|
||||
|
||||
**Big-bug relabel rule ([org-internal #3061])** — before the generic escalation above, split the triggers by kind:
|
||||
**Big-bug relabel rule ([TT-3061])** — before the generic escalation above, split the triggers by kind:
|
||||
|
||||
- **Design-level triggers** (root cause is a design decision — protocol / schema / architecture; shared-contract or public-API change; data migration): do NOT push through bugfix — **relabel the ticket `Kind/Feature`** and reroute via Step 0 (DAG route; 1–3 node small DAG expected); repro + root-cause notes become node input.
|
||||
- **Mechanical size triggers only** (many files / lines, same design): stay in bugfix — batch into iterations, keep review-code + verify. Scale alone never justifies a relabel.
|
||||
|
||||
#### Pipeline Mode (bugfix)
|
||||
|
||||
> **Legacy path retired ([org-internal #3072] phase 3)**: the requirements → design → review → plan front-end was archived; a big bug needing a design-level decision relabels `Kind/Feature` into the DAG route (big-bug relabel rule above).
|
||||
> **Legacy path retired ([TT-3072] phase 3)**: the requirements → design → review → plan front-end was archived; a big bug needing a design-level decision relabels `Kind/Feature` into the DAG route (big-bug relabel rule above).
|
||||
|
||||
When a bugfix escalates beyond standalone scope, the bug report becomes a pipeline input; the bugfix phases (reproduce, root cause, regression test, fix) are embedded within the implement stage, and review-code + verify remain mandatory. On the DAG route the node spec lives in `{epic-slug}/dag`; the Developer follows bugfix Phases 1–6 as the implementation method, then produces the standard implementation report (Mode: implement, Phase 5).
|
||||
|
||||
@@ -259,7 +259,7 @@ Restructure existing code without changing observable behavior — the existing
|
||||
1. **Phase 1 — Scope & Baseline**: map exact files + dependents; run `bun run test:parallel` (the refactor baseline legitimately needs the full suite) — ANY pre-existing failure → stop ("Cannot begin refactoring with failing tests. Fix them first."). Capture baseline: test count, coverage, optional complexity (template: `reference/refactor-mode.md` § Baseline).
|
||||
2. **Phase 2 — Define Target Pattern**: Extract / Inline / Rename / Move / Replace / Simplify / Upgrade, with one-sentence goal + success criteria (all tests pass unchanged; structural goal met; coverage does not decrease). Pipeline mode: align with the node spec + contracts, or justify in the report.
|
||||
3. **Phase 3 — Decompose into Steps**: smallest individually-verifiable steps (each reversible, suite-passing, ONE conceptual transformation); present the plan before executing (user may approve / reorder / reject). **If > 10 steps, the scope is too large — split into multiple sessions.**
|
||||
4. **Phase 4 — Incremental Execution**: per step — transform, run `bun run test:changed` (ALL pass; per-step scoped reruns — full suite is verify's job, [org-internal #2598]), commit `refactor: {what} from {where}`. **If FAIL: revert immediately** — do NOT fix the test or code within the same step; find a smaller decomposition (exception: fix a flaky test first as a prerequisite step, then retry).
|
||||
4. **Phase 4 — Incremental Execution**: per step — transform, run `bun run test:changed` (ALL pass; per-step scoped reruns — full suite is verify's job, [TT-2598]), commit `refactor: {what} from {where}`. **If FAIL: revert immediately** — do NOT fix the test or code within the same step; find a smaller decomposition (exception: fix a flaky test first as a prerequisite step, then retry).
|
||||
5. **Phase 5 — Final Validation**: `bun run test:parallel` all pass; `bun typecheck` zero errors; `bun oxlint --deny-warnings` zero errors; coverage MUST NOT decrease vs baseline (±1% noise).
|
||||
6. **Phase 6 — Report**: before/after metrics, steps executed, verification results, design deviations (template: `reference/refactor-mode.md` § Refactor Report).
|
||||
7. **Phase 7 — Approval**: present the report (prompt: `reference/refactor-mode.md` § Phase 7 — Approval). Route to code review if > 50 lines or ≥ 5 files.
|
||||
@@ -336,7 +336,7 @@ Not all work items involve writing new code — some are refactoring, bugfix, or
|
||||
- `core/skills/browser-debug/SKILL.md` — Interactive browser verification (for frontend work items) and UI bug reproduction (bugfix Phase 1)
|
||||
- `core/skills/review-code/SKILL.md` — Code review (next step after implementation)
|
||||
- `core/skills/verify/SKILL.md` — Integration + fidelity verification (pipeline-mode bugfix, large port)
|
||||
- `<instance-root>/archive/skills/` — Legacy requirements/design/plan/roadmap skills (archived [org-internal #3072] phase 3; their templates moved to `<instance-root>/archive/templates/`)
|
||||
- `<instance-root>/archive/skills/` — Legacy requirements/design/plan/roadmap skills (archived [TT-3072] phase 3; their templates moved to `<instance-root>/archive/templates/`)
|
||||
- `reference/source-analysis.md` — Port Phase A1, A1.5, A1.7, A1.8 detailed processes & templates
|
||||
- `reference/mapping-and-design.md` — Port Phase A2, A3, A4 detailed processes & templates
|
||||
- `reference/large-port-pipeline.md` — Port Phase B1–B4 detailed processes
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: bugfix) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: bugfix) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: bugfix
|
||||
|
||||
@@ -182,7 +182,7 @@ If the Developer is uncertain, escalate. A false pipeline escalation costs a few
|
||||
extra review rounds. A false standalone decision risks missing a quality gate on
|
||||
a complex change.
|
||||
|
||||
**Big-bug relabel rule ([org-internal #3061])** — before the generic escalation below, split
|
||||
**Big-bug relabel rule ([TT-3061])** — before the generic escalation below, split
|
||||
the triggers by kind:
|
||||
|
||||
- **Design-level triggers** (root cause is a design decision — protocol /
|
||||
@@ -449,7 +449,7 @@ resolves it by permitting triage but forbidding deferral.
|
||||
|
||||
#### Pipeline Mode (bugfix)
|
||||
|
||||
> **Legacy path retired ([org-internal #3072] phase 3, 2026-08-21)**: the full
|
||||
> **Legacy path retired ([TT-3072] phase 3, 2026-08-21)**: the full
|
||||
> requirements-elicitation → design → review-artifact(design-space) →
|
||||
> plan-iterations → review-artifact(plan) front-end was archived
|
||||
> (`<instance-root>/archive/skills/`). A big bug that needs a design-level decision
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: implement) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: implement) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: implement (default)
|
||||
|
||||
@@ -8,7 +8,7 @@ and self-verify before passing to code review.
|
||||
|
||||
#### Pre-flight
|
||||
|
||||
The pre-flight self-check prompt format ([org-internal #2599]), prepended to the Developer
|
||||
The pre-flight self-check prompt format ([TT-2599]), prepended to the Developer
|
||||
sub-agent's task prompt when `routes.{Kind}.preflight` is non-empty:
|
||||
|
||||
```
|
||||
@@ -75,7 +75,7 @@ Developer is structurally biased to miss.
|
||||
|
||||
#### Preconditions
|
||||
|
||||
> **Publish target (tiered targeting retired, [org-internal #3072] phase 3)**: the
|
||||
> **Publish target (tiered targeting retired, [TT-3072] phase 3)**: the
|
||||
> `Size/*`-tiered publish rule (`rules/workflow-routing.md` §"Publish target
|
||||
> by Size/* tier — RETIRED") was retired with the legacy producer skills.
|
||||
> Artifacts publish where the live mode puts them: DAG task mode → node spec
|
||||
@@ -125,7 +125,7 @@ Developer is structurally biased to miss.
|
||||
|
||||
Before starting implementation, confirm:
|
||||
|
||||
> **Legacy pipeline preconditions retired ([org-internal #3072] phase 3, 2026-08-21)**: the
|
||||
> **Legacy pipeline preconditions retired ([TT-3072] phase 3, 2026-08-21)**: the
|
||||
> tier-dependent requirements/design/plan artifact-existence checks and the
|
||||
> design-space / iteration-plan review-convergence checks that used to head
|
||||
> this list belonged to the archived legacy pipeline (`<instance-root>/archive/`).
|
||||
@@ -162,7 +162,7 @@ the work-item list from the frozen DAG copy: the ready/pending task nodes in
|
||||
`{epic-slug}/dag` (via `wiki 读写 API(见 TERMINOLOGY)`), cross-checked against the
|
||||
node tickets on the Epic's `## DAG 状态` table. (Legacy tier-based resolution
|
||||
via `{slug}/04-plan-04-iteration-assignment` was archived 2026-08-21,
|
||||
[org-internal #3072] phase 3.) Present the current ready nodes for selection:
|
||||
[TT-3072] phase 3.) Present the current ready nodes for selection:
|
||||
|
||||
```
|
||||
Current iteration: Iteration {N}: {Goal}
|
||||
@@ -346,7 +346,7 @@ a one-pass implementation into a multi-round review.
|
||||
| "Design is ambiguous here, I'll pick the obvious option" | Inventing a design decision is a Phase 2 abort condition. Flag the gap; do not guess. |
|
||||
| "Already manually verified it works" | Manual ≠ systematic — no record, can't re-run, can't bisect. `bun run test:changed` is the evidence the report demands. |
|
||||
| "Report is busywork, the diff speaks for itself" | No report → review-code cannot trace AC→test. Phase 5 is the handoff contract; skip it and the review stalls. |
|
||||
| "X× improvement — assumed, no measurement" | Quick-measure before it becomes an AC. Unverified assumptions in ACs waste framing cost ([org-internal #1932]: YAML token density assumed 2-3×, measured 0.95 — hypothesis rejected by data). |
|
||||
| "X× improvement — assumed, no measurement" | Quick-measure before it becomes an AC. Unverified assumptions in ACs waste framing cost ([TT-1932]: YAML token density assumed 2-3×, measured 0.95 — hypothesis rejected by data). |
|
||||
|
||||
---
|
||||
|
||||
@@ -463,14 +463,14 @@ waiting for the final verify gate.
|
||||
|
||||
The session pushes its branch and reports `status=done branch=<ref> verify=…
|
||||
risk=…`; the orchestrator admits the PR (serially, one open at a time) —
|
||||
workers never open PRs (TD-678/[org-internal #4425]; `uncoordinated` self-open only when
|
||||
workers never open PRs (TD-678/[TT-4425]; `uncoordinated` self-open only when
|
||||
the orchestrator is unreachable). Once that PR exists, update the source
|
||||
issue so stakeholders see the mergeable state without waiting for code
|
||||
review. Mandated by the `issue-checklist-sync` L1 rule; skip if no source
|
||||
issue exists.
|
||||
|
||||
> PR shape per mode: default = one 1:1 PR per task (body carries the worker
|
||||
> report); batch-mode epics ([org-internal #3731], per-epic opt-in) = the orchestrator
|
||||
> report); batch-mode epics ([TT-3731], per-epic opt-in) = the orchestrator
|
||||
> composes ONE batch PR per iteration via the `land-batch` skill. This phase
|
||||
> then runs per member issue as usual (N times), each pointing at its PR
|
||||
> (batch: the single batch PR); the poller writes the PR/CI/review rows
|
||||
@@ -549,7 +549,7 @@ Produce an implementation report:
|
||||
**Handoff**: Ready for `core/skills/review-code/SKILL.md`
|
||||
```
|
||||
|
||||
**Persist before returning ([org-internal #2847])**: the Developer MUST write the final
|
||||
**Persist before returning ([TT-2847])**: the Developer MUST write the final
|
||||
report above to disk as its LAST action, BEFORE returning it —
|
||||
`<runs-root>/{slug}/workers/{chunk-id}-worker-{seq}.md` when the Tier 1
|
||||
run workspace exists, else `/tmp/octopus/{chunk-id}-worker-{seq}.md`
|
||||
@@ -582,7 +582,7 @@ To notify workflow completion, call the `signal_stage_done` tool.
|
||||
|
||||
#### Legacy notes
|
||||
|
||||
> **Publish target (tiered targeting retired, [org-internal #3072] phase 3)**: the
|
||||
> **Publish target (tiered targeting retired, [TT-3072] phase 3)**: the
|
||||
> `Size/*`-tiered publish rule (`rules/workflow-routing.md` §"Publish target
|
||||
> by Size/* tier — RETIRED") was retired with the legacy producer skills.
|
||||
> Artifacts publish where the live mode puts them: DAG task mode → node spec
|
||||
|
||||
@@ -155,7 +155,7 @@ analysis:
|
||||
|
||||
## Phase B3 — Handoff to DAG Decomposition
|
||||
|
||||
> Legacy note ([org-internal #3072] phase 3, 2026-08-21): this handoff used to target the
|
||||
> Legacy note ([TT-3072] phase 3, 2026-08-21): this handoff used to target the
|
||||
> archived `roadmap` skill; it now targets `analyze-dag`.
|
||||
|
||||
Present the source analysis and request task-DAG decomposition:
|
||||
@@ -194,7 +194,7 @@ core/skills/implement/SKILL.md
|
||||
|
||||
(The legacy per-chunk `requirements-elicitation` → `design` →
|
||||
`review-artifact(design-space)` → `plan-iterations` → `review-artifact(plan)`
|
||||
front-end was archived 2026-08-21, [org-internal #3072] phase 3 — `<instance-root>/archive/`.)
|
||||
front-end was archived 2026-08-21, [TT-3072] phase 3 — `<instance-root>/archive/`.)
|
||||
|
||||
### implement
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: port) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: port) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: port
|
||||
|
||||
@@ -274,7 +274,7 @@ port (source analysis)
|
||||
→ verify (integration + fidelity)
|
||||
```
|
||||
|
||||
> Legacy diagram (archived [org-internal #3072] phase 3): the former per-chunk pipeline ran
|
||||
> Legacy diagram (archived [TT-3072] phase 3): the former per-chunk pipeline ran
|
||||
> requirements-elicitation → design → review (target: design-space) →
|
||||
> plan-iterations → review (target: plan) → implement → review-code. Those
|
||||
> skills/targets are archived (`<instance-root>/archive/`); the live path is the
|
||||
@@ -286,7 +286,7 @@ port (source analysis)
|
||||
| B1.5 | **GATE** — 10-dimensional peer review of source analysis | `reference/large-port-pipeline.md` |
|
||||
| B1.7+B1.8 | Target surface & capability boundary as formal artifacts for peer review | `reference/large-port-pipeline.md` |
|
||||
| B2 | Self-check source analysis against port checklist | `reference/large-port-pipeline.md` |
|
||||
| B3 | Handoff to analyze-dag — decompose by source module into DAG nodes (legacy: roadmap skill, archived [org-internal #3072] phase 3) | `reference/large-port-pipeline.md` |
|
||||
| B3 | Handoff to analyze-dag — decompose by source module into DAG nodes (legacy: roadmap skill, archived [TT-3072] phase 3) | `reference/large-port-pipeline.md` |
|
||||
| B4 | Per-node DAG task route: implement → review-code (the review-dag single gate replaces the legacy design-space + plan reviews at the Epic level) | `reference/large-port-pipeline.md` |
|
||||
| B5 | Verify — integration + fidelity, every `FID-*` traced to a passing test | `reference/fidelity-verification.md` |
|
||||
| B6 | **Final Approval** — consolidated port report | *(inline below)* |
|
||||
@@ -324,7 +324,7 @@ Present source analysis summary and request task-DAG decomposition. The
|
||||
Builder routes to `core/skills/analyze-dag/SKILL.md` with slug
|
||||
`port-{name}` (nodes per source module; the source analysis supplies node
|
||||
ACs and edge contracts). (Legacy: this handed off to the archived `roadmap`
|
||||
skill — `<instance-root>/archive/skills/roadmap/`, [org-internal #3072] phase 3.) See
|
||||
skill — `<instance-root>/archive/skills/roadmap/`, [TT-3072] phase 3.) See
|
||||
`reference/large-port-pipeline.md` for the handoff format.
|
||||
|
||||
##### Phase B4 — Per-Node Pipeline
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Mode: refactor) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Mode: refactor) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
### Mode: refactor
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
> Extracted from implement/SKILL.md (Pipeline Work Item Detection) — moved verbatim 2026-08-25, ticket [org-internal #3381].
|
||||
> Extracted from implement/SKILL.md (Pipeline Work Item Detection) — moved verbatim 2026-08-25, ticket [TT-3381].
|
||||
|
||||
## Pipeline Work Item Detection
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name: land-batch
|
||||
description: >
|
||||
Use ONLY when the orchestrator lands the finished task branches of one DAG
|
||||
iteration as a single batch PR ([org-internal #3731] batch-landing pilot). Composes
|
||||
iteration as a single batch PR ([TT-3731] batch-landing pilot). Composes
|
||||
path-disjoint member branches via the deterministic batch-compose script,
|
||||
pre-validates locally, opens ONE PR for N tasks (one CI fan-out instead of
|
||||
N on the single-runner pool), pastes each member's review synthesis into
|
||||
@@ -27,18 +27,18 @@ role: Producer
|
||||
(single writer at iteration close — the same role that already owns uniform
|
||||
merge/close). `workflow/batch/*` branches are NOT claim branches: no
|
||||
`claim.sh` interaction, no assignee; the orchestrator is the only composer.
|
||||
Pilot charter: the decision comment on [org-internal #3731] (scope, opt-in protocol, cap,
|
||||
Pilot charter: the decision comment on [TT-3731] (scope, opt-in protocol, cap,
|
||||
success criteria) — this skill implements that charter, not the epic's
|
||||
frozen DAG v1 (which covers only the merge-coordinator nodes N-01..04).
|
||||
|
||||
## Applicability: post-hoc composition only (topology B)
|
||||
|
||||
Two batch shapes exist ([org-internal #3731] charter addendum, comment 39347):
|
||||
Two batch shapes exist ([TT-3731] charter addendum, comment 39347):
|
||||
|
||||
- **Topology A — single-session mono-branch batch**: one session owns every
|
||||
ticket from inception and writes them on ONE branch (instance: PR [org-internal #3861],
|
||||
ticket from inception and writes them on ONE branch (instance: PR [TT-3861],
|
||||
audit-h1). Hand composition is natural there — do NOT force this skill on
|
||||
it; record the outcome on [org-internal #3731] as a manual-batch datum instead.
|
||||
it; record the outcome on [TT-3731] as a manual-batch datum instead.
|
||||
- **Topology B — parallel workers, post-hoc composition**: workers finish on
|
||||
SEPARATE branches at different times; the orchestrator composes at
|
||||
iteration close. This is the skill's ONLY applicability — cross-branch
|
||||
@@ -173,7 +173,7 @@ Do NOT hand-merge, do NOT hand-sync main into the batch branch.
|
||||
|
||||
Member issues auto-close via the English keywords; their `## 当前状态`
|
||||
PR/代码评审/CI rows fan out to EVERY close ref (status-sync poller Wide
|
||||
behavior — requires [org-internal #3867], merged 2026-08-31). `task done ≡ PR merged`
|
||||
behavior — requires [TT-3867], merged 2026-08-31). `task done ≡ PR merged`
|
||||
still holds, transitively
|
||||
through the batch PR; verify milestones fire unchanged.
|
||||
|
||||
@@ -189,15 +189,15 @@ through the batch PR; verify milestones fire unchanged.
|
||||
Any fallback preserves today's behavior — batch landing is an optimization,
|
||||
never a dependency.
|
||||
|
||||
## Measurement (pilot duty — revised per [org-internal #3731] charter addendum 39347)
|
||||
## Measurement (pilot duty — revised per [TT-3731] charter addendum 39347)
|
||||
|
||||
Per-iteration attribution only; the global 7-day ratio is trend context,
|
||||
never a pass/fail judge (same-window confounders: test-slim [org-internal #3855] /
|
||||
test-dedupe [org-internal #3854] / the pilot's own PRs). On the server,
|
||||
never a pass/fail judge (same-window confounders: test-slim [TT-3855] /
|
||||
test-dedupe [TT-3854] / the pilot's own PRs). On the server,
|
||||
`bun .gitea/scripts/ci-run-stats.ts --days 7 --json /tmp/<slug>-ci-stats.json`
|
||||
(the `--json` flag takes a filename — bare, it is a silent no-op; the human
|
||||
summary still prints). Same methodology as the checklist-merge-gate.yml
|
||||
2026-08-27 note. Record on [org-internal #3731]: (a) this batch iteration's per-workflow
|
||||
2026-08-27 note. Record on [TT-3731]: (a) this batch iteration's per-workflow
|
||||
trigger counts vs a historically similar 1:1 iteration, and (b) one
|
||||
fallback drill (construct a path-overlap group → exit-3 split executed).
|
||||
Baseline, trend only: 2026-08-31, 5,081 runs / TOTAL 2.75x single runner.
|
||||
|
||||
@@ -8,7 +8,7 @@ description: >
|
||||
project scaffolding. Do not use for application-level configuration —
|
||||
this skill covers the octopus project lifecycle, not user application code.
|
||||
triggers:
|
||||
# High-discrimination phrases only ([org-internal #4525]): bare "setup"/"init"/"配置" fire
|
||||
# High-discrimination phrases only ([TT-4525]): bare "setup"/"init"/"配置" fire
|
||||
# on any configuration mention, and the skill gate folds the previous
|
||||
# assistant turn on approval turns — one stray "配置" in a reply re-fires
|
||||
# the gate every turn. Keep triggers to phrases that name THIS workflow;
|
||||
@@ -36,7 +36,7 @@ This skill activates when the user's text matches any of the trigger keywords:
|
||||
- `project setup` — asking how to set up a project in octopus
|
||||
- `项目初始化` / `项目配置` — asking how to initialize or configure an octopus project (Chinese)
|
||||
|
||||
Generic "setup"/"init"/"配置" mentions are deliberately NOT triggers ([org-internal #4525]): they collide with everyday configuration talk, and the hard skill gate folds the previous assistant turn into its match text on approval turns — a passing "或配置x: false" in a reply would re-fire the gate every turn. `/init` note: `/init` generates AGENTS.md via LLM; kickoff uses the managed template from `octopus setup` — the Builder distinguishes based on context.
|
||||
Generic "setup"/"init"/"配置" mentions are deliberately NOT triggers ([TT-4525]): they collide with everyday configuration talk, and the hard skill gate folds the previous assistant turn into its match text on approval turns — a passing "或配置x: false" in a reply would re-fire the gate every turn. `/init` note: `/init` generates AGENTS.md via LLM; kickoff uses the managed template from `octopus setup` — the Builder distinguishes based on context.
|
||||
|
||||
Typical user intents include: encountering a readiness prompt at session start, wondering how to initialize a project, or wanting to understand the kickoff workflow steps.
|
||||
|
||||
@@ -74,14 +74,14 @@ The kickoff workflow runs in four automated steps:
|
||||
- [2/5] **Scaffold** — Creates the `<instance-root>/` skeleton (`core/skills/` directory + default `octopus.jsonc` template if absent); domain skills content arrives via the [5/5] overlay pull
|
||||
- [3/5] **Config stub + MCP wiring** — Writes the `mcp.codegraph` block into `octopus.jsonc`
|
||||
- [4/5] **Codegraph init** — Initializes and builds the per-project `.codegraph/` index
|
||||
- [5/5] **Skills remote + overlay pull** — Opt-in semantics ([org-internal #4370]); branches by flags when no `overlay.remotes` entry is configured:
|
||||
- [5/5] **Skills remote + overlay pull** — Opt-in semantics ([TT-4370]); branches by flags when no `overlay.remotes` entry is configured:
|
||||
- no flags (interactive run) — **safe default**: nothing is written; a remediation hint is printed (pass `--skills-remote`, or edit `overlay.remotes`), and the readiness skills item stays not-ready
|
||||
- `--yes` — legacy behavior kept: writes the default skills remote, then pulls domain skills content (`octopus skills pull` equivalent)
|
||||
- `--skills-remote <owner/repo>` (+ optional `--skills-remote-base-url <url>`) — writes the specified remote instead (ref `main`; base URL defaults to `<instance-base-url>`), then pulls from it
|
||||
- `overlay.remotes` already configured — the write is skipped (idempotent; an explicit `--skills-remote` is ignored with a warning)
|
||||
4. **Post-kickoff verification** — Run `octopus kickoff --check-only` again. After a `--yes` or `--skills-remote` run it reports all 5 items as ready; after a no-flag interactive run it reports 4 of 5 — the skills item stays not-ready until a remote is configured (`--skills-remote`, `--yes`, or a manual `overlay.remotes` edit + `octopus skills pull`).
|
||||
|
||||
### First-ticket hint ([org-internal #3061])
|
||||
### First-ticket hint ([TT-3061])
|
||||
|
||||
For a brand-new project still validating its concept, open the FIRST ticket as
|
||||
`Kind/MVP` — the interactive no-pipeline mode (decision log + debt register in
|
||||
|
||||
@@ -63,14 +63,14 @@ Run each check against the live project. Stop and report failures.
|
||||
- No new HIGH or CRITICAL CVEs block the release.
|
||||
- Pre-existing HIGH/CRITICAL CVEs do NOT block but **MUST be filed as
|
||||
tech-debt** before the release lands. File them in TWO TIERS (batching
|
||||
rule, [org-internal #3846] — a single release audit once fanned out to 14 TDs → 14 PRs →
|
||||
rule, [TT-3846] — a single release audit once fanned out to 14 TDs → 14 PRs →
|
||||
56-84 CI runs on a saturated runner pool): Tier A below is the general
|
||||
mechanical-change batching rule; Tier B and the escape hatch follow it.
|
||||
|
||||
<a id="phase-1-tier-a"></a>
|
||||
### Tier A — 通用机械变更并单规则 / Universal mechanical-change batching rule
|
||||
|
||||
Origin [org-internal #3846] (audit-batch pilot, generalized in place): the rule covers ANY
|
||||
Origin [TT-3846] (audit-batch pilot, generalized in place): the rule covers ANY
|
||||
single-source fan-out of mechanical changes, not just dependency audits.
|
||||
Two source types today: (a) dependency bump audits; (b) docs 批量修订
|
||||
(batch docs revisions).
|
||||
@@ -81,7 +81,7 @@ Two source types today: (a) dependency bump audits; (b) docs 批量修订
|
||||
source are filed as ONE batch issue + ONE batch PR — never N×issue +
|
||||
N×PR. The batch body keeps one row per item (per-CVE / per-doc mapping),
|
||||
so per-item traceability is unchanged; work the batch as a single PR.
|
||||
- **(a) Dependency bump audits** (the [org-internal #3846] origin case): advisories whose
|
||||
- **(a) Dependency bump audits** (the [TT-3846] origin case): advisories whose
|
||||
remediation is a plain version bump (lockfile-only diff, no semver-major
|
||||
jump, no overrides/catalog surgery, no API or adapter fallout) are filed
|
||||
together via REST `POST .../issues` with
|
||||
@@ -132,7 +132,7 @@ Two source types today: (a) dependency bump audits; (b) docs 批量修订
|
||||
along the reported pairs (or land the overlapping member 1:1) and re-run
|
||||
per group; `4` merge conflict / `5` transport/git error → fall back to
|
||||
1:1 PRs for the whole batch.
|
||||
- **Preflight hedge ([org-internal #3846])**: run `bun install --dry-run` before opening
|
||||
- **Preflight hedge ([TT-3846])**: run `bun install --dry-run` before opening
|
||||
a dependency-batch PR — the resolver accepting the composed version set
|
||||
is a cheap pre-CI rejection of impossible bump combinations.
|
||||
|
||||
@@ -292,7 +292,7 @@ Write to root `CHANGELOG.md` (prepend section).
|
||||
> the goal is identical (turn the tag into downloadable assets).
|
||||
|
||||
The CI publish pipeline (`.gitea/workflows/publish.yml`) was **retired by
|
||||
[org-internal #2003]** (138/138 historical runs cancelled; the pipeline sat unused for 35+
|
||||
[TT-2003]** (138/138 historical runs cancelled; the pipeline sat unused for 35+
|
||||
days). Releasing octopus is now a **manual local process**. All former CI
|
||||
steps live in repo scripts, runnable from a maintainer machine with the right
|
||||
credentials in the environment.
|
||||
@@ -358,11 +358,11 @@ credentials in the environment.
|
||||
### Notes
|
||||
|
||||
- **Windows code-signing** is not provisioned (no Windows runner / Azure
|
||||
Trusted Signing); the CLI ships unsigned, as before ([org-internal #252]).
|
||||
Trusted Signing); the CLI ships unsigned, as before ([TT-252]).
|
||||
- **Rollback**: if a step fails mid-release, the draft release + tag can be
|
||||
deleted and re-run; every script above is idempotent or safely re-runnable.
|
||||
- If a future CI pipeline replaces this manual flow, update this section and
|
||||
reference [org-internal #2003] for the retirement rationale.
|
||||
reference [TT-2003] for the retirement rationale.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ review findings not actionable upstream]`.
|
||||
archive-at-close; (b) the committed archive bundles
|
||||
`<runs-root>/archive/{slug}.json`, where per-review round counts are
|
||||
reconstructed from the documented `reviews/{stage}/round{N}/` layout in
|
||||
`index.artifacts[].path` ([org-internal #2591] — the archive source is what makes M3
|
||||
`index.artifacts[].path` ([TT-2591] — the archive source is what makes M3
|
||||
durable instead of structurally emptying as runs close). Available once
|
||||
any run has closed.
|
||||
- Rework fraction: 🟢 <15% / 🟡 15–30% / 🔴 >30%.
|
||||
@@ -245,7 +245,7 @@ or upstream design unclear]`.
|
||||
- 🟢 cache_read/input > 10:1 / 🟡 3–10:1 / 🔴 < 3:1.
|
||||
- < 3:1 → `[SIGNAL: cache hit <3:1 — context re-read, code-graph-first
|
||||
not followed]`.
|
||||
- **Compact frequency ([org-internal #2601] pilot data)**: report the token-telemetry
|
||||
- **Compact frequency ([TT-2601] pilot data)**: report the token-telemetry
|
||||
"Compactor Activity" line (compactor messages/tokens in window) and the
|
||||
zero-compact share of short runs (bugfix / DAG task) — the capacity-driven compaction
|
||||
pilot metrics. A rising zero-compact share with NO late-stage
|
||||
@@ -259,7 +259,7 @@ not followed]`.
|
||||
- < 1:1 → `[SIGNAL: explore/execute <1:1 — workers doing explorers' job,
|
||||
exploration skipped or under-delegated]`.
|
||||
|
||||
### 2.8 Gate defect-escape analysis (single metric, [org-internal #3061])
|
||||
### 2.8 Gate defect-escape analysis (single metric, [TT-3061])
|
||||
|
||||
Gates earn their cost by what they CATCH, and the honest test is what slips
|
||||
past them: a gate that runs clean while the same defect resurfaces downstream
|
||||
@@ -297,7 +297,7 @@ status` CLI or commit-status inspection. Final reports at
|
||||
downstream sources for an escape.
|
||||
3. Tally per `gate_id`: `clean_runs`, `escapes`, `escape_rate`.
|
||||
4. Reading (thresholds are this skill's own policy — the `gate_trim:` block
|
||||
they once deferred to was retired 2026-08-21, [org-internal #3072] phase 3; nothing
|
||||
they once deferred to was retired 2026-08-21, [TT-3072] phase 3; nothing
|
||||
trims gates anymore, so the trim-candidate branch below is gone):
|
||||
- `escape_rate ≥ 0.3` → the gate is
|
||||
**UNDER-POWERED**: route the escape causes into §2.9 pre-flight
|
||||
@@ -305,12 +305,12 @@ status` CLI or commit-status inspection. Final reports at
|
||||
propose trimming it.
|
||||
- `escape_rate < 0.3` → healthy; report the numbers, no further verdict.
|
||||
|
||||
**DAG single-gate exclusion ([org-internal #2267])**: `review-dag` is structurally
|
||||
**DAG single-gate exclusion ([TT-2267])**: `review-dag` is structurally
|
||||
non-trimmable (`dag.route.single_gate.never_trim: true` — self-contained in
|
||||
the `dag:` block); `verify` and `merge-pr` were `never_trim` in the retired
|
||||
`gate_trim` block and stay untouchable by convention.
|
||||
|
||||
**keep_gates exclusion (TD-390, [org-internal #3061]) — RETIRED with gate_trim**: the
|
||||
**keep_gates exclusion (TD-390, [TT-3061]) — RETIRED with gate_trim**: the
|
||||
rule that a trim candidate's gate must not be a member of the target route's
|
||||
`keep_gates` guarded a landing field (`sizing.tiers.*.additional_skip`)
|
||||
that no longer exists. Historical record: wiki `rules/gate-trim`.
|
||||
@@ -331,10 +331,10 @@ runs for a gate → report the raw numbers with
|
||||
- [NOTE: insufficient sample for gate X] where clean runs < 5.
|
||||
- UNDER-POWERED gates (escape_rate ≥ 0.3) feed §2.9 pre-flight — never a
|
||||
unilateral trim: the only exit is a furlough entry in
|
||||
`<instance-root>/gate-ledger.yaml` (evidence + reopen condition, [org-internal #3607]).
|
||||
`<instance-root>/gate-ledger.yaml` (evidence + reopen condition, [TT-3607]).
|
||||
```
|
||||
|
||||
### 2.9 Pre-flight defect-prevention analysis ([org-internal #2599])
|
||||
### 2.9 Pre-flight defect-prevention analysis ([TT-2599])
|
||||
|
||||
First-round FAIL/WARN findings are the pipeline's cost multiplier: every
|
||||
multi-round review pays for them twice (review round + revision round).
|
||||
@@ -348,13 +348,13 @@ code.
|
||||
reports for the cycle's tickets (`{slug}/reviews/{stage}/final/report` —
|
||||
round-1 findings with severity FAIL/WARN, their dimension codes, and the
|
||||
finding text for root-cause categorization) + the source issues'
|
||||
`Kind/*` labels. For DAG-routed Epics ([org-internal #2905] 方案 3), two further
|
||||
`Kind/*` labels. For DAG-routed Epics ([TT-2905] 方案 3), two further
|
||||
read-only sources feed the `REQ × late-discovery` root cause (step 1):
|
||||
(a) **DAG oversize-signal events** — `node_split` / registry-row additions
|
||||
recorded on the Epic's issue timeline / `## DAG 状态` whose trigger is a NEW
|
||||
requirement rather than a refactor; (b) **demo-period feedback** —
|
||||
stakeholder comments naming functionality the frozen DAG never covered. For browser-evidence
|
||||
cycles ([org-internal #4499], contract `browser-evidence-4486/shared/evidence-ref-v1` §3), a
|
||||
cycles ([TT-4499], contract `browser-evidence-4486/shared/evidence-ref-v1` §3), a
|
||||
third read-only
|
||||
source: (c) **browser session rows** — per browser-debug session
|
||||
`{session_id, outcome: evidence-captured | env-unavailable | replay-failed,
|
||||
@@ -373,7 +373,7 @@ Rows are currently Task-DAG cycle products by default (the helper's
|
||||
Bug- or Feature-cycle session to its own landing slot). The replay
|
||||
success-rate baseline (N-03 BENCH) is exposed as a consumable metric — a SEEDED CONVENTION (fixture-authored outcomes, channel health),
|
||||
NOT a live-browser trend baseline. Mechanical helper:
|
||||
`<harness-package>/scripts/browser-retro-tally.ts`. Boundary rules ([org-internal #4499]
|
||||
`<harness-package>/scripts/browser-retro-tally.ts`. Boundary rules ([TT-4499]
|
||||
AC-3): out-of-enum or empty categories fall into an explicit `other` bucket
|
||||
with provenance (recorded, never silently swallowed, never a crash); rows
|
||||
missing replay/attribution fields yield structured errors in the tally
|
||||
@@ -395,10 +395,10 @@ late-discovery` — 冻结后才被发现的需求 (a requirement that surfaced
|
||||
oversize signal or demo comment — count it from sources (a)/(b) above,
|
||||
not only from review findings.
|
||||
2. Tally per **route-class** — `Bug`, `Feature-DAG`, `Epic-DAG-route`,
|
||||
`Task-DAG` (Kind/Feature routes to the DAG pipeline since [org-internal #3061] Phase 2 /
|
||||
`Task-DAG` (Kind/Feature routes to the DAG pipeline since [TT-3061] Phase 2 /
|
||||
TD-388 — `Feature-legacy` survives only as a historical bucket for tickets
|
||||
closed before 2026-08-20; the Size dimension is retired from retro keying,
|
||||
[org-internal #3061]: DAG-routed tickets derive depth instead of carrying `Size/*`
|
||||
[TT-3061]: DAG-routed tickets derive depth instead of carrying `Size/*`
|
||||
(spec-06), and `Kind/Bug` carries no ladder). First-round hit count
|
||||
and distinct-ticket count per cause per class.
|
||||
3. A cause is a **pre-flight candidate** when ALL hold (thresholds from
|
||||
@@ -408,7 +408,7 @@ late-discovery` — 冻结后才被发现的需求 (a requirement that surfaced
|
||||
A qualifying `Epic × DAG-route` cause (e.g. `REQ × late-discovery`) lands
|
||||
on `<instance-root>/workflow-routing.yaml` `dag.route.preflight` — NOT
|
||||
`routes.Kind/Epic.preflight` (legacy-roadmap-era landing; the legacy route
|
||||
was archived [org-internal #3072] phase 3) ([org-internal #2905] 方案 3). The analyze-dag skill reads
|
||||
was archived [TT-3072] phase 3) ([TT-2905] 方案 3). The analyze-dag skill reads
|
||||
`dag.route.preflight` before decomposition.
|
||||
4. Aging: for causes ALREADY landed in `routes.{Kind}.preflight` or
|
||||
`dag.route.preflight`, count
|
||||
@@ -423,7 +423,7 @@ Sample-sufficiency guard mirrors 2.8: zero qualifying tickets → emit
|
||||
|
||||
| route-class | Cause (checklist-qualified dim × root-cause) | 1st-round hits | tickets | qualify? |
|
||||
| -------------- | ------------------------------------------- | -------------- | --------------------------- | -------------------------------- |
|
||||
| Bug | code-review.md COR × unhandled-null | 5 | 4 ([org-internal #2400] [org-internal #2429] [org-internal #2471] [org-internal #2488]) | ✅ PROPOSE |
|
||||
| Bug | code-review.md COR × unhandled-null | 5 | 4 ([TT-2400] [TT-2429] [TT-2471] [TT-2488]) | ✅ PROPOSE |
|
||||
| Bug | code-review.md STY × wrong-import-order | 6 | 2 | ⛔ tickets <3 |
|
||||
| Feature-DAG | code-review.md TST × missing-boundary-test | 3 | 3 | ⛔ hits <5 |
|
||||
| Epic-DAG-route | REQ × late-discovery | 5 | 3 (#27xx #28xx #29xx) | ✅ PROPOSE → dag.route.preflight |
|
||||
@@ -433,7 +433,7 @@ Sample-sufficiency guard mirrors 2.8: zero qualifying tickets → emit
|
||||
- Landed-item aging: `cor-unhandled-null clean streak 5 ≥ aging 5` → REMOVAL row.
|
||||
```
|
||||
|
||||
### 2.10 Derived-ticket health ([org-internal #3061])
|
||||
### 2.10 Derived-ticket health ([TT-3061])
|
||||
|
||||
Derived tickets (TD promotions, BF umbrellas, FT tickets) are the pipeline's
|
||||
exhaust. Unmanaged they accumulate into flush cycles (2026-08 evidence: 122
|
||||
@@ -477,7 +477,7 @@ this probe checks whether the system DIGESTS what it records:
|
||||
- rows marked [COLD] this cycle: {list or "none"}
|
||||
```
|
||||
|
||||
### 2.11 Threshold calibration tally ([org-internal #3380])
|
||||
### 2.11 Threshold calibration tally ([TT-3380])
|
||||
|
||||
Process prose constants (round caps, D1–D4 thresholds, preflight knobs,
|
||||
escape-rate cutoffs, quotas — full index:
|
||||
@@ -665,7 +665,7 @@ Each item MUST specify:
|
||||
- Action items that modify SKILLs or templates are applied immediately (the
|
||||
Retrospective Lead can edit `<instance-root>/` files).
|
||||
- Action items MUST NOT be vague ("try harder", "be more careful").
|
||||
- **Layering question** (injection-budget ruling item 3, [org-internal #3547]): every action
|
||||
- **Layering question** (injection-budget ruling item 3, [TT-3547]): every action
|
||||
item that encodes a lesson as a process constraint MUST answer **"which
|
||||
layer carries this lesson?"** — options in ascending per-turn cost, pick
|
||||
the cheapest that actually enforces it:
|
||||
@@ -682,7 +682,7 @@ Each item MUST specify:
|
||||
corpus — do not casually re-grow it; the rule-GC report in that same check
|
||||
flags aging L1 rules for L2 retirement).
|
||||
|
||||
**TRIM PROPOSAL rows — RETIRED ([org-internal #3072] phase 3, 2026-08-21)**: the
|
||||
**TRIM PROPOSAL rows — RETIRED ([TT-3072] phase 3, 2026-08-21)**: the
|
||||
gate-trim landing machinery (`gate_trim.action` →
|
||||
`sizing.tiers.{Size}.additional_skip` / `routes.{Kind}.skip` /
|
||||
`auto_approve.stages`) was removed with the `gate_trim:` and `sizing:`
|
||||
@@ -691,12 +691,12 @@ Gate health findings flow exclusively through §2.8's escape-rate verdict
|
||||
(UNDER-POWERED → §2.9 pre-flight) and ordinary action items. Historical
|
||||
spec: wiki `rules/gate-trim` (L2).
|
||||
|
||||
**PRE-FLIGHT PROPOSAL rows** (from Phase 2.9 defect-prevention, [org-internal #2599]): format
|
||||
**PRE-FLIGHT PROPOSAL rows** (from Phase 2.9 defect-prevention, [TT-2599]): format
|
||||
the What cell as
|
||||
`Add pre-flight '{id}' to {Kind} ({hits} first-round FAIL/WARN hits, {tickets} tickets — {evidence})`
|
||||
and the Where cell as
|
||||
`<instance-root>/workflow-routing.yaml` `routes.{Kind}.preflight` — or, for causes
|
||||
keyed `Epic × DAG-route` (e.g. `REQ × late-discovery`, [org-internal #2905] 方案 3),
|
||||
keyed `Epic × DAG-route` (e.g. `REQ × late-discovery`, [TT-2905] 方案 3),
|
||||
`<instance-root>/workflow-routing.yaml` `dag.route.preflight` (consumed by
|
||||
analyze-dag before decomposition).
|
||||
Aging removal rows: `Remove pre-flight '{id}' from {Kind} (clean streak {N} ≥ aging threshold)`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: review-artifact
|
||||
description: >-
|
||||
Use ONLY after analyze-dag has produced the DAG artifact — review the task DAG (review-dag single gate) — OR when auditing the <instance-root>/ process infrastructure itself (audit-process). Spawns N parallel Explorer reviewers (1 dimension each) against the matching checklist, synthesizes findings with a Worker Synthesizer, and iterates with a Worker reviser until convergence. The legacy roadmap / design-space / iteration-plan targets were archived 2026-08-21 ([org-internal #3072] phase 3, <instance-root>/archive/). Do NOT use for code review — use the review-code skill for that.
|
||||
Use ONLY after analyze-dag has produced the DAG artifact — review the task DAG (review-dag single gate) — OR when auditing the <instance-root>/ process infrastructure itself (audit-process). Spawns N parallel Explorer reviewers (1 dimension each) against the matching checklist, synthesizes findings with a Worker Synthesizer, and iterates with a Worker reviser until convergence. The legacy roadmap / design-space / iteration-plan targets were archived 2026-08-21 ([TT-3072] phase 3, <instance-root>/archive/). Do NOT use for code review — use the review-code skill for that.
|
||||
triggers:
|
||||
- audit-process
|
||||
- review-dag
|
||||
@@ -25,7 +25,7 @@ role: Reviewer
|
||||
## Tool Availability & Path Resolution
|
||||
|
||||
This skill's reviewers (parallel Explorer subagents) read two kinds of files.
|
||||
Some runs cannot reach the Gitea REST API (cross-repo scenario, [org-internal #2115]); the
|
||||
Some runs cannot reach the Gitea REST API (cross-repo scenario, [TT-2115]); the
|
||||
fallbacks below keep reviews working without it.
|
||||
|
||||
The Orchestrator probes REST reachability **before dispatching reviewers** (Phase A
|
||||
@@ -74,7 +74,7 @@ This skill reviews different artifact types. Identify the target from the pipeli
|
||||
| **review-dag** | `review-dag` | `core/checklists/dag-single-gate.md` | 3 | Analyst | `{epic-slug}/reviews/review-dag/` |
|
||||
|
||||
> **Retired targets (historical)**: the `roadmap`, `design-space`, and `plan`
|
||||
> targets were archived on 2026-08-21 per [org-internal #3072] phase 3 (ruling:
|
||||
> targets were archived on 2026-08-21 per [TT-3072] phase 3 (ruling:
|
||||
> `docs/workflow-refactor/phase3-retirement-ruling.md`) — the legacy
|
||||
> production skills they gated no longer exist (see `<instance-root>/archive/`).
|
||||
> Their stage ids (`review-roadmap`, `review-design-space`,
|
||||
@@ -84,7 +84,7 @@ This skill reviews different artifact types. Identify the target from the pipeli
|
||||
|
||||
The stage IDs remain as-is — they are used by the stage registry and auto-approve system. The skill name is `review-artifact`, but the stage IDs do not change.
|
||||
|
||||
> **Progressive disclosure ([org-internal #3734])**: this skill has two disjoint live
|
||||
> **Progressive disclosure ([TT-3734])**: this skill has two disjoint live
|
||||
> targets — dispatch an auditor/reviewer with
|
||||
> `skills: ["review-artifact:target-process"]` or
|
||||
> `["review-artifact:target-review-dag"]` (preamble + that target only)
|
||||
@@ -148,7 +148,7 @@ Before launching any review, confirm:
|
||||
|
||||
Each target adds specific preconditions listed in its section below. If any precondition is unmet, abort and inform the user.
|
||||
|
||||
> ## Retired targets (historical, [org-internal #3072] phase 3)
|
||||
> ## Retired targets (historical, [TT-3072] phase 3)
|
||||
|
||||
The three legacy production-review targets — **roadmap** (stage
|
||||
`review-roadmap`, checklist `roadmap.md`, revision role Analyst),
|
||||
@@ -187,7 +187,7 @@ The audit target is the **SDLC factory itself** — the set of skills, checklist
|
||||
- [ ] `core/skills/` exists and contains at least one `SKILL.md`.
|
||||
- [ ] `core/checklists/audit-process.md` is accessible.
|
||||
- [ ] `core/schemas/` contains the shared review schemas (`reviewer-output`, `synthesis`, `review-status`).
|
||||
- [ ] **Process-tests-green gate ([org-internal #4787] STD 8.8)**: before dispatching
|
||||
- [ ] **Process-tests-green gate ([TT-4787] STD 8.8)**: before dispatching
|
||||
auditors, the Orchestrator (bash-capable; Explorer auditors have none by
|
||||
construction) runs the process's own suite and guards — from
|
||||
`<harness-package>`: `bun run test:parallel`, plus the repo-root `check:*`
|
||||
@@ -366,9 +366,9 @@ from `Size/*` labels.
|
||||
| D1 | 1 | `all` |
|
||||
| D2 | 3 | `TOPO:1 REQMAP:1 RELEASE:1` |
|
||||
| D3 | 5 | `TOPO:2 REQMAP:2 RELEASE:1` |
|
||||
| D4 | 5 ([org-internal #3061] cap) | `TOPO:2 REQMAP:2 RELEASE:1` |
|
||||
| D4 | 5 ([TT-3061] cap) | `TOPO:2 REQMAP:2 RELEASE:1` |
|
||||
|
||||
> **D4 cap ([org-internal #3061])**: D4 keeps its own rounds budget (4) but its fanout is
|
||||
> **D4 cap ([TT-3061])**: D4 keeps its own rounds budget (4) but its fanout is
|
||||
> capped at D3 level (5 reviewers) — under the 3-dimension + checklist-bound
|
||||
> review the marginal coverage of 9 reviewers was redundancy, and round
|
||||
> iteration is the backstop.
|
||||
@@ -390,7 +390,7 @@ file (concurrent write race):
|
||||
`core/schemas/reviewer-output.schema.json`. Finding ids inside slot
|
||||
files MUST be slot-prefixed (`{DIM}R{k}-F{NNN}`, e.g. `TOPOR1-F001`) so ids
|
||||
stay unique across a dimension's slot files. This preserves per-reviewer
|
||||
attribution (retrospective overlap analysis, [org-internal #2996] step ①a) and makes the
|
||||
attribution (retrospective overlap analysis, [TT-2996] step ①a) and makes the
|
||||
write race impossible by construction.
|
||||
- Synthesis input for a dimension = ALL `findings-{DIM}*.json` in the round
|
||||
directory — the synthesizer already globs every `findings-*.json`; the slot
|
||||
|
||||
@@ -5,7 +5,7 @@ description: >
|
||||
ticket under a DAG-routed parent) against the node spec + frozen
|
||||
cross-session contracts of the frozen DAG copy (`{epic-slug}/dag`), or in
|
||||
standalone-bugfix mode without a design baseline. (The legacy
|
||||
approved-design pipeline mode was archived 2026-08-21, [org-internal #3072] phase 3.) Spawns up to 10 parallel Explorer reviewers (risk-tier scaled;
|
||||
approved-design pipeline mode was archived 2026-08-21, [TT-3072] phase 3.) Spawns up to 10 parallel Explorer reviewers (risk-tier scaled;
|
||||
fewer in standalone-bugfix mode where DGN may be skipped) against core/checklists/code-review.md, synthesizes
|
||||
findings with a Worker Synthesizer (the main-session Orchestrator aggregates), and iterates with a Worker developer until
|
||||
convergence.
|
||||
@@ -57,7 +57,7 @@ abstract best practices.
|
||||
|
||||
Before launching this review, confirm:
|
||||
|
||||
> **Legacy pipeline preconditions retired ([org-internal #3072] phase 3, 2026-08-21)**: the
|
||||
> **Legacy pipeline preconditions retired ([TT-3072] phase 3, 2026-08-21)**: the
|
||||
> design-document / design-space-convergence / iteration-plan-convergence
|
||||
> checks that used to head this list belonged to the archived legacy pipeline
|
||||
> (`design` / `plan-iterations` skills — `<instance-root>/archive/`). Live entry
|
||||
@@ -66,7 +66,7 @@ Before launching this review, confirm:
|
||||
> runs' design pages stay readable via `_shared/gitea-read-patterns.md`.
|
||||
|
||||
- [ ] Code files to review are specified (list of file paths or use `git diff`).
|
||||
- [ ] Mechanical-green gate PASSED (L0-enforced, [org-internal #2598]): run
|
||||
- [ ] Mechanical-green gate PASSED (L0-enforced, [TT-2598]): run
|
||||
`bun core/skills/review-code/scripts/precondition-gate.ts {slug}` —
|
||||
CI-aligned checks (`bun oxlint --deny-warnings` + `bun turbo typecheck`
|
||||
+ `test:changed` with `CI=true TEST_SHARDS=3`, mirroring ci.yml).
|
||||
@@ -83,7 +83,7 @@ Before launching this review, confirm:
|
||||
- [ ] 跨阶段门控清单: `core/checklists/pipeline-gate.md` is accessible and
|
||||
its Upstream Review Convergence section has been confirmed item by item.
|
||||
|
||||
**Kind/MVP graduation chokepoint ([org-internal #3061])**: when this skill is invoked ad hoc
|
||||
**Kind/MVP graduation chokepoint ([TT-3061])**: when this skill is invoked ad hoc
|
||||
on a `Kind/MVP` ticket's changes (no mode, no pipeline), the mechanical-green
|
||||
gate applies, and the Orchestrator additionally checks the diff for
|
||||
**graduation triggers** — changes crossing ≥2 modules, touching a shared
|
||||
@@ -110,9 +110,9 @@ no design doc exists at `.artifacts/{slug}/design/index.md`(存量只读,不
|
||||
|
||||
**Weakened preconditions** for standalone mode:
|
||||
|
||||
- Design doc existence → NOT required (the legacy design pipeline is archived, [org-internal #3072] phase 3).
|
||||
- Design doc existence → NOT required (the legacy design pipeline is archived, [TT-3072] phase 3).
|
||||
- **Instead require**: `.artifacts/{slug}/repro-notes.md`(存量只读,不迁移;Gitea 等效:wiki page `{slug}/repro-notes`,`_shared/gitea-read-patterns.md` Pattern 1)exists (bugfix Phase 1-2 output: reproduction steps + root cause) OR `.artifacts/{slug}/impl-notes.md`(存量只读,不迁移;Gitea 等效:wiki page `{slug}/impl-notes`,`_shared/gitea-read-patterns.md` Pattern 1)exists (post-fix behavior contract).
|
||||
- All other Preconditions (code files specified, mechanical-green gate green ([org-internal #2598]), checklist accessible) STILL APPLY.
|
||||
- All other Preconditions (code files specified, mechanical-green gate green ([TT-2598]), checklist accessible) STILL APPLY.
|
||||
- The `core/checklists/pipeline-gate.md` cross-stage gate (Upstream Review Convergence section) → NOT required; the bugfix-specific Pre-Design Falsification Gate section still applies if relevant.
|
||||
|
||||
**DGN dimension handling**: In standalone-bugfix mode, the DGN (Design Compliance & Dependencies) reviewer is SKIPPED because there is no design to comply with. The Orchestrator dispatches 9 reviewers (all 10 dimensions except DGN).
|
||||
@@ -120,7 +120,7 @@ no design doc exists at `.artifacts/{slug}/design/index.md`(存量只读,不
|
||||
**What standalone bugfix review focuses on**: code correctness, error handling & compatibility (COR), regression coverage (TST), security (SEC), performance (PERF), style & conventions (STY), database & data (DBT), accessibility & browser compatibility (A11Y), documentation (DOC), traceability (TRC) — everything that does not depend on a design baseline.
|
||||
|
||||
**Historical**: the legacy pipeline mode (design doc + design-space/plan
|
||||
review convergence as preconditions) was archived 2026-08-21 ([org-internal #3072] phase 3).
|
||||
review convergence as preconditions) was archived 2026-08-21 ([TT-3072] phase 3).
|
||||
Historical design pages remain readable via `_shared/gitea-read-patterns.md`.
|
||||
|
||||
### DAG Task Mode
|
||||
@@ -147,7 +147,7 @@ table and implement's §"DAG-mode input path"):
|
||||
| Iteration-plan review converged (`--stage iteration-plan`) | REMOVED (DAG has no plan review; the single review-dag gate replaces both) |
|
||||
| `slug` matches the design slug | N/A (review is scoped to the node ticket; run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace verify's task mode archives to — so review outputs are node-scoped and never clobber sibling nodes' reports. Note: this namespace covers review + verify runs only; the node's implement report below lives in the Epic run workspace `{epic-slug}/workers/` — implement worker runs keep the Epic run slug (implement §Preconditions: "DAG: `{epic-slug}`"), a different run from this review run) |
|
||||
| `core/checklists/pipeline-gate.md` Upstream Review Convergence | NOT required — the review-dag convergence check above stands in its place |
|
||||
| All other preconditions (code files specified, mechanical-green gate green ([org-internal #2598]), checklist accessible) | KEEP — unconditional; plus the implement report (AC → test traceability) present — Tier 1 at `<runs-root>/{epic-slug}/workers/{node-id}-worker-{seq}.md` (implement Phase 5 persistence; `{chunk-id}` = the node id) |
|
||||
| All other preconditions (code files specified, mechanical-green gate green ([TT-2598]), checklist accessible) | KEEP — unconditional; plus the implement report (AC → test traceability) present — Tier 1 at `<runs-root>/{epic-slug}/workers/{node-id}-worker-{seq}.md` (implement Phase 5 persistence; `{chunk-id}` = the node id) |
|
||||
|
||||
The `{BASELINE_SECTION}` for DAG-task mode uses the node spec + cross-session
|
||||
edge contracts from `{epic-slug}/dag` instead of the design index; the 5-Check
|
||||
@@ -228,7 +228,7 @@ file is a test file.
|
||||
- Design-space review convergence → NOT required.
|
||||
- Iteration-plan review convergence → NOT required.
|
||||
- All Preconditions from the pipeline checklist are bypassed.
|
||||
- Only requires: the mechanical-green gate ([org-internal #2598]) — same script as the full
|
||||
- Only requires: the mechanical-green gate ([TT-2598]) — same script as the full
|
||||
mode; on a test-only changeset `test:changed` selects exactly the changed
|
||||
tests, so the gate cost stays proportional to the diff.
|
||||
|
||||
@@ -263,7 +263,7 @@ fall back to the appropriate full mode (pipeline or standalone-bugfix).
|
||||
|
||||
## Agent Roles
|
||||
|
||||
> **Progressive disclosure ([org-internal #3722])**: when dispatching a Reviewer /
|
||||
> **Progressive disclosure ([TT-3722])**: when dispatching a Reviewer /
|
||||
> Synthesizer / Developer scoped to one phase, pass
|
||||
> `skills: ["review-code:phase-a"]` (preamble — incl. dimensions, JSON
|
||||
> schema, prompt template — plus that phase only) instead of the full body;
|
||||
@@ -338,7 +338,7 @@ audit (`review-artifact` targets):
|
||||
| `core/schemas/synthesis.schema.json` | Orchestrator round synthesis (Tier 2 — synthesis comment) |
|
||||
| `core/schemas/review-status.schema.json` | Review lifecycle tracking |
|
||||
|
||||
> **Findings sink: `tier1-local`** ([org-internal #1988]). `review-code` writes raw
|
||||
> **Findings sink: `tier1-local`** ([TT-1988]). `review-code` writes raw
|
||||
> per-dimension findings to Tier 1 local files (`<runs-root>/{slug}/reviews/code/`),
|
||||
> not Gitea issue comments. The synthesis comment + commit status stay Tier 2.
|
||||
> See `_shared/review-pipeline-phases.md` "Output model — two findings sinks"
|
||||
@@ -362,7 +362,7 @@ table).
|
||||
- `{REVIEWER_ROLE}`: code reviewer
|
||||
- `{BASELINE_SECTION}`:
|
||||
|
||||
**Legacy pipeline mode** (archived 2026-08-21, [org-internal #3072] phase 3 — the design
|
||||
**Legacy pipeline mode** (archived 2026-08-21, [TT-3072] phase 3 — the design
|
||||
doc at `{slug}/03-design-*` / `{slug}/02-03-req-design` it read is
|
||||
historical; live modes use the two baselines below):
|
||||
|
||||
@@ -464,7 +464,7 @@ table).
|
||||
|
||||
When invoked from the `implement` skill in bugfix mode (caller passes
|
||||
`mode: "standalone-bugfix"` — the legacy "detect absence of a design doc"
|
||||
fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
fallback is retired with the design pipeline, [TT-3072] phase 3):
|
||||
|
||||
1. The Orchestrator dispatches **9 reviewers** (all 10 dimensions **except DGN** — Design Compliance & Dependencies), because there is no design baseline to audit compliance against.
|
||||
2. For any dimension that would normally receive design reference files (COR, DGN, SEC, PERF, TST, DBT, A11Y, DOC, TRC), substitute the bugfix baseline docs:
|
||||
@@ -480,7 +480,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
```
|
||||
5. The `{CONTRADICTION_RULE}` is weakened: code that contradicts repro-notes/impl-notes is a MAJOR — there is no design to elevate to BLOCKER.
|
||||
6. All other Phase A dispatch rules (reviewer comment posting, commit status, reviewer prompt template, temperature, permissions, worktree-path rule) apply unchanged.
|
||||
7. Efficiency optimization (round 2+, [org-internal #2598]): follows the shared Phase D rule (`_shared/review-pipeline-phases.md` Phase D "Efficiency optimization") with no standalone-mode deviation — partial re-dispatch, full sweep every 2 rounds, delta-scoped reviewer input.
|
||||
7. Efficiency optimization (round 2+, [TT-2598]): follows the shared Phase D rule (`_shared/review-pipeline-phases.md` Phase D "Efficiency optimization") with no standalone-mode deviation — partial re-dispatch, full sweep every 2 rounds, delta-scoped reviewer input.
|
||||
|
||||
**Orchestrator actions**:
|
||||
|
||||
@@ -498,7 +498,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
|
||||
2. Initialize or update review status by posting a commit status via `POST /api/v1/repos/Octopus/octopus/statuses/{sha}` (`_shared/gitea-write-patterns.md` Pattern 8) with context `pipeline/review-code`. The commit-status payload carries `state` and `description`; the full review lifecycle state is documented in `core/schemas/review-status.schema.json` and tracked by the `octopus review status` CLI.
|
||||
|
||||
2.5. **Mechanical-green gate (mandatory, [org-internal #2598])** — before spawning ANY reviewer,
|
||||
2.5. **Mechanical-green gate (mandatory, [TT-2598])** — before spawning ANY reviewer,
|
||||
run `bun core/skills/review-code/scripts/precondition-gate.ts {slug} --round {N}`
|
||||
from the worktree root. Exit 0 → continue to step 3. Exit 1 → the script has
|
||||
appended a PRECONDITION-BLOCK record (Tier 1,
|
||||
@@ -516,7 +516,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
|
||||
3. Spawn **all reviewers in parallel** (10 in pipeline mode at Large tier; fewer at Small/Medium tiers; DGN skipped in standalone-bugfix mode). Each reviewer receives:
|
||||
- The standardized prompt (above) with dimension-specific values filled in.
|
||||
- For round ≥ 2 ([org-internal #2598] delta scoping): `{FILE_SECTIONS}` lists ONLY the
|
||||
- For round ≥ 2 ([TT-2598] delta scoping): `{FILE_SECTIONS}` lists ONLY the
|
||||
files revised since the previous round plus their 3–5 convention-comparison
|
||||
neighbors — not the round-1 full file set. Round 1 keeps the full set.
|
||||
- Agent type: Explorer.
|
||||
@@ -607,7 +607,7 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
- Updates review status by posting a commit status via `POST /api/v1/repos/Octopus/octopus/statuses/{sha}` (`_shared/gitea-write-patterns.md` Pattern 8)with context `pipeline/review-code`.
|
||||
- Persists its return summary to
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/synthesis-return.md` (Tier 1,
|
||||
worker-report persistence [org-internal #2847] — see
|
||||
worker-report persistence [TT-2847] — see
|
||||
`_shared/worker-report-persistence.md`) BEFORE returning, and registers
|
||||
the `index.json` row (type `other`, schema null, stage `review-code`,
|
||||
produced_by `Synthesizer`). The persisted copy is the report of record —
|
||||
@@ -633,240 +633,14 @@ fallback is retired with the design pipeline, [org-internal #3072] phase 3):
|
||||
---
|
||||
|
||||
<!-- section:phase-c -->
|
||||
## Phase C — Developer Revision
|
||||
### Phase C+D — Developer Revision & Re-review Loop — see `reference/revision-loop.md`
|
||||
|
||||
If `overall_verdict` is PASS, skip to Phase E.
|
||||
> Phase C (Developer revision: task-file preparation, revision survival via
|
||||
> `task_id` resume, convergence tracking) and Phase D (re-review loop until
|
||||
> convergence or round budget exhaustion) live in
|
||||
> `reference/revision-loop.md`. Read it when `overall_verdict` is not PASS.
|
||||
> On PASS, skip both phases and proceed to Phase E.
|
||||
|
||||
Otherwise:
|
||||
|
||||
**Orchestrator actions**:
|
||||
|
||||
1. Prepare the Developer's input as a structured task file,
|
||||
created as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/task-developer`.
|
||||
|
||||
This file must contain:
|
||||
- Paths to all code files that need revision.
|
||||
- Reference to the synthesis comment on the ticket (posted via `工单评论 API(见 TERMINOLOGY)` in Phase B — Tier 2).
|
||||
- References to the Tier 1 finding files for dimensions that have FAIL or WARN
|
||||
verdicts (`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`).
|
||||
- The Developer MUST NOT receive the full text of all reviewer findings
|
||||
inline — use finding-file path references only to avoid context explosion.
|
||||
- Convergence status: blockers/majors remaining vs. previous round.
|
||||
- **Revision survival ([org-internal #2601]) — primary path**: the task tool's completion
|
||||
output includes a `task_id`; passing it back resumes the SAME Developer
|
||||
subagent session instead of creating a fresh one. Round 1: persist the
|
||||
returned `task_id` with the round's working-notes entry (it must survive
|
||||
round-boundary compaction). Round ≥ 2: dispatch with `task_id` set to the
|
||||
previous revision round's — the Developer continues in-session with its
|
||||
prior diff/context; the round's task page then carries only the findings
|
||||
delta, not a full re-derivation. Reviewers are NEVER resumed — per-round
|
||||
freshness is their independence.
|
||||
- **Revision survival — fallback** (task_id lost to compaction before it
|
||||
was persisted): prepend the current `<runs-root>/{slug}/working-notes.md`
|
||||
content (run narrative memory — prior decisions, dead ends, reviewer
|
||||
feedback from earlier rounds) and reference the previous round's revision
|
||||
summary (`{slug}/reviews/code/round{N-1}/revision-summary`), stating
|
||||
explicitly that this revises code a prior round already wrote — do NOT
|
||||
re-read the full design/acceptance artifacts unless a finding requires
|
||||
them.
|
||||
|
||||
2. Spawn the Developer (Worker) with the prompt
|
||||
template at `core/skills/_shared/review-revision-prompt.md`, substituting:
|
||||
|
||||
- `{ROLE}`: Developer
|
||||
- `{TASK_FILE}`: task-developer
|
||||
- `{REVISION_SCOPE}`: Apply the Developer Revision Protocol (see Protocol
|
||||
subsection below) — evaluate each finding against codebase reality:
|
||||
Explorer reviewers are automated LLM sub-agents that can hallucinate
|
||||
citations, misapply rules, or miss design context. Verify cited code
|
||||
exists, the rule applies, and the fix does not break existing
|
||||
functionality. WAIVE technically-incorrect findings with justification
|
||||
(`WAIVED-{finding-id}` → one-line reason; canonical definition of the
|
||||
`WAIVED-{id}` convention, incl. the round-2+ cosmetic-MINOR waiver
|
||||
rule: `_shared/review-revision-prompt.md`). Revise code minimally and
|
||||
surgically — do NOT refactor unrelated code or introduce new behavior.
|
||||
- `{RESOLUTION_RULE}`: Do NOT silently deviate from the approved baseline
|
||||
(DAG task mode: the node spec + frozen cross-session contracts in
|
||||
`{epic-slug}/dag`; the legacy `{slug}/03-design-*` baseline is archived
|
||||
historical, [org-internal #3072] phase 3). If a finding exposes a design flaw, mark it
|
||||
as deferred with justification and suggest a design amendment — do not
|
||||
change the code against the baseline.
|
||||
- `{COSMETIC_MINOR_EXAMPLES}`: naming, comments, dead code, import
|
||||
ordering, style
|
||||
- `{WAIVED_EXAMPLE}`: `WAIVED-COR-R2-001`
|
||||
- `{CHECKLIST_REF}`: `core/checklists/code-review.md`
|
||||
- `{FILES_MODIFIED_LINE}`: {list}
|
||||
- `{RETURN_FILE}`:
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md`
|
||||
(Tier 1 return persistence — [org-internal #2847],
|
||||
`_shared/worker-report-persistence.md`)
|
||||
|
||||
3. The Developer revises the code files in place. The Developer creates a
|
||||
revision summary as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/revision-summary`,
|
||||
and persists its final return summary to
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md` (Tier 1,
|
||||
worker-report persistence [org-internal #2847] — see
|
||||
`_shared/worker-report-persistence.md`) BEFORE returning. If the
|
||||
completion notification is lost, the Orchestrator recovers the revision
|
||||
outcome from the persisted return (wiki page for the full summary,
|
||||
Tier 1 file for the conclusion of record).
|
||||
|
||||
4. **Pre-handoff gate** — before reporting completion, the Developer MUST run
|
||||
the same mechanical gate the Orchestrator will re-run at Phase D re-entry
|
||||
(the tree-fingerprint cache turns the re-run into a cache hit — one real
|
||||
execution per tree state, no double-paying):
|
||||
- Run `bun core/skills/review-code/scripts/precondition-gate.ts {slug} --round {N}`
|
||||
from the worktree root (oxlint + typecheck + `test:changed`, CI-aligned —
|
||||
`bun run test:parallel` is verify's job, not a per-revision
|
||||
requirement ([org-internal #2598])).
|
||||
- Exit 0 required; a new test failure, lint error, or type error introduced
|
||||
by the revision must be fixed before the Orchestrator proceeds to Phase D.
|
||||
- Report the gate's per-check results in the revision summary.
|
||||
|
||||
---
|
||||
|
||||
### Phase C — Developer Revision: Protocol
|
||||
|
||||
The Developer applies this cognitive protocol before implementing any finding.
|
||||
**Core principle:** reviewer findings are claims to evaluate, not orders to
|
||||
execute. Verify before implementing. Technical correctness over performative
|
||||
agreement.
|
||||
|
||||
#### Response Pattern
|
||||
|
||||
1. **READ** — Load every FAIL/WARN dimension finding file
|
||||
(`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`,
|
||||
Tier 1 local). Do not react item-by-item.
|
||||
2. **UNDERSTAND** — Restate each finding's requirement in your own words.
|
||||
If you cannot, the finding is unclear — see STOP rule below.
|
||||
3. **VERIFY** — Check the finding against codebase reality: does the cited
|
||||
code exist at the given file:line? Does the cited rule apply?
|
||||
4. **EVALUATE** — Is the finding technically correct for THIS codebase?
|
||||
Does the proposed fix break existing functionality? Does it conflict
|
||||
with the approved baseline (DAG task mode: the node spec + contracts in
|
||||
`{epic-slug}/dag`)?
|
||||
5. **RESPOND** — Fix it (correct), WAIVE it (`WAIVED-{finding-id}` →
|
||||
one-line reason), or flag it (unclear / design-level question).
|
||||
6. **IMPLEMENT** — One verified finding at a time, test each individually.
|
||||
|
||||
#### Evaluating Findings — 5-Check Gate
|
||||
|
||||
Before implementing any finding, run these checks:
|
||||
|
||||
1. **Cited code is real** — Open the file:line. Does the code exist and say
|
||||
what the finding claims?
|
||||
2. **Rule applies** — Does the cited checklist rule actually match this issue?
|
||||
3. **Reason for current implementation** — Is the flagged behavior
|
||||
intentional? Check the baseline (node spec + contracts in
|
||||
`{epic-slug}/dag` for DAG task mode) for rationale.
|
||||
4. **Fix does not break existing functionality** — Will the proposed change
|
||||
cause a regression?
|
||||
5. **Reviewer has full context** — Did the reviewer see the baseline (node
|
||||
spec + acceptance criteria) and the diff context? An isolated diff review
|
||||
can miss architectural intent.
|
||||
|
||||
```
|
||||
IF a finding seems wrong:
|
||||
WAIVE it: WAIVED-{finding-id} → <one-line technical reason>
|
||||
|
||||
IF you cannot easily verify a finding:
|
||||
State the limitation in revision_summary.md and request direction.
|
||||
|
||||
IF a finding conflicts with the approved design:
|
||||
Flag as a design-level question — do NOT silently change code against the design.
|
||||
```
|
||||
|
||||
#### Unclear Findings — STOP Rule
|
||||
|
||||
```
|
||||
IF any finding is unclear:
|
||||
STOP — do not implement ANY finding yet.
|
||||
Flag the unclear items in revision_summary.md and request clarification.
|
||||
|
||||
WHY: findings may be related. Partial understanding produces wrong
|
||||
implementation across multiple items.
|
||||
```
|
||||
|
||||
**Example:** The synthesis lists findings F1–F6. You understand F1, F2, F3, F6.
|
||||
F4 and F5 are ambiguous about what change is expected.
|
||||
- **WRONG:** implement F1, F2, F3, F6 now; ask about F4, F5 later.
|
||||
- **RIGHT:** "Understand F1, F2, F3, F6. Need clarification on F4, F5 before
|
||||
proceeding — they may interact with the same module."
|
||||
|
||||
#### YAGNI Check
|
||||
|
||||
```
|
||||
IF a reviewer suggests "implementing this properly" (full abstraction,
|
||||
generic API, configurable layer):
|
||||
Check actual usage (codegraph callers / grep) BEFORE expanding scope.
|
||||
|
||||
IF unused: WAIVE — "No call sites found. Leaving as-is (YAGNI)."
|
||||
IF used: Then implement properly.
|
||||
```
|
||||
|
||||
#### Forbidden Responses in revision_summary.md
|
||||
|
||||
**NEVER** write:
|
||||
- "You're absolutely right!" / "Great point!" / "Excellent catch!" — performative.
|
||||
- "Thanks for catching that!" / any gratitude expression.
|
||||
- "Let me implement that now" — before verification.
|
||||
|
||||
**INSTEAD:**
|
||||
- Restate the technical requirement concisely.
|
||||
- State the fix factually: `Fixed {finding-id}: <what changed> at <file:line>`.
|
||||
- Just fix it and show the result in the diff.
|
||||
|
||||
#### Gracefully Correcting a WAIVE
|
||||
|
||||
If you WAIVEd a finding and were wrong:
|
||||
```
|
||||
"Verified {finding-id} — the reviewer is correct. My initial read missed
|
||||
<reason>. Implementing now."
|
||||
```
|
||||
State the correction factually. No lengthy apology.
|
||||
|
||||
#### Implementation Order
|
||||
|
||||
For multi-finding revisions, after clarifying all unclear items:
|
||||
1. **Blocking issues** — security, data loss, breaks existing functionality.
|
||||
2. **Simple fixes** — typos, imports, naming, dead code.
|
||||
3. **Complex fixes** — logic changes, refactoring within minimal-surgical scope.
|
||||
Test each fix individually.
|
||||
|
||||
#### Rationalization-Anticipation Quick Reference
|
||||
|
||||
| Trap | Hold to |
|
||||
|------|---------|
|
||||
| "The reviewer flagged it as BLOCKER, so it must be real." | VERIFY cited code exists and rule applies before any edit. |
|
||||
| "Just fix everything to avoid a re-review round." | EVALUATE each finding; WAIVE the wrong ones with reasoning. |
|
||||
| "This finding looks plausible — I'll fix it without checking." | Open the file:line, confirm the behavior. |
|
||||
| "I'll implement the clear findings and ask about unclear ones later." | STOP. Clarify ALL unclear items before implementing any. |
|
||||
| "The reviewer wants it done 'properly' — full abstraction." | Check call sites first. If unused, WAIVE (YAGNI). |
|
||||
| "I shouldn't push back — the reviewer is probably right." | Push back with technical reasoning. The diff is the acknowledgment. |
|
||||
|
||||
---
|
||||
|
||||
<!-- section:phase-d -->
|
||||
## Phase D — Re-review Loop
|
||||
|
||||
After the Developer completes revision:
|
||||
|
||||
1. Increment the round counter (the Synthesizer updates the commit status in Phase B
|
||||
with the new round's results).
|
||||
2. Re-enter Phase A at step 2.5 — the mechanical-green gate re-runs on the
|
||||
revised tree before any reviewer spawn (a red gate blocks dispatch exactly
|
||||
as on round-1 entry) — then spawn the new round of reviewers against the
|
||||
revised files.
|
||||
|
||||
**Convergence criteria**: see `core/skills/_shared/review-pipeline-phases.md` Phase D for the canonical table (stop conditions). `{MAX_ROUNDS}` is per-skill — code review binds the routing budget: **2** rounds default, **3** for high risk (a BLOCKER survived a round, or the diff touches a frozen cross-session contract) — `<instance-root>/workflow-routing.yaml` `review.max_rounds` ([org-internal #3567]). The code-review-specific addition is inheritance of the shared INFO-disposition rule. The shared Round-3 Escalation Guardrail is scoped to the `review-artifact` skill targets only and does not apply here.
|
||||
|
||||
**Round budget (mandatory, [org-internal #3567])**: when `current_round` reaches the budget (2; 3 for high risk) without convergence, do NOT enter another round. STOP: register every remaining BLOCKER/MAJOR finding as TD registry rows (`rules/ticket-lifecycle.md`), record the verdict with the shared three-tier ladder (`core/schemas/synthesis.schema.json` `overall_verdict` + `core/skills/_shared/review-orchestrator-rules.md` rule 3): FAIL if any BLOCKER or FAIL dimension remains, else WARN, PASS only if every remaining dimension is PASS ([org-internal #4786]: the prior binary "else PASS" wording silently upgraded WARN-eligible outcomes to PASS), and close the loop. The debt is carried by the TD registry rows just registered, not by the recorded verdict. A review that cannot converge within budget is a design-level stall wearing review clothes (retro 2026-08-21 / [org-internal #3050]): in DAG task mode, map it to the DAG oversize signals (`<instance-root>/workflow-routing.yaml` `dag.size_derivation.oversize_signals`) and let the aggregator agent drive re-derivation + a `review-dag` re-run; otherwise record the design-level finding on the Epic, or open `{slug}/03-design-amendments` via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1).
|
||||
|
||||
**Efficiency optimization**: see `core/skills/_shared/review-pipeline-phases.md` Phase D (same rule — from round 2 onward ([org-internal #2598]), only spawn reviewers for FAIL/WARN/UNRESOLVED dimensions; full sweep every 2 rounds). Round ≥2 reviewer input is delta-scoped to the revised files + their neighbors.
|
||||
|
||||
<!-- inject: ../_shared/compaction-round-boundary.md -->
|
||||
|
||||
---
|
||||
|
||||
<!-- section:phase-e -->
|
||||
## Phase E — Final Report & Approval
|
||||
@@ -912,11 +686,11 @@ After the Developer completes revision:
|
||||
the findings JSONs are deleted at Tier 1 archive-at-close, so the final
|
||||
report is the ONLY durable carrier of round-1 findings — retrospective
|
||||
M7 (§2.9 first-round root-cause analysis) reads this table instead of
|
||||
relying on commit messages (retro 2026-08-21 / [org-internal #3120]).
|
||||
relying on commit messages (retro 2026-08-21 / [TT-3120]).
|
||||
|
||||
2.56. **Inline-ization — post the final round's findings as PR inline
|
||||
comments** (consumer of frozen contract
|
||||
`{epic-slug}/shared/review-inline-v1`, epic [org-internal #3533]; REQ-F-001/002/004).
|
||||
`{epic-slug}/shared/review-inline-v1`, epic [TT-3533]; REQ-F-001/002/004).
|
||||
After the final report page exists (step 1), post the FINAL round's
|
||||
findings as Gitea PR inline comments so review conclusions land
|
||||
line-level on the diff. Run the runner from the repo root:
|
||||
@@ -980,7 +754,7 @@ After the Developer completes revision:
|
||||
> THEN ask the human to approve. Approving before the reviewer is
|
||||
> registered produces `official: false` on the approval — the gate
|
||||
> treats the PR as unapproved and the approval must be re-done. See
|
||||
> `_shared/review-pipeline-phases.md` Phase E step 3.5. ([org-internal #1931]: audit
|
||||
> `_shared/review-pipeline-phases.md` Phase E step 3.5. ([TT-1931]: audit
|
||||
> R2→R3 re-loop + re-approve, ~30min wasted on exactly this ordering.)
|
||||
|
||||
```
|
||||
@@ -1058,7 +832,7 @@ To notify workflow completion, call the `signal_stage_done` tool.
|
||||
- Legacy design path (historical note, FLOW-F001 / audit-20260901): the
|
||||
design-document precondition row formerly in the DAG task-mode table
|
||||
(legacy `{slug}/03-design-index` / `{slug}/02-03-req-design` → node spec + frozen DAG
|
||||
copy) referenced the legacy design pipeline, archived 2026-08-21 with [org-internal #3072]
|
||||
copy) referenced the legacy design pipeline, archived 2026-08-21 with [TT-3072]
|
||||
phase 3 (see `<instance-root>/archive/skills/design/`); the live design baseline is
|
||||
the node spec + cross-session edge contracts in the frozen DAG copy
|
||||
`{epic-slug}/dag`.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Code Review Output Artifacts
|
||||
|
||||
> Output tree for code review artifacts. Read on-demand for reference.
|
||||
> Output model ([org-internal #1988] Tier 1 migration): Tier 1 local files (raw dimension findings) + Tier 2 wiki pages (task prompts, revision summaries, final reports) + Tier 2 synthesis comment. Status tracking via commit status `pipeline/review-code`.
|
||||
> Output model ([TT-1988] Tier 1 migration): Tier 1 local files (raw dimension findings) + Tier 2 wiki pages (task prompts, revision summaries, final reports) + Tier 2 synthesis comment. Status tracking via commit status `pipeline/review-code`.
|
||||
|
||||
```
|
||||
<runs-root>/{slug}/reviews/code/
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
> Extracted from review-code/SKILL.md (Phase C — Developer Revision +
|
||||
> Phase D — Re-review Loop) — moved verbatim; read on-demand when
|
||||
> `overall_verdict` is not PASS (skipped entirely on PASS, which jumps
|
||||
> straight to Phase E).
|
||||
|
||||
<!-- section:phase-c -->
|
||||
## Phase C — Developer Revision
|
||||
|
||||
If `overall_verdict` is PASS, skip to Phase E.
|
||||
|
||||
Otherwise:
|
||||
|
||||
**Orchestrator actions**:
|
||||
|
||||
1. Prepare the Developer's input as a structured task file,
|
||||
created as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/task-developer`.
|
||||
|
||||
This file must contain:
|
||||
- Paths to all code files that need revision.
|
||||
- Reference to the synthesis comment on the ticket (posted via `工单评论 API(见 TERMINOLOGY)` in Phase B — Tier 2).
|
||||
- References to the Tier 1 finding files for dimensions that have FAIL or WARN
|
||||
verdicts (`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`).
|
||||
- The Developer MUST NOT receive the full text of all reviewer findings
|
||||
inline — use finding-file path references only to avoid context explosion.
|
||||
- Convergence status: blockers/majors remaining vs. previous round.
|
||||
- **Revision survival ([TT-2601]) — primary path**: the task tool's completion
|
||||
output includes a `task_id`; passing it back resumes the SAME Developer
|
||||
subagent session instead of creating a fresh one. Round 1: persist the
|
||||
returned `task_id` with the round's working-notes entry (it must survive
|
||||
round-boundary compaction). Round ≥ 2: dispatch with `task_id` set to the
|
||||
previous revision round's — the Developer continues in-session with its
|
||||
prior diff/context; the round's task page then carries only the findings
|
||||
delta, not a full re-derivation. Reviewers are NEVER resumed — per-round
|
||||
freshness is their independence.
|
||||
- **Revision survival — fallback** (task_id lost to compaction before it
|
||||
was persisted): prepend the current `<runs-root>/{slug}/working-notes.md`
|
||||
content (run narrative memory — prior decisions, dead ends, reviewer
|
||||
feedback from earlier rounds) and reference the previous round's revision
|
||||
summary (`{slug}/reviews/code/round{N-1}/revision-summary`), stating
|
||||
explicitly that this revises code a prior round already wrote — do NOT
|
||||
re-read the full design/acceptance artifacts unless a finding requires
|
||||
them.
|
||||
|
||||
2. Spawn the Developer (Worker) with the prompt
|
||||
template at `core/skills/_shared/review-revision-prompt.md`, substituting:
|
||||
|
||||
- `{ROLE}`: Developer
|
||||
- `{TASK_FILE}`: task-developer
|
||||
- `{REVISION_SCOPE}`: Apply the Developer Revision Protocol (see Protocol
|
||||
subsection below) — evaluate each finding against codebase reality:
|
||||
Explorer reviewers are automated LLM sub-agents that can hallucinate
|
||||
citations, misapply rules, or miss design context. Verify cited code
|
||||
exists, the rule applies, and the fix does not break existing
|
||||
functionality. WAIVE technically-incorrect findings with justification
|
||||
(`WAIVED-{finding-id}` → one-line reason; canonical definition of the
|
||||
`WAIVED-{id}` convention, incl. the round-2+ cosmetic-MINOR waiver
|
||||
rule: `_shared/review-revision-prompt.md`). Revise code minimally and
|
||||
surgically — do NOT refactor unrelated code or introduce new behavior.
|
||||
- `{RESOLUTION_RULE}`: Do NOT silently deviate from the approved baseline
|
||||
(DAG task mode: the node spec + frozen cross-session contracts in
|
||||
`{epic-slug}/dag`; the legacy `{slug}/03-design-*` baseline is archived
|
||||
historical, [TT-3072] phase 3). If a finding exposes a design flaw, mark it
|
||||
as deferred with justification and suggest a design amendment — do not
|
||||
change the code against the baseline.
|
||||
- `{COSMETIC_MINOR_EXAMPLES}`: naming, comments, dead code, import
|
||||
ordering, style
|
||||
- `{WAIVED_EXAMPLE}`: `WAIVED-COR-R2-001`
|
||||
- `{CHECKLIST_REF}`: `core/checklists/code-review.md`
|
||||
- `{FILES_MODIFIED_LINE}`: {list}
|
||||
- `{RETURN_FILE}`:
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md`
|
||||
(Tier 1 return persistence — [TT-2847],
|
||||
`_shared/worker-report-persistence.md`)
|
||||
|
||||
3. The Developer revises the code files in place. The Developer creates a
|
||||
revision summary as a wiki page via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1)with page_name `{slug}/reviews/code/round{N}/revision-summary`,
|
||||
and persists its final return summary to
|
||||
`<runs-root>/{slug}/reviews/code/round{N}/revision-return.md` (Tier 1,
|
||||
worker-report persistence [TT-2847] — see
|
||||
`_shared/worker-report-persistence.md`) BEFORE returning. If the
|
||||
completion notification is lost, the Orchestrator recovers the revision
|
||||
outcome from the persisted return (wiki page for the full summary,
|
||||
Tier 1 file for the conclusion of record).
|
||||
|
||||
4. **Pre-handoff gate** — before reporting completion, the Developer MUST run
|
||||
the same mechanical gate the Orchestrator will re-run at Phase D re-entry
|
||||
(the tree-fingerprint cache turns the re-run into a cache hit — one real
|
||||
execution per tree state, no double-paying):
|
||||
- Run `bun core/skills/review-code/scripts/precondition-gate.ts {slug} --round {N}`
|
||||
from the worktree root (oxlint + typecheck + `test:changed`, CI-aligned —
|
||||
`bun run test:parallel` is verify's job, not a per-revision
|
||||
requirement ([TT-2598])).
|
||||
- Exit 0 required; a new test failure, lint error, or type error introduced
|
||||
by the revision must be fixed before the Orchestrator proceeds to Phase D.
|
||||
- Report the gate's per-check results in the revision summary.
|
||||
|
||||
---
|
||||
|
||||
### Phase C — Developer Revision: Protocol
|
||||
|
||||
The Developer applies this cognitive protocol before implementing any finding.
|
||||
**Core principle:** reviewer findings are claims to evaluate, not orders to
|
||||
execute. Verify before implementing. Technical correctness over performative
|
||||
agreement.
|
||||
|
||||
#### Response Pattern
|
||||
|
||||
1. **READ** — Load every FAIL/WARN dimension finding file
|
||||
(`<runs-root>/{slug}/reviews/code/round{N}/findings-{DIMENSION_CODE}.json`,
|
||||
Tier 1 local). Do not react item-by-item.
|
||||
2. **UNDERSTAND** — Restate each finding's requirement in your own words.
|
||||
If you cannot, the finding is unclear — see STOP rule below.
|
||||
3. **VERIFY** — Check the finding against codebase reality: does the cited
|
||||
code exist at the given file:line? Does the cited rule apply?
|
||||
4. **EVALUATE** — Is the finding technically correct for THIS codebase?
|
||||
Does the proposed fix break existing functionality? Does it conflict
|
||||
with the approved baseline (DAG task mode: the node spec + contracts in
|
||||
`{epic-slug}/dag`)?
|
||||
5. **RESPOND** — Fix it (correct), WAIVE it (`WAIVED-{finding-id}` →
|
||||
one-line reason), or flag it (unclear / design-level question).
|
||||
6. **IMPLEMENT** — One verified finding at a time, test each individually.
|
||||
|
||||
#### Evaluating Findings — 5-Check Gate
|
||||
|
||||
Before implementing any finding, run these checks:
|
||||
|
||||
1. **Cited code is real** — Open the file:line. Does the code exist and say
|
||||
what the finding claims?
|
||||
2. **Rule applies** — Does the cited checklist rule actually match this issue?
|
||||
3. **Reason for current implementation** — Is the flagged behavior
|
||||
intentional? Check the baseline (node spec + contracts in
|
||||
`{epic-slug}/dag` for DAG task mode) for rationale.
|
||||
4. **Fix does not break existing functionality** — Will the proposed change
|
||||
cause a regression?
|
||||
5. **Reviewer has full context** — Did the reviewer see the baseline (node
|
||||
spec + acceptance criteria) and the diff context? An isolated diff review
|
||||
can miss architectural intent.
|
||||
|
||||
```
|
||||
IF a finding seems wrong:
|
||||
WAIVE it: WAIVED-{finding-id} → <one-line technical reason>
|
||||
|
||||
IF you cannot easily verify a finding:
|
||||
State the limitation in revision_summary.md and request direction.
|
||||
|
||||
IF a finding conflicts with the approved design:
|
||||
Flag as a design-level question — do NOT silently change code against the design.
|
||||
```
|
||||
|
||||
#### Unclear Findings — STOP Rule
|
||||
|
||||
```
|
||||
IF any finding is unclear:
|
||||
STOP — do not implement ANY finding yet.
|
||||
Flag the unclear items in revision_summary.md and request clarification.
|
||||
|
||||
WHY: findings may be related. Partial understanding produces wrong
|
||||
implementation across multiple items.
|
||||
```
|
||||
|
||||
**Example:** The synthesis lists findings F1–F6. You understand F1, F2, F3, F6.
|
||||
F4 and F5 are ambiguous about what change is expected.
|
||||
- **WRONG:** implement F1, F2, F3, F6 now; ask about F4, F5 later.
|
||||
- **RIGHT:** "Understand F1, F2, F3, F6. Need clarification on F4, F5 before
|
||||
proceeding — they may interact with the same module."
|
||||
|
||||
#### YAGNI Check
|
||||
|
||||
```
|
||||
IF a reviewer suggests "implementing this properly" (full abstraction,
|
||||
generic API, configurable layer):
|
||||
Check actual usage (codegraph callers / grep) BEFORE expanding scope.
|
||||
|
||||
IF unused: WAIVE — "No call sites found. Leaving as-is (YAGNI)."
|
||||
IF used: Then implement properly.
|
||||
```
|
||||
|
||||
#### Forbidden Responses in revision_summary.md
|
||||
|
||||
**NEVER** write:
|
||||
- "You're absolutely right!" / "Great point!" / "Excellent catch!" — performative.
|
||||
- "Thanks for catching that!" / any gratitude expression.
|
||||
- "Let me implement that now" — before verification.
|
||||
|
||||
**INSTEAD:**
|
||||
- Restate the technical requirement concisely.
|
||||
- State the fix factually: `Fixed {finding-id}: <what changed> at <file:line>`.
|
||||
- Just fix it and show the result in the diff.
|
||||
|
||||
#### Gracefully Correcting a WAIVE
|
||||
|
||||
If you WAIVEd a finding and were wrong:
|
||||
```
|
||||
"Verified {finding-id} — the reviewer is correct. My initial read missed
|
||||
<reason>. Implementing now."
|
||||
```
|
||||
State the correction factually. No lengthy apology.
|
||||
|
||||
#### Implementation Order
|
||||
|
||||
For multi-finding revisions, after clarifying all unclear items:
|
||||
1. **Blocking issues** — security, data loss, breaks existing functionality.
|
||||
2. **Simple fixes** — typos, imports, naming, dead code.
|
||||
3. **Complex fixes** — logic changes, refactoring within minimal-surgical scope.
|
||||
Test each fix individually.
|
||||
|
||||
#### Rationalization-Anticipation Quick Reference
|
||||
|
||||
| Trap | Hold to |
|
||||
|------|---------|
|
||||
| "The reviewer flagged it as BLOCKER, so it must be real." | VERIFY cited code exists and rule applies before any edit. |
|
||||
| "Just fix everything to avoid a re-review round." | EVALUATE each finding; WAIVE the wrong ones with reasoning. |
|
||||
| "This finding looks plausible — I'll fix it without checking." | Open the file:line, confirm the behavior. |
|
||||
| "I'll implement the clear findings and ask about unclear ones later." | STOP. Clarify ALL unclear items before implementing any. |
|
||||
| "The reviewer wants it done 'properly' — full abstraction." | Check call sites first. If unused, WAIVE (YAGNI). |
|
||||
| "I shouldn't push back — the reviewer is probably right." | Push back with technical reasoning. The diff is the acknowledgment. |
|
||||
|
||||
---
|
||||
|
||||
<!-- section:phase-d -->
|
||||
## Phase D — Re-review Loop
|
||||
|
||||
After the Developer completes revision:
|
||||
|
||||
1. Increment the round counter (the Synthesizer updates the commit status in Phase B
|
||||
with the new round's results).
|
||||
2. Re-enter Phase A at step 2.5 — the mechanical-green gate re-runs on the
|
||||
revised tree before any reviewer spawn (a red gate blocks dispatch exactly
|
||||
as on round-1 entry) — then spawn the new round of reviewers against the
|
||||
revised files.
|
||||
|
||||
**Convergence criteria**: see `core/skills/_shared/review-pipeline-phases.md` Phase D for the canonical table (stop conditions). `{MAX_ROUNDS}` is per-skill — code review binds the routing budget: **2** rounds default, **3** for high risk (a BLOCKER survived a round, or the diff touches a frozen cross-session contract) — `<instance-root>/workflow-routing.yaml` `review.max_rounds` ([TT-3567]). The code-review-specific addition is inheritance of the shared INFO-disposition rule. The shared Round-3 Escalation Guardrail is scoped to the `review-artifact` skill targets only and does not apply here.
|
||||
|
||||
**Round budget (mandatory, [TT-3567])**: when `current_round` reaches the budget (2; 3 for high risk) without convergence, do NOT enter another round. STOP: register every remaining BLOCKER/MAJOR finding as TD registry rows (`rules/ticket-lifecycle.md`), record the verdict with the shared three-tier ladder (`core/schemas/synthesis.schema.json` `overall_verdict` + `core/skills/_shared/review-orchestrator-rules.md` rule 3): FAIL if any BLOCKER or FAIL dimension remains, else WARN, PASS only if every remaining dimension is PASS ([TT-4786]: the prior binary "else PASS" wording silently upgraded WARN-eligible outcomes to PASS), and close the loop. The debt is carried by the TD registry rows just registered, not by the recorded verdict. A review that cannot converge within budget is a design-level stall wearing review clothes (retro 2026-08-21 / [TT-3050]): in DAG task mode, map it to the DAG oversize signals (`<instance-root>/workflow-routing.yaml` `dag.size_derivation.oversize_signals`) and let the aggregator agent drive re-derivation + a `review-dag` re-run; otherwise record the design-level finding on the Epic, or open `{slug}/03-design-amendments` via `wiki 读写 API(见 TERMINOLOGY)` (`_shared/gitea-write-patterns.md` Pattern 1).
|
||||
|
||||
**Efficiency optimization**: see `core/skills/_shared/review-pipeline-phases.md` Phase D (same rule — from round 2 onward ([TT-2598]), only spawn reviewers for FAIL/WARN/UNRESOLVED dimensions; full sweep every 2 rounds). Round ≥2 reviewer input is delta-scoped to the revised files + their neighbors.
|
||||
|
||||
<!-- inject: ../_shared/compaction-round-boundary.md -->
|
||||
|
||||
---
|
||||
+26
-674
@@ -60,10 +60,10 @@ digraph verify {
|
||||
|
||||
## Agent Role
|
||||
|
||||
> **Progressive disclosure ([org-internal #3722], [org-internal #3734], [org-internal #3745])**: when dispatching a Verifier
|
||||
> **Progressive disclosure ([TT-3722], [TT-3734], [TT-3745])**: when dispatching a Verifier
|
||||
> scoped to one phase, pass `skills: ["verify:phase-2"]` (preamble + that
|
||||
> phase only) instead of the full body; multi-phase dispatches may union.
|
||||
> Phase 5 is subdivided ([org-internal #3734]): `phase-5` covers the report template only;
|
||||
> Phase 5 is subdivided ([TT-3734]): `phase-5` covers the report template only;
|
||||
> each mandatory filing subsection carries its own marker (`phase-5.5` tech
|
||||
> debt, `phase-5.55` baseline failures, `phase-5.56` flaky tests,
|
||||
> `phase-5.6` checklist sync, `phase-5.7` CI sync). Dispatch recipes:
|
||||
@@ -71,7 +71,7 @@ digraph verify {
|
||||
> / `phase-5.56` when baseline failures / flaky tests are present); PASS
|
||||
> close-out →
|
||||
> `"verify:phase-5,phase-5.5,phase-5.55,phase-5.56,phase-5.6,phase-5.7,phase-6"`.
|
||||
> The DAG branch is separately marked ([org-internal #3745]): `phase-6` narrows to
|
||||
> The DAG branch is separately marked ([TT-3745]): `phase-6` narrows to
|
||||
> Approval + Commit Gate, and the tail References rides `dag-branch` (same
|
||||
> tail rule as review-code's phase-e). Non-DAG dispatches thereby drop the
|
||||
> ~175-line DAG branch; DAG milestone/task verify → union `dag-branch` onto
|
||||
@@ -155,7 +155,7 @@ Before starting verification, confirm:
|
||||
node spec, its `acceptance_criteria` + `test_id` declarations, and the
|
||||
DoD slice. (Legacy tier rule — `{slug}/04-plan-*` wiki pages / issue
|
||||
comment, and the design-space + iteration-plan convergence checks that
|
||||
used to follow here — was archived 2026-08-21, [org-internal #3072] phase 3; historical
|
||||
used to follow here — was archived 2026-08-21, [TT-3072] phase 3; historical
|
||||
plan/AC pages stay readable via `_shared/gitea-read-patterns.md`.)
|
||||
- [ ] `core/checklists/verification.md` is accessible.
|
||||
- [ ] `slug` matches the run's slug (DAG: `{epic-slug}`).
|
||||
@@ -223,7 +223,7 @@ the DAG branch below for its read map):
|
||||
(The legacy `Size/*`-tiered locations — `{slug}/04-plan-*`,
|
||||
`{slug}/02-requirements-index`, `{slug}/02-03-req-design`,
|
||||
`{slug}/03-design-06-non-functional-design` — were archived 2026-08-21,
|
||||
[org-internal #3072] phase 3; historical pages stay readable for legacy-run verification
|
||||
[TT-3072] phase 3; historical pages stay readable for legacy-run verification
|
||||
via `_shared/gitea-read-patterns.md`.)
|
||||
|
||||
5. **Code review final report** — `{slug}/reviews/code/final/report`
|
||||
@@ -277,7 +277,7 @@ before. This section saves redundant typecheck/lint/security re-runs; it
|
||||
never weakens a gate.
|
||||
|
||||
**Second evidence source — the review-code precondition-gate cache
|
||||
(eff-gate-cache [org-internal #2598] / [org-internal #2990])**. The mechanical checks this phase would re-run
|
||||
(eff-gate-cache [TT-2598] / [TT-2990])**. The mechanical checks this phase would re-run
|
||||
(oxlint / typecheck / `test:changed`) are exactly the precondition-gate's
|
||||
check-set, and the gate caches GREEN results keyed on a tree fingerprint
|
||||
(HEAD + tracked diff + untracked contents) in
|
||||
@@ -394,8 +394,8 @@ For each DoD entry with verification method "Security scan":
|
||||
every failing test, run it on the last known-green commit (or the base
|
||||
branch) in isolation. **Never use `git stash` for this** — the stash stack
|
||||
is shared across all worktrees of this repo and a parallel session can
|
||||
overwrite your entry mid-flight (issue [org-internal #1655]). Instead, use the
|
||||
lifecycle-managed scratch-worktree script ([org-internal #2790]) — it registers the
|
||||
overwrite your entry mid-flight (issue [TT-1655]). Instead, use the
|
||||
lifecycle-managed scratch-worktree script ([TT-2790]) — it registers the
|
||||
worktree for the sweep backstop, symlinks `node_modules` from the source
|
||||
checkout when `bun.lock` matches (dropping the per-instance cost from
|
||||
~170k inodes to ~7k), and deregisters on removal:
|
||||
@@ -435,7 +435,7 @@ For each DoD entry with verification method "Security scan":
|
||||
### 2.7 — Browser Evidence Reference Validation (UI-touching PR)
|
||||
|
||||
For DoD entries of the「UI 主张 ↔ 可复现浏览器证据」type — contract
|
||||
`browser-evidence-4486/shared/evidence-ref-v1` (frozen 2026-09-10, [org-internal #4498]).
|
||||
`browser-evidence-4486/shared/evidence-ref-v1` (frozen 2026-09-10, [TT-4498]).
|
||||
Applicable ONLY to UI-touching PRs (changes under `packages/app`,
|
||||
`packages/ui`, or `packages/console/*` frontend surfaces):
|
||||
|
||||
@@ -493,7 +493,7 @@ Browser-evidence rows (UI-touching PRs only, Phase 2.7): ✅ PASS requires a
|
||||
mechanically validated, replayable pack-ref; `unregistered` / `manifest-missing` /
|
||||
`manifest-corrupt` / `not-replayable` / `over-limit` references are
|
||||
⚠️ UNVERIFIABLE at best — the reference channel fails explicitly, never
|
||||
silently green ([org-internal #4498] AC-4).
|
||||
silently green ([TT-4498] AC-4).
|
||||
|
||||
### Iteration Verdict
|
||||
|
||||
@@ -619,501 +619,20 @@ issue close) is performed later in Phase 5.6 — see
|
||||
`rules/issue-checklist-sync.md` § 归档动作.
|
||||
|
||||
<!-- section:phase-5.5 -->
|
||||
### Phase 5.5 — Tech Debt Registry Filing (mandatory before PASS)
|
||||
|
||||
Tech debt is filed **registry-first** (`core/rules/ticket-lifecycle.md`,
|
||||
[org-internal #3002] G1): new items become ROWS in the source ticket's `## TD 登记` comment;
|
||||
an independent ticket is created only at **promotion** (claim/schedule). There
|
||||
is no `tech-debt.md` file and no `{slug}/tech-debt` wiki page — both remain
|
||||
retired. The registry preserves the three guarantees of the old
|
||||
one-issue-per-item model: visible (the comment lives on a tracker ticket),
|
||||
individually closeable (row-level checkbox), de-duplicated across sessions
|
||||
(the TD index is stronger than title-keyword matching).
|
||||
|
||||
**Sprint-mode override ([org-internal #3002] G5/[org-internal #3007])**: read `filing.sprint-mode` from
|
||||
`<instance-root>/workflow-routing.yaml` at the START of this phase (no caching). When
|
||||
`true`, ALL severities file registry-only — registration rows are written as
|
||||
normal (severity included, nothing lost) but promotion to standalone tickets
|
||||
is FROZEN until the switch returns to `false`. Rationale: the 2026-08-12
|
||||
sprint zeroed fix capacity while filing kept running (the 125-fragment
|
||||
backlog's direct trigger); an explicit debt-side downshift beats hoping for
|
||||
discipline. BF/FT phases 5.55/5.56 are NOT covered by this switch — failure
|
||||
evidence must stay immediately visible. Flipping the switch is a human
|
||||
decision recorded on the sprint tracker; semantics in
|
||||
`rules/workflow-routing.md` §立案降档.
|
||||
|
||||
**Adjacency quota ([org-internal #3002] G3/[org-internal #3005])**: while collecting inputs, also check the
|
||||
AREAS this iteration touched (packages/modules with commits this iteration).
|
||||
If the source tickets for those areas carry applicable `## TD 登记` rows, at
|
||||
least ONE row must be taken along and disposed this iteration (fixed, or
|
||||
explicitly re-deferred with a reason — silence is not a disposition). Record
|
||||
`consumed X / applicable Y` (or `0 applicable`) in the TD report section;
|
||||
verification checklist §8.4 cross-checks it against the run's debt-quota
|
||||
record (historically the roadmap's per-chunk debt-quota line). This gives debt digestion a steady capacity source tied to
|
||||
touch, not to cleanup campaigns.
|
||||
|
||||
**Promotion quota + pull event ([org-internal #3061])**: promotion to a standalone ticket
|
||||
requires (a) a **pull event** — the row's Reactivation Trigger fired (state
|
||||
the observed event) OR a named claimer/schedule; "it seemed important" is not
|
||||
a pull event — recorded in the promotion body's `## 拉动事件 / Pull Event`
|
||||
section; and (b) the origin module's OPEN promoted-TD count is below the
|
||||
quota (**default 10** — counted **per origin module**: resolve the row's
|
||||
module from the ticket body's `Origin` field, then count that module's OPEN
|
||||
`tech-debt` tickets; retro §2.10 reports breaches). At or above quota →
|
||||
register-only until the count drops; before each Phase 5.5 promotion
|
||||
re-check the owning module's count, and a row whose module is at or above
|
||||
quota is NOT promoted — defer it and annotate the registry row with
|
||||
`quota-held` (re-checked on the next verify run, retro 2026-08-21). A row
|
||||
marked `[COLD]` by retrospective §2.10
|
||||
(unclaimed >3 retro cycles) promotes only after the pull event clears the
|
||||
mark.
|
||||
|
||||
**Collect inputs** — every tech-debt item to register this iteration:
|
||||
|
||||
1. Every UNVERIFIABLE row in the DoD matrix (Phase 3), with its Reactivation
|
||||
Trigger.
|
||||
2. Every ACCEPTED_RISK finding in the code-review final report
|
||||
(`{slug}/reviews/code/final/report`), with its Recommended Reactivation
|
||||
Trigger.
|
||||
3. Every `[OPEN: <short-id>]` marker the Developer left in code this iteration
|
||||
(per implementation checklist POST-6.2).
|
||||
|
||||
If the code-review final report does not exist, warn the user — ACCEPTED_RISK
|
||||
items cannot be captured. This is itself a process gap that must be flagged.
|
||||
|
||||
**Step 1 — De-duplicate against the registry index and promoted issues.**
|
||||
|
||||
1. Read the source ticket's `## TD 登记` comment (create the comment if this
|
||||
is its first row) and match each candidate against existing rows by
|
||||
`TD-NNN` and reactivation trigger. Same-source re-reporting is the
|
||||
anti-pattern this step exists to prevent (the visual-cluster incident: 18
|
||||
fragments from one source under the old keyword matching).
|
||||
2. Query OPEN promoted tech-debt issues for cross-source duplicates:
|
||||
|
||||
```
|
||||
工单 API 检索(见 TERMINOLOGY)
|
||||
(owner/repo 按实例绑定,labels="tech-debt", state="open")
|
||||
```
|
||||
|
||||
**Step 2 — Assign `TD-NNN` via the ledger mutex ([org-internal #3322]).** One script call
|
||||
per batch: `bash script/td-alloc.sh <count = new items> <source-slug>
|
||||
[--ticket N]` returns a contiguous range from the TD allocation ledger
|
||||
(append-only comments, earliest-comment-id wins; the seed comment pins the
|
||||
historical floor). Split the returned range across the Step 3 rows in order.
|
||||
**Any allocation — manual included — must land a `**td-alloc**` comment on
|
||||
the ledger before the registry row is written; hand-computed `max + 1` is
|
||||
forbidden** (the 2026-08-24 three-way collision). On exit 5 (retry
|
||||
exhaustion) abort this phase's filing and retry — never hand-assign. The id is **reserved for life**: promotion reuses it, never
|
||||
renumbers. Run `--check` (reconciliation) here if the last check predates
|
||||
this batch.
|
||||
|
||||
**Step 3 — Append one registry row per new item.** Append to the source
|
||||
ticket's `## TD 登记` comment (no source ticket → the owning Epic's tracker
|
||||
ticket; no Epic → the standing `TD 冷存档` tracker):
|
||||
|
||||
```markdown
|
||||
- [ ] TD-{NNN} · {UNVERIFIABLE | ACCEPTED_RISK | DEFERRED} · {HIGH | MEDIUM | LOW}
|
||||
· {origin chunk-id/iter-N} — {one-line summary}
|
||||
· trigger: {objectively verifiable reactivation condition — never "when ready";
|
||||
if no trigger can be defined this is NOT tech debt and the iteration verdict
|
||||
becomes FAIL}
|
||||
```
|
||||
|
||||
**Step 4 — Cross-link (adapted).** The registry comment already lives on the
|
||||
source issue — the source → debt navigation the old body-edit provided. When
|
||||
filing went to an Epic tracker or the 冷存档 (no source ticket), reference the
|
||||
originating slug in each row so the trail survives.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The report's
|
||||
"Tech Debt" section records `TD-NNN → registry row` (source `#NNNN` +
|
||||
`## TD 登记` comment); promoted items record `TD-NNN → #NNNN` as before.
|
||||
|
||||
**Promotion (认领升票) — when a row is scheduled or picked up.** Create the
|
||||
independent ticket THEN, carrying the reserved `TD-NNN`:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Tech debt: {short description} (TD-{NNN})",
|
||||
"body":<promotion template below>,
|
||||
"labels":[tech_debt_label_id, severity_label_id]}
|
||||
```
|
||||
|
||||
- **Severity → label** (reuse the existing exclusive Priority set):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- **Promotion body template** (the pre-[org-internal #3002] issue template, now used only at
|
||||
promotion):
|
||||
|
||||
```markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue carrying the ## TD 登记 row}
|
||||
|
||||
## Summary
|
||||
|
||||
{one-paragraph description of the debt}
|
||||
|
||||
| Field | Value |
|
||||
| -------- | ------------------------------------------- |
|
||||
| TD ID | TD-{NNN} (reserved at registration) |
|
||||
| Type | {UNVERIFIABLE \| ACCEPTED_RISK \| DEFERRED} |
|
||||
| Origin | {chunk-id/iter-N/phase or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
|
||||
## Reactivation Trigger
|
||||
|
||||
{from the registry row}
|
||||
|
||||
## 拉动事件 / Pull Event
|
||||
|
||||
{trigger fired: {observed event} | claimed by {who} for {when}}
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] {specific action that resolves the debt}
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
- Code review report: `{slug}/reviews/code/final/report` (if ACCEPTED_RISK)
|
||||
```
|
||||
|
||||
- After creating the promoted ticket: tick the registry row (`- [x]`) and
|
||||
append `→ #NNNN` to it.
|
||||
|
||||
If no new tech-debt items were found this iteration, the phase is a no-op —
|
||||
record "0 tech-debt items" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.55 -->
|
||||
### Phase 5.55 — Baseline-Failure Issue Registration (mandatory before PASS when pre-existing failures exist)
|
||||
|
||||
Pre-existing test failures (BF) are tracked as **root-cause family umbrella
|
||||
tickets** (`core/rules/ticket-lifecycle.md`, [org-internal #3002] G1; precedents [org-internal #2585]
|
||||
umbrella + [org-internal #2925] cluster) — one `BF-NNN` ticket per failure-signature family,
|
||||
labeled `baseline-failure`, with each occurrence's evidence attached as
|
||||
comments. There is no `baseline-failures.md` file and no
|
||||
`{slug}/baseline-failures` wiki page. A pre-existing failure does not block
|
||||
the iteration that _discovered_ it (it pre-dates that work), but it MUST be
|
||||
filed against (or into) a family; an un-filed baseline failure is a process
|
||||
gap and the iteration is NOT Done.
|
||||
|
||||
**Birth triage SLA ([org-internal #3061])**: a BF umbrella is born with `Kind/Bug` (it IS a
|
||||
bug — of the baseline) and must be triaged the SAME DAY it is filed:
|
||||
assigned, scheduled, or explicitly deferred with a reason on the ticket.
|
||||
Untriaged-next-day BF umbrellas are named individually in retro §2.10
|
||||
(compliance %), not averaged away.
|
||||
|
||||
**Collect inputs** — every pre-existing failure to register this iteration:
|
||||
|
||||
1. Every failure classified **pre-existing** in Phase 2.6 (fails on the base
|
||||
branch / last-green commit too).
|
||||
2. Any baseline-run failures noted in the brownfield pre-check (Greenfield vs.
|
||||
Brownfield section).
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [org-internal #2696]). Query `baseline-failure` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=baseline-failure&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the error/assertion signature
|
||||
plus the affected surface, not just `file::test-name` (one root-cause family
|
||||
may span several tests; several tests failing with the same assertion shape
|
||||
are ONE family). On a signature hit, do NOT create a new ticket: attach the
|
||||
new run evidence (run, commit, failing output, sibling tests observed) as a
|
||||
comment on the FAMILY umbrella ticket. Filing a second ticket inside a known
|
||||
root-cause family is the anti-pattern this phase exists to prevent. If a
|
||||
tracked family is now FIXED by this iteration's work, close its umbrella with
|
||||
a comment citing the fixing commit (a bonus, not a requirement). If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [org-internal #3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `BF-NNN`** per `core/rules/testing.md`
|
||||
§ "Pre-existing test failures must be filed, not silently logged" (the L1 rule
|
||||
owns the repo-wide sequential numbering invariant — `max + 1`, duplicate ids
|
||||
forbidden incl. closed tickets). `BF-NNN` names the FAMILY; the Gitea issue
|
||||
number `#NNNN` is the tracker handle.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Baseline failure: {test identifier} (BF-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[baseline_failure_label_id, severity_label_id, kind_bug_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Baseline failure: {signature summary} (BF-{NNN})`
|
||||
where `{origin}` is `chunk-{id}/iter-{N}` or the bugfix slug, and
|
||||
`{signature summary}` is the family's error/assertion shape (not a single
|
||||
test name — sibling tests observed later join this umbrella as evidence
|
||||
comments).
|
||||
- **Severity → label** (reuse the existing exclusive Priority set; a failing
|
||||
test defaults to at least MEDIUM, HIGH if on a critical path):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- Also attach `Kind/Bug` so the failure is discoverable in the bug tracker
|
||||
alongside manually-reported bugs.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration baseline"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test was already failing before this iteration's work began. It does not
|
||||
block the discovering iteration but must be tracked to closure.
|
||||
|
||||
| Field | Value |
|
||||
| -------------- | ---------------------------------------------- |
|
||||
| BF ID | BF-{NNN} (family) |
|
||||
| Signature | {error/assertion shape} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| First observed | {base commit / date the failure reproduces on} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
git checkout {base commit}
|
||||
(cd <harness-package> && bun test --timeout 120000 {test file}) # or project-equivalent
|
||||
```
|
||||
|
||||
Failing output:
|
||||
|
||||
```
|
||||
{paste the relevant assertion / error}
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The named test passes on a clean checkout of the target branch.
|
||||
- [ ] If the test is deleted/renamed, the replacement covers the same
|
||||
behavior and passes.
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Per the
|
||||
issue-cross-linking rule, every baseline-failure issue MUST link back to its
|
||||
source:
|
||||
|
||||
- The issue body already carries `## Parent` (above).
|
||||
- Update the source/parent issue body to reference each new baseline-failure
|
||||
issue by `#NNNN` in its task list (e.g.
|
||||
`- [ ] #NNNN — BF-{NNN} {test identifier}`), so reviewers can navigate from
|
||||
source → failure.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`BF-NNN → #NNNN` mapping is written ONLY in the Phase 5 verification report's
|
||||
"Baseline Failures" section (and in the issue title itself). There is no local
|
||||
file to update.
|
||||
|
||||
If no new baseline failures were found this iteration, the phase is a no-op —
|
||||
record "0 baseline failures" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.56 -->
|
||||
### Phase 5.56 — Flaky-Test Issue Registration (mandatory before PASS when flaky tests are unfixed)
|
||||
|
||||
Flaky tests (intermittent pass/fail) are tracked as **root-cause family
|
||||
umbrella tickets** (`core/rules/ticket-lifecycle.md`, [org-internal #3002] G1) — one
|
||||
`FT-NNN` ticket per failure-signature family, labeled `flaky-test`, with each
|
||||
occurrence's evidence (run count, failure rate, commit) attached as comments.
|
||||
A flaky test that is not fixed within this iteration MUST be filed against
|
||||
(or into) a family; otherwise it evaporates at iteration end and the
|
||||
"compare flaky count against baseline" check (TST-2.5) has no persistent
|
||||
register to compare against. Filing does not block the verdict, but an unfixed
|
||||
flaky test left un-filed is a process gap and the iteration is NOT Done.
|
||||
|
||||
**Expiry SLA ([org-internal #3061])**: an FT umbrella is born with `Kind/Testing` and a
|
||||
**fix-or-isolate window** (default 7 days) recorded in its body (isolating =
|
||||
quarantining/skipping the test with the family id in the skip reason, which
|
||||
keeps the register comparable). Past the window without fix or isolation, the
|
||||
umbrella is escalated on the ticket (comment naming the owner); retro §2.10
|
||||
reports fix-or-isolate compliance per cycle.
|
||||
|
||||
**Collect inputs** — every flaky test to register this iteration:
|
||||
|
||||
1. Every flaky test surfaced in Phase 2.1 (intermittent pass/fail across
|
||||
reruns) that was NOT fixed by the Developer this iteration.
|
||||
2. Any flaky test carried over from a prior iteration's report that is still
|
||||
intermittently failing.
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [org-internal #2696]). Query `flaky-test` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=flaky-test&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the flakiness mode (timeout /
|
||||
race / order-dependence / env-leak) plus the affected surface, not just
|
||||
`file::test-name` (one root cause may flake several tests). On a signature
|
||||
hit, do NOT create a new ticket: attach the new run evidence (run count,
|
||||
failure rate, commit, sibling tests) as a comment on the FAMILY umbrella
|
||||
ticket. Filing a second ticket inside a known root-cause family is the
|
||||
anti-pattern this phase exists to prevent. If a tracked family now passes
|
||||
deterministically, close its umbrella citing the fixing commit. If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [org-internal #3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `FT-NNN`** per `core/rules/testing.md`
|
||||
§ "Flaky tests must be filed, not silently tolerated" (the L1 rule owns the
|
||||
repo-wide sequential numbering invariant — `max + 1`, duplicate ids forbidden
|
||||
incl. closed tickets). `FT-NNN` names the FAMILY.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Flaky test: {test identifier} (FT-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[flaky_test_label_id, severity_label_id, kind_testing_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Flaky test: {signature summary} (FT-{NNN})` — the
|
||||
family's flakiness mode + surface (sibling tests join later as evidence
|
||||
comments, not new tickets).
|
||||
- **Severity** → a flaky test defaults to MEDIUM (HIGH if on a critical path
|
||||
or blocking CI); reuse the exclusive Priority set.
|
||||
- Also attach `Kind/Testing` so it is discoverable in the testing tracker.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration verification"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test passes and fails intermittently across runs. It undermines the
|
||||
reliability of the suite and must be stabilized or quarantined.
|
||||
|
||||
| Field | Value |
|
||||
| ------------ | ------------------------- |
|
||||
| FT ID | FT-{NNN} (family) |
|
||||
| Signature | {flakiness mode + surface} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| Failure rate | {e.g. 3/10 runs} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
for i in $(seq 1 10); do (cd <harness-package> && bun test --timeout 120000 {test file}) || echo "run $i FAILED"; done
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The test passes deterministically across 10 consecutive runs.
|
||||
- [ ] If it cannot be stabilized, it is quarantined (`test.skip` /
|
||||
`test.todo` with a comment citing FT-{NNN}) and a stable replacement
|
||||
is filed as tech-debt (TD-NNN).
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Every flaky-test
|
||||
issue links back to its source via `## Parent`, and the source/parent issue
|
||||
task list references each by `#NNNN`
|
||||
(`- [ ] #NNNN — FT-{NNN} {test identifier}`).
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`FT-NNN → #NNNN` mapping is written ONLY in the Phase 5 report's "Flaky Tests"
|
||||
section (and the issue title). No local file.
|
||||
|
||||
If no unfixed flaky tests exist this iteration, the phase is a no-op — record
|
||||
"0 flaky tests" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.6 -->
|
||||
### Phase 5.6 — Issue Checklist Sync (final sweep, mandatory before PASS)
|
||||
|
||||
This is the **final** checklist sync — the last of the progressive sync
|
||||
points (requirements exit, design exit, plan exit, each iteration commit, PR
|
||||
creation, review convergence, CI transitions, and here — per the sync-point
|
||||
table in `core/rules/issue-checklist-sync.md`). Earlier syncs may have
|
||||
already checked off completed items; this phase catches everything remaining
|
||||
and ensures no `- [ ]` item is left without an annotation.
|
||||
|
||||
1. **Identify the source issue** per `core/rules/issue-checklist-sync.md`
|
||||
§ "How to sync (each point)" step 1 (find `Closes #N` / `Fixes #N` in the
|
||||
PR body or commit messages). If no source issue exists (e.g. standalone
|
||||
bugfix with no tracking issue), skip this phase.
|
||||
2. **Fetch the issue body** via `工单 API(见 TERMINOLOGY)get` (rule step 2).
|
||||
3. **Map every remaining `- [ ]` checklist item** to one of three states:
|
||||
- **Done** (missed by earlier syncs) → mark `- [x]` and append
|
||||
`_(PR #NNN: <file/component>)_`.
|
||||
- **Deferred** → keep `- [ ]` and append `_(Deferred: TD-NNN <reason>)_`.
|
||||
- **Pending** → keep `- [ ]` and append `_(Pending: <blocker>)_`.
|
||||
4. **Fold the `## 当前状态` live-status section** (if present). Rows that have
|
||||
a checklist counterpart (review, process-ACs) are already reflected as
|
||||
checklist annotations at their sync points. Rows with no checklist
|
||||
counterpart in a non-Epic issue (PR opened/merged) are folded as follow-up
|
||||
evidence on the issue narrative (e.g. `_(PR #NNN merged: <summary>)_` on the
|
||||
item it delivered, or in the report). Once every row is accounted for,
|
||||
remove the section from the issue body.
|
||||
5. **archive-at-close: mark the `## 工件索引` comment archived** (归档动作 — [org-internal #1929]). Issue
|
||||
closing IS the archive-at-close action; it is explicit, not implicit. Edit the index
|
||||
comment in place per `_shared/gitea-write-patterns.md` Pattern 10 Archive-at-close
|
||||
(mechanism — banner + every row's 重读 → ARCHIVE + invariants — is defined there,
|
||||
do not restate; sequence/actor per `rules/issue-checklist-sync.md` § 归档动作).
|
||||
- Skip if no source issue exists.
|
||||
- **Tier 1 run archive** ([org-internal #1988] two-tier artifacts — only if a Tier 1 run
|
||||
workspace exists): if `<runs-root>/{slug}/` exists (a stage in this run
|
||||
produced Tier 1 local artifacts, e.g. review-code findings), archive the
|
||||
run workspace per `core/rules/two-tier-artifacts.md` § Archive-at-close
|
||||
(the L1 rule is authoritative — do NOT restate its steps here).
|
||||
The archived bundle must pass
|
||||
`core/schemas/runs-bundle.schema.json` validation (the generator
|
||||
validates by default; a red exit blocks close).
|
||||
Verify deltas only: skip in milestone/task DAG mode (the aggregator agent
|
||||
performs it at Epic/task-ticket close — see the DAG branch below).
|
||||
6. **Update the issue body** via `工单 API(见 TERMINOLOGY)update` with the annotated
|
||||
checklist. Preserve all non-checklist content unchanged.
|
||||
7. **Verify**: re-read the issue and confirm no `- [ ]` item lacks an
|
||||
annotation. Every unchecked item MUST have a `(Deferred: ...)` or
|
||||
`(Pending: ...)` note explaining why it is not done.
|
||||
8. **Close the issue** (completes the archive-at-close loop): if the flow has
|
||||
no PR (no `Closes #N` on merge), the Verifier closes the issue after PASS
|
||||
approval via `工单 API(见 TERMINOLOGY)update(state="closed")` — the banner date is
|
||||
corrected to the actual close date if it differs from today. If a PR carries
|
||||
`Closes #N`, the merge closes it; no further action.
|
||||
|
||||
If a checklist item cannot be mapped to evidence, deferral, or pending
|
||||
status, the iteration is NOT Done — the item represents untracked scope.
|
||||
### Phase 5.5–5.6 — Issue Filing Protocols (TD registry / baseline / flaky / checklist sync)
|
||||
|
||||
> The four mandatory-before-PASS filing protocols — Phase 5.5 Tech-Debt
|
||||
> registry filing (sprint-mode override), Phase 5.55 baseline-failure
|
||||
> registration, Phase 5.56 flaky-test registration, Phase 5.6 issue
|
||||
> checklist final sweep — live in `reference/issue-filing.md`. Read each at
|
||||
> its boundary during Phase 5; PASS is blocked until all applicable filings
|
||||
> report completion. Phase 5.7 (CI state sync) stays inline below.
|
||||
|
||||
<!-- section:phase-5.7 -->
|
||||
### Phase 5.7 — CI State Transition Sync (progressive)
|
||||
|
||||
Process-type acceptance criteria (e.g. "ci.yml passes N consecutive runs",
|
||||
AC#3 in [org-internal #1668]) have no single moment of completion — their progress lives on
|
||||
AC#3 in [TT-1668]) have no single moment of completion — their progress lives on
|
||||
the issue. The `CI` row in `## 当前状态` is written by the `status-sync` poller
|
||||
(`.gitea/scripts/status-sync-poll.ts`), NOT this skill — do NOT manually
|
||||
`工单 API(见 TERMINOLOGY)update` it. When verification observes a CI state transition
|
||||
@@ -1121,7 +640,7 @@ the issue. The `CI` row in `## 当前状态` is written by the `status-sync` pol
|
||||
process-AC's progress note in place via `工单 API(见 TERMINOLOGY)update` (per the
|
||||
`issue-checklist-sync` L1 rule § Automated sync — the poller owns the CI row;
|
||||
the checklist annotation remains manual). Do NOT wait for Phase 5.6: a
|
||||
transition left unsynced for tens of minutes is exactly the staleness [org-internal #1689]
|
||||
transition left unsynced for tens of minutes is exactly the staleness [TT-1689]
|
||||
targets. Skip if no source issue exists.
|
||||
|
||||
---
|
||||
@@ -1213,181 +732,14 @@ To notify workflow completion, call the `signal_stage_done` tool.
|
||||
---
|
||||
|
||||
<!-- section:dag-branch -->
|
||||
## DAG branch (milestone + task modes)
|
||||
## DAG branch (milestone + task modes) — see `reference/dag-branch.md`
|
||||
|
||||
> This branch OVERRIDES the Preconditions table, Phase 1 read inputs, Phase 5
|
||||
> report index, Phase 5.5 ACCEPTED_RISK source, Phase 5.6 final sweep, and
|
||||
> Phase 6.5 commit gate for a DAG-ticket-pipeline Epic. It applies when the
|
||||
> routed Epic is DAG-shaped: a frozen DAG copy exists at `{epic-slug}/dag` and
|
||||
> the DAG's `task_route.keep_gates` includes `verify`. Legacy iteration verify
|
||||
> (the sections above) remains authoritative for non-DAG iterations. Spec:
|
||||
> `dag-pipeline/spec-05` §5. commit status stays
|
||||
> `pipeline/verify` in both modes.
|
||||
> This branch (milestone mode / task mode / no-milestone Epic gate) lives in
|
||||
> `reference/dag-branch.md`, read it on-demand when the Epic is DAG-shaped:
|
||||
> frozen DAG at `{epic-slug}/dag` + `task_route.keep_gates` includes `verify`.
|
||||
> Legacy iteration verify (the sections above) remains authoritative for
|
||||
> non-DAG iterations. Spec: `dag-pipeline/spec-05` §5.
|
||||
|
||||
### Milestone mode (verify runs on a milestone M when `all_incoming_done_and_green`)
|
||||
|
||||
A milestone node (`type: milestone`) has no implementation work and no ticket;
|
||||
its verify is the integration verification welded at a DAG convergence point
|
||||
(`cross_session_in ≥ 2`). Trigger: the aggregator agent (main
|
||||
session/Orchestrator) detects `all_incoming_done_and_green` — every fan-in
|
||||
source node at its terminal state (task source `done` / milestone source
|
||||
`green`) — and initiates this verify run; the milestone never self-triggers.
|
||||
|
||||
**Precondition replacements** (vs legacy iteration verify):
|
||||
|
||||
| Legacy verify precondition | Milestone-mode replacement |
|
||||
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged (`review status --stage design-space` success) | review-dag converged (`review status --stage review-dag` success) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review; the single review-dag gate replaces it) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | DAG artifact + milestone fan-in slice (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | all milestone fan-in source nodes at terminal state (task source `done` / milestone source `green`, i.e. `all_incoming_done_and_green`) |
|
||||
| code review converged (`pipeline/review-code` success) | ALL fan-in node tickets review-code PASS + PR merged (implied by `done`) |
|
||||
| code review final report exists | REMOVED (no Epic-level final report; per-node review-code reports live on task tickets) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP (unconditional) |
|
||||
| Acceptance criteria exist | from DAG-slice-generated DoD matrix (fan-in node AC + integration/contract-conformance/regression/NFR-coverage items) |
|
||||
| `slug` matches the plan slug | N/A (output naming frozen to `{epic-slug}`) |
|
||||
|
||||
**Phase 1 read inputs** → the DAG slice: read the milestone's fan-in subgraph
|
||||
(fan-in nodes + their cross-session edges + contracts) from the frozen DAG copy
|
||||
`{epic-slug}/dag`, and generate the DoD matrix from it (integration items,
|
||||
contract-conformance items, regression items, NFR-coverage items) instead of
|
||||
reading `04-plan-*` pages.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-milestone-{M-id}` (distinct from
|
||||
iteration verify `05-verify-iteration-{N}`).
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-M-{M-id}` row to the `## 工件索引`
|
||||
comment with 重读 = `ON-DEMAND` (NOT `ARCHIVE`). The milestone verify does NOT
|
||||
edit the comment directly — it reports the row-payload to the aggregator agent
|
||||
(main session/Orchestrator), which is the SINGLE WRITER appending in place
|
||||
(`工单评论 API(见 TERMINOLOGY)`). `ARCHIVE` is never written by milestone verify
|
||||
(Epic close is the sole archive point).
|
||||
|
||||
**Phase 5.5 ACCEPTED_RISK source**: fan-in node task-ticket review-code reports
|
||||
(located in each task ticket's review annotations / `## 当前状态` review row),
|
||||
not an Epic-level final report. A missing Epic-level final report does NOT
|
||||
trigger the "code-review final report does not exist" warn (that warn is
|
||||
legacy-iteration-only). tech-debt / baseline-failure / flaky-test registration
|
||||
proceeds as usual, sourced from the milestone DoD matrix's regression /
|
||||
baseline-classification results.
|
||||
|
||||
**Phase 5.6 milestone mode** (restricted semantics — skip archive-at-close and
|
||||
issue close):
|
||||
|
||||
1. **Checklist final sweep** only — object = each fan-in task ticket's row 6
|
||||
(`verify里程碑`) + the milestone DoD matrix, NOT the Epic body checklist.
|
||||
Verify each fan-in node's row 6 is checked or annotated
|
||||
`_(Pending: M-{M-id} 未 green)_`. Do NOT flip a still-Pending row 6 — that
|
||||
flip belongs to the aggregator agent (main session/Orchestrator), which
|
||||
performs the node-ticket close action. Write the milestone DoD matrix final
|
||||
sweep to `{epic-slug}/05-verify-milestone-{M-id}`.
|
||||
2. **Do NOT fold/remove any Epic-body `## 当前状态` / `## DAG 状态` section** —
|
||||
milestone verify is read-only on Epic body state.
|
||||
3. **SKIP archive-at-close** (the `## 工件索引` archive banner + row-level
|
||||
`ARCHIVE`) and **SKIP issue close** — both belong to the aggregator agent at
|
||||
Epic close.
|
||||
4. **SKIP Tier 1 run archive** (Phase 5.6 step 5, Tier 1 run archive sub-bullet) — the aggregator agent
|
||||
performs it at Epic close.
|
||||
|
||||
**Milestone verify execution context (pinned)**: run the
|
||||
integration/regression/contract-conformance/NFR suite on a checkout CONTAINING
|
||||
all fan-in nodes' merged code — the aggregator agent syncs main (containing the
|
||||
merged fan-in PRs) into the execution worktree, or builds a temp verify worktree
|
||||
from main HEAD, before triggering; the verify report
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` records the actual execution commit
|
||||
SHA.
|
||||
|
||||
**M→green status transition**: NOT done by milestone verify (read-only on Epic
|
||||
body). The aggregator agent (main session/Orchestrator) reads the verify report
|
||||
and sets the aggregator table M row 状态 = `green`, 重读 = `ON-DEMAND`, and
|
||||
syncs the frozen DAG copy `{epic-slug}/dag` node `status` to `green`.
|
||||
|
||||
**Phase 6.5 milestone mode**: vacuous skip — a milestone has no implementation
|
||||
commit. Commit existence is evidenced by the fan-in node verify PASS + PR
|
||||
merged (already implied by `all_incoming_done_and_green`).
|
||||
|
||||
**Milestone verify FAIL recovery**: FAIL → M `status` = `blocked`. Fix
|
||||
responsibility = the fan-in node owning the failing integration/regression item
|
||||
(the last-done fan-in node's session) or the Epic-level session (DAG author) if
|
||||
un-attributable. Re-run is triggered ONLY by a "fix-landed event" (fix commit
|
||||
merged + CI green, or an explicit re-done report from the owning session) —
|
||||
NOT status polling (done nodes are never reset; `all_incoming_done_and_green`
|
||||
stays true after FAIL). M stays `blocked` until a fix event, then returns to
|
||||
`pending` and verify re-runs. No review-dag re-run unless the fix changes a
|
||||
cross-session contract or the node/edge set.
|
||||
|
||||
### Task mode (verify on a task node ticket, because `task_route.keep_gates` includes `verify`)
|
||||
|
||||
Each task ticket closes only after its own verify run, but legacy verify
|
||||
preconditions do not hold in DAG mode — this node-level branch reuses the
|
||||
`verify` skill with the following node-scoped semantics (so the `verify` gate is
|
||||
not silently downgraded to CI-only).
|
||||
|
||||
**Verification object**: the node's own `acceptance_criteria` → the `test_id`
|
||||
suite (`file-path::test-name` / `MANUAL` / `BENCH:`) all passing fresh + that
|
||||
node's review-code PASS recorded + CI green. NOT milestone fan-in
|
||||
integration/contract/regression items (those are milestone verify's). Spec
|
||||
authority = the node in the frozen DAG copy `{epic-slug}/dag`.
|
||||
|
||||
**Precondition replacements** (task mode — mirror the milestone table, scoped to
|
||||
the node):
|
||||
|
||||
| Legacy verify precondition | Task-mode replacement |
|
||||
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged | review-dag converged (this Epic already passed the single gate; do NOT re-run it) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | the node in the frozen DAG copy `{epic-slug}/dag` (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | this node's cross-session in-edge source nodes at terminal state (task source `done` / milestone source `green`) |
|
||||
| code review converged (`pipeline/review-code` success) | this node's ticket review-code PASS + PR merged |
|
||||
| code review final report exists | REMOVED (this node's review-code report lives on the task ticket) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP |
|
||||
| Acceptance criteria exist | from node AC + `test_id` suite |
|
||||
| `slug` matches the plan slug | N/A (Tier 1 run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace review-code runs in and this mode's archive bundle uses below; the Phase 2 precondition-gate cache read MUST use this slug. Only the wiki output naming stays Epic-scoped: `{epic-slug}/05-verify-task-{node-id}`) |
|
||||
|
||||
**Phase 1 read inputs** → the node's AC + `test_id` suite from the frozen DAG
|
||||
copy `{epic-slug}/dag`, generating the DoD matrix.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-task-{node-id}`.
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-TASK-{node-id}` row, 重读 =
|
||||
`ON-DEMAND` (NOT `ARCHIVE`), via the aggregator agent as single writer (task
|
||||
verify does not edit the comment directly).
|
||||
|
||||
**Phase 5.5 task mode**: ACCEPTED_RISK source = this node's task-ticket
|
||||
review-code report (no Epic-level final report → no "does not exist" warn).
|
||||
tech-debt / baseline-failure / flaky-test registration proceeds as usual.
|
||||
|
||||
**Phase 5.6 task mode**: only checklist final sweep — object = this ticket's
|
||||
5-row checklist (NOT row 6 `verify里程碑` — row 6 is flipped ONLY by the
|
||||
aggregator agent). SKIP archive-at-close (`## 工件索引` row-level `ARCHIVE`) and
|
||||
issue close (both belong to the aggregator agent). SKIP Tier 1 run archive — the
|
||||
aggregator agent collects it cross-worktree at task-ticket close (archive to
|
||||
`<runs-root>/archive/{epic-slug}-task-{node-id}.json` and commit to the
|
||||
workflow branch). Do NOT fold Epic body status sections.
|
||||
|
||||
**Phase 6.5 task mode**: object = this node ticket's commit; semantics = "node
|
||||
implementation commit exists". Baseline = the task worktree's creation-commit
|
||||
SHA (`git log {creation-SHA}..HEAD`), NOT a generic base-branch (post-merge
|
||||
there are no new commits vs base). The task worktree is retained until ticket
|
||||
close (the aggregator agent removes it after collecting task-level Tier 1
|
||||
archive); the task session must NOT remove its own worktree.
|
||||
|
||||
**commit status**: still `pipeline/verify` in both modes.
|
||||
|
||||
### No-milestone DAG Epic-level verify gate
|
||||
|
||||
When the routed Epic's DAG has NO milestone (no `cross_session_in ≥ 2`
|
||||
convergence point), the Epic-level `keep_gates: verify` is satisfied
|
||||
AGGREGATELY by all task-ticket verify runs (each with commit status
|
||||
`pipeline/verify` success) — NO independent Epic-level verify run, NO
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` artifact, NO `VERIFY-M-{M-id}` index
|
||||
row. The Epic close condition degenerates to "all task nodes `done`".
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
> Extracted from verify/SKILL.md (section:dag-branch) — moved verbatim; read
|
||||
> on-demand ONLY when the routed Epic is DAG-shaped (frozen DAG at
|
||||
> `{epic-slug}/dag` and `task_route.keep_gates` includes `verify`).
|
||||
|
||||
<!-- section:dag-branch -->
|
||||
## DAG branch (milestone + task modes)
|
||||
|
||||
> This branch OVERRIDES the Preconditions table, Phase 1 read inputs, Phase 5
|
||||
> report index, Phase 5.5 ACCEPTED_RISK source, Phase 5.6 final sweep, and
|
||||
> Phase 6.5 commit gate for a DAG-ticket-pipeline Epic. It applies when the
|
||||
> routed Epic is DAG-shaped: a frozen DAG copy exists at `{epic-slug}/dag` and
|
||||
> the DAG's `task_route.keep_gates` includes `verify`. Legacy iteration verify
|
||||
> (the sections above) remains authoritative for non-DAG iterations. Spec:
|
||||
> `dag-pipeline/spec-05` §5. commit status stays
|
||||
> `pipeline/verify` in both modes.
|
||||
|
||||
### Milestone mode (verify runs on a milestone M when `all_incoming_done_and_green`)
|
||||
|
||||
A milestone node (`type: milestone`) has no implementation work and no ticket;
|
||||
its verify is the integration verification welded at a DAG convergence point
|
||||
(`cross_session_in ≥ 2`). Trigger: the aggregator agent (main
|
||||
session/Orchestrator) detects `all_incoming_done_and_green` — every fan-in
|
||||
source node at its terminal state (task source `done` / milestone source
|
||||
`green`) — and initiates this verify run; the milestone never self-triggers.
|
||||
|
||||
**Precondition replacements** (vs legacy iteration verify):
|
||||
|
||||
| Legacy verify precondition | Milestone-mode replacement |
|
||||
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged (`review status --stage design-space` success) | review-dag converged (`review status --stage review-dag` success) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review; the single review-dag gate replaces it) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | DAG artifact + milestone fan-in slice (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | all milestone fan-in source nodes at terminal state (task source `done` / milestone source `green`, i.e. `all_incoming_done_and_green`) |
|
||||
| code review converged (`pipeline/review-code` success) | ALL fan-in node tickets review-code PASS + PR merged (implied by `done`) |
|
||||
| code review final report exists | REMOVED (no Epic-level final report; per-node review-code reports live on task tickets) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP (unconditional) |
|
||||
| Acceptance criteria exist | from DAG-slice-generated DoD matrix (fan-in node AC + integration/contract-conformance/regression/NFR-coverage items) |
|
||||
| `slug` matches the plan slug | N/A (output naming frozen to `{epic-slug}`) |
|
||||
|
||||
**Phase 1 read inputs** → the DAG slice: read the milestone's fan-in subgraph
|
||||
(fan-in nodes + their cross-session edges + contracts) from the frozen DAG copy
|
||||
`{epic-slug}/dag`, and generate the DoD matrix from it (integration items,
|
||||
contract-conformance items, regression items, NFR-coverage items) instead of
|
||||
reading `04-plan-*` pages.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-milestone-{M-id}` (distinct from
|
||||
iteration verify `05-verify-iteration-{N}`).
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-M-{M-id}` row to the `## 工件索引`
|
||||
comment with 重读 = `ON-DEMAND` (NOT `ARCHIVE`). The milestone verify does NOT
|
||||
edit the comment directly — it reports the row-payload to the aggregator agent
|
||||
(main session/Orchestrator), which is the SINGLE WRITER appending in place
|
||||
(`工单评论 API(见 TERMINOLOGY)`). `ARCHIVE` is never written by milestone verify
|
||||
(Epic close is the sole archive point).
|
||||
|
||||
**Phase 5.5 ACCEPTED_RISK source**: fan-in node task-ticket review-code reports
|
||||
(located in each task ticket's review annotations / `## 当前状态` review row),
|
||||
not an Epic-level final report. A missing Epic-level final report does NOT
|
||||
trigger the "code-review final report does not exist" warn (that warn is
|
||||
legacy-iteration-only). tech-debt / baseline-failure / flaky-test registration
|
||||
proceeds as usual, sourced from the milestone DoD matrix's regression /
|
||||
baseline-classification results.
|
||||
|
||||
**Phase 5.6 milestone mode** (restricted semantics — skip archive-at-close and
|
||||
issue close):
|
||||
|
||||
1. **Checklist final sweep** only — object = each fan-in task ticket's row 6
|
||||
(`verify里程碑`) + the milestone DoD matrix, NOT the Epic body checklist.
|
||||
Verify each fan-in node's row 6 is checked or annotated
|
||||
`_(Pending: M-{M-id} 未 green)_`. Do NOT flip a still-Pending row 6 — that
|
||||
flip belongs to the aggregator agent (main session/Orchestrator), which
|
||||
performs the node-ticket close action. Write the milestone DoD matrix final
|
||||
sweep to `{epic-slug}/05-verify-milestone-{M-id}`.
|
||||
2. **Do NOT fold/remove any Epic-body `## 当前状态` / `## DAG 状态` section** —
|
||||
milestone verify is read-only on Epic body state.
|
||||
3. **SKIP archive-at-close** (the `## 工件索引` archive banner + row-level
|
||||
`ARCHIVE`) and **SKIP issue close** — both belong to the aggregator agent at
|
||||
Epic close.
|
||||
4. **SKIP Tier 1 run archive** (Phase 5.6 step 5, Tier 1 run archive sub-bullet) — the aggregator agent
|
||||
performs it at Epic close.
|
||||
|
||||
**Milestone verify execution context (pinned)**: run the
|
||||
integration/regression/contract-conformance/NFR suite on a checkout CONTAINING
|
||||
all fan-in nodes' merged code — the aggregator agent syncs main (containing the
|
||||
merged fan-in PRs) into the execution worktree, or builds a temp verify worktree
|
||||
from main HEAD, before triggering; the verify report
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` records the actual execution commit
|
||||
SHA.
|
||||
|
||||
**M→green status transition**: NOT done by milestone verify (read-only on Epic
|
||||
body). The aggregator agent (main session/Orchestrator) reads the verify report
|
||||
and sets the aggregator table M row 状态 = `green`, 重读 = `ON-DEMAND`, and
|
||||
syncs the frozen DAG copy `{epic-slug}/dag` node `status` to `green`.
|
||||
|
||||
**Phase 6.5 milestone mode**: vacuous skip — a milestone has no implementation
|
||||
commit. Commit existence is evidenced by the fan-in node verify PASS + PR
|
||||
merged (already implied by `all_incoming_done_and_green`).
|
||||
|
||||
**Milestone verify FAIL recovery**: FAIL → M `status` = `blocked`. Fix
|
||||
responsibility = the fan-in node owning the failing integration/regression item
|
||||
(the last-done fan-in node's session) or the Epic-level session (DAG author) if
|
||||
un-attributable. Re-run is triggered ONLY by a "fix-landed event" (fix commit
|
||||
merged + CI green, or an explicit re-done report from the owning session) —
|
||||
NOT status polling (done nodes are never reset; `all_incoming_done_and_green`
|
||||
stays true after FAIL). M stays `blocked` until a fix event, then returns to
|
||||
`pending` and verify re-runs. No review-dag re-run unless the fix changes a
|
||||
cross-session contract or the node/edge set.
|
||||
|
||||
### Task mode (verify on a task node ticket, because `task_route.keep_gates` includes `verify`)
|
||||
|
||||
Each task ticket closes only after its own verify run, but legacy verify
|
||||
preconditions do not hold in DAG mode — this node-level branch reuses the
|
||||
`verify` skill with the following node-scoped semantics (so the `verify` gate is
|
||||
not silently downgraded to CI-only).
|
||||
|
||||
**Verification object**: the node's own `acceptance_criteria` → the `test_id`
|
||||
suite (`file-path::test-name` / `MANUAL` / `BENCH:`) all passing fresh + that
|
||||
node's review-code PASS recorded + CI green. NOT milestone fan-in
|
||||
integration/contract/regression items (those are milestone verify's). Spec
|
||||
authority = the node in the frozen DAG copy `{epic-slug}/dag`.
|
||||
|
||||
**Precondition replacements** (task mode — mirror the milestone table, scoped to
|
||||
the node):
|
||||
|
||||
| Legacy verify precondition | Task-mode replacement |
|
||||
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
|
||||
| design-space review converged | review-dag converged (this Epic already passed the single gate; do NOT re-run it) |
|
||||
| iteration-plan review converged | REMOVED (DAG has no plan review) |
|
||||
| legacy iteration plan at `{slug}/04-plan-index` | the node in the frozen DAG copy `{epic-slug}/dag` (no `04-plan-*` page) |
|
||||
| legacy NFR targets from `{slug}/03-design-06-non-functional-design` | REMOVED (product NFRs live in node AC, handled by per-task review-code) |
|
||||
| upstream roadmap chunk done+verified | this node's cross-session in-edge source nodes at terminal state (task source `done` / milestone source `green`) |
|
||||
| code review converged (`pipeline/review-code` success) | this node's ticket review-code PASS + PR merged |
|
||||
| code review final report exists | REMOVED (this node's review-code report lives on the task ticket) |
|
||||
| carried items from previous iteration closed | REMOVED (vacuous — no iteration) |
|
||||
| `core/checklists/verification.md` accessible | KEEP |
|
||||
| Acceptance criteria exist | from node AC + `test_id` suite |
|
||||
| `slug` matches the plan slug | N/A (Tier 1 run slug = `{epic-slug}-task-{node-id}` — the same node-task run namespace review-code runs in and this mode's archive bundle uses below; the Phase 2 precondition-gate cache read MUST use this slug. Only the wiki output naming stays Epic-scoped: `{epic-slug}/05-verify-task-{node-id}`) |
|
||||
|
||||
**Phase 1 read inputs** → the node's AC + `test_id` suite from the frozen DAG
|
||||
copy `{epic-slug}/dag`, generating the DoD matrix.
|
||||
|
||||
**Output naming**: `{epic-slug}/05-verify-task-{node-id}`.
|
||||
|
||||
**Phase 5 report index**: append a `VERIFY-TASK-{node-id}` row, 重读 =
|
||||
`ON-DEMAND` (NOT `ARCHIVE`), via the aggregator agent as single writer (task
|
||||
verify does not edit the comment directly).
|
||||
|
||||
**Phase 5.5 task mode**: ACCEPTED_RISK source = this node's task-ticket
|
||||
review-code report (no Epic-level final report → no "does not exist" warn).
|
||||
tech-debt / baseline-failure / flaky-test registration proceeds as usual.
|
||||
|
||||
**Phase 5.6 task mode**: only checklist final sweep — object = this ticket's
|
||||
5-row checklist (NOT row 6 `verify里程碑` — row 6 is flipped ONLY by the
|
||||
aggregator agent). SKIP archive-at-close (`## 工件索引` row-level `ARCHIVE`) and
|
||||
issue close (both belong to the aggregator agent). SKIP Tier 1 run archive — the
|
||||
aggregator agent collects it cross-worktree at task-ticket close (archive to
|
||||
`<runs-root>/archive/{epic-slug}-task-{node-id}.json` and commit to the
|
||||
workflow branch). Do NOT fold Epic body status sections.
|
||||
|
||||
**Phase 6.5 task mode**: object = this node ticket's commit; semantics = "node
|
||||
implementation commit exists". Baseline = the task worktree's creation-commit
|
||||
SHA (`git log {creation-SHA}..HEAD`), NOT a generic base-branch (post-merge
|
||||
there are no new commits vs base). The task worktree is retained until ticket
|
||||
close (the aggregator agent removes it after collecting task-level Tier 1
|
||||
archive); the task session must NOT remove its own worktree.
|
||||
|
||||
**commit status**: still `pipeline/verify` in both modes.
|
||||
|
||||
### No-milestone DAG Epic-level verify gate
|
||||
|
||||
When the routed Epic's DAG has NO milestone (no `cross_session_in ≥ 2`
|
||||
convergence point), the Epic-level `keep_gates: verify` is satisfied
|
||||
AGGREGATELY by all task-ticket verify runs (each with commit status
|
||||
`pipeline/verify` success) — NO independent Epic-level verify run, NO
|
||||
`{epic-slug}/05-verify-milestone-{M-id}` artifact, NO `VERIFY-M-{M-id}` index
|
||||
row. The Epic close condition degenerates to "all task nodes `done`".
|
||||
|
||||
---
|
||||
@@ -0,0 +1,495 @@
|
||||
> Extracted from verify/SKILL.md (phase 5.5 / 5.55 / 5.56 / 5.6) — moved
|
||||
> verbatim; read on-demand during Phase 5 execution, before PASS. Each phase
|
||||
> is mandatory-before-PASS in its trigger condition; the main flow stops at
|
||||
> each boundary until the referenced protocol reports completion.
|
||||
|
||||
<!-- section:phase-5.5 -->
|
||||
### Phase 5.5 — Tech Debt Registry Filing (mandatory before PASS)
|
||||
|
||||
Tech debt is filed **registry-first** (`core/rules/ticket-lifecycle.md`,
|
||||
[TT-3002] G1): new items become ROWS in the source ticket's `## TD 登记` comment;
|
||||
an independent ticket is created only at **promotion** (claim/schedule). There
|
||||
is no `tech-debt.md` file and no `{slug}/tech-debt` wiki page — both remain
|
||||
retired. The registry preserves the three guarantees of the old
|
||||
one-issue-per-item model: visible (the comment lives on a tracker ticket),
|
||||
individually closeable (row-level checkbox), de-duplicated across sessions
|
||||
(the TD index is stronger than title-keyword matching).
|
||||
|
||||
**Sprint-mode override ([TT-3002] G5/[TT-3007])**: read `filing.sprint-mode` from
|
||||
`<instance-root>/workflow-routing.yaml` at the START of this phase (no caching). When
|
||||
`true`, ALL severities file registry-only — registration rows are written as
|
||||
normal (severity included, nothing lost) but promotion to standalone tickets
|
||||
is FROZEN until the switch returns to `false`. Rationale: the 2026-08-12
|
||||
sprint zeroed fix capacity while filing kept running (the 125-fragment
|
||||
backlog's direct trigger); an explicit debt-side downshift beats hoping for
|
||||
discipline. BF/FT phases 5.55/5.56 are NOT covered by this switch — failure
|
||||
evidence must stay immediately visible. Flipping the switch is a human
|
||||
decision recorded on the sprint tracker; semantics in
|
||||
`rules/workflow-routing.md` §立案降档.
|
||||
|
||||
**Adjacency quota ([TT-3002] G3/[TT-3005])**: while collecting inputs, also check the
|
||||
AREAS this iteration touched (packages/modules with commits this iteration).
|
||||
If the source tickets for those areas carry applicable `## TD 登记` rows, at
|
||||
least ONE row must be taken along and disposed this iteration (fixed, or
|
||||
explicitly re-deferred with a reason — silence is not a disposition). Record
|
||||
`consumed X / applicable Y` (or `0 applicable`) in the TD report section;
|
||||
verification checklist §8.4 cross-checks it against the run's debt-quota
|
||||
record (historically the roadmap's per-chunk debt-quota line). This gives debt digestion a steady capacity source tied to
|
||||
touch, not to cleanup campaigns.
|
||||
|
||||
**Promotion quota + pull event ([TT-3061])**: promotion to a standalone ticket
|
||||
requires (a) a **pull event** — the row's Reactivation Trigger fired (state
|
||||
the observed event) OR a named claimer/schedule; "it seemed important" is not
|
||||
a pull event — recorded in the promotion body's `## 拉动事件 / Pull Event`
|
||||
section; and (b) the origin module's OPEN promoted-TD count is below the
|
||||
quota (**default 10** — counted **per origin module**: resolve the row's
|
||||
module from the ticket body's `Origin` field, then count that module's OPEN
|
||||
`tech-debt` tickets; retro §2.10 reports breaches). At or above quota →
|
||||
register-only until the count drops; before each Phase 5.5 promotion
|
||||
re-check the owning module's count, and a row whose module is at or above
|
||||
quota is NOT promoted — defer it and annotate the registry row with
|
||||
`quota-held` (re-checked on the next verify run, retro 2026-08-21). A row
|
||||
marked `[COLD]` by retrospective §2.10
|
||||
(unclaimed >3 retro cycles) promotes only after the pull event clears the
|
||||
mark.
|
||||
|
||||
**Collect inputs** — every tech-debt item to register this iteration:
|
||||
|
||||
1. Every UNVERIFIABLE row in the DoD matrix (Phase 3), with its Reactivation
|
||||
Trigger.
|
||||
2. Every ACCEPTED_RISK finding in the code-review final report
|
||||
(`{slug}/reviews/code/final/report`), with its Recommended Reactivation
|
||||
Trigger.
|
||||
3. Every `[OPEN: <short-id>]` marker the Developer left in code this iteration
|
||||
(per implementation checklist POST-6.2).
|
||||
|
||||
If the code-review final report does not exist, warn the user — ACCEPTED_RISK
|
||||
items cannot be captured. This is itself a process gap that must be flagged.
|
||||
|
||||
**Step 1 — De-duplicate against the registry index and promoted issues.**
|
||||
|
||||
1. Read the source ticket's `## TD 登记` comment (create the comment if this
|
||||
is its first row) and match each candidate against existing rows by
|
||||
`TD-NNN` and reactivation trigger. Same-source re-reporting is the
|
||||
anti-pattern this step exists to prevent (the visual-cluster incident: 18
|
||||
fragments from one source under the old keyword matching).
|
||||
2. Query OPEN promoted tech-debt issues for cross-source duplicates:
|
||||
|
||||
```
|
||||
工单 API 检索(见 TERMINOLOGY)
|
||||
(owner/repo 按实例绑定,labels="tech-debt", state="open")
|
||||
```
|
||||
|
||||
**Step 2 — Assign `TD-NNN` via the ledger mutex ([TT-3322]).** One script call
|
||||
per batch: `bash script/td-alloc.sh <count = new items> <source-slug>
|
||||
[--ticket N]` returns a contiguous range from the TD allocation ledger
|
||||
(append-only comments, earliest-comment-id wins; the seed comment pins the
|
||||
historical floor). Split the returned range across the Step 3 rows in order.
|
||||
**Any allocation — manual included — must land a `**td-alloc**` comment on
|
||||
the ledger before the registry row is written; hand-computed `max + 1` is
|
||||
forbidden** (the 2026-08-24 three-way collision). On exit 5 (retry
|
||||
exhaustion) abort this phase's filing and retry — never hand-assign. The id is **reserved for life**: promotion reuses it, never
|
||||
renumbers. Run `--check` (reconciliation) here if the last check predates
|
||||
this batch.
|
||||
|
||||
**Step 3 — Append one registry row per new item.** Append to the source
|
||||
ticket's `## TD 登记` comment (no source ticket → the owning Epic's tracker
|
||||
ticket; no Epic → the standing `TD 冷存档` tracker):
|
||||
|
||||
```markdown
|
||||
- [ ] TD-{NNN} · {UNVERIFIABLE | ACCEPTED_RISK | DEFERRED} · {HIGH | MEDIUM | LOW}
|
||||
· {origin chunk-id/iter-N} — {one-line summary}
|
||||
· trigger: {objectively verifiable reactivation condition — never "when ready";
|
||||
if no trigger can be defined this is NOT tech debt and the iteration verdict
|
||||
becomes FAIL}
|
||||
```
|
||||
|
||||
**Step 4 — Cross-link (adapted).** The registry comment already lives on the
|
||||
source issue — the source → debt navigation the old body-edit provided. When
|
||||
filing went to an Epic tracker or the 冷存档 (no source ticket), reference the
|
||||
originating slug in each row so the trail survives.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The report's
|
||||
"Tech Debt" section records `TD-NNN → registry row` (source `#NNNN` +
|
||||
`## TD 登记` comment); promoted items record `TD-NNN → #NNNN` as before.
|
||||
|
||||
**Promotion (认领升票) — when a row is scheduled or picked up.** Create the
|
||||
independent ticket THEN, carrying the reserved `TD-NNN`:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Tech debt: {short description} (TD-{NNN})",
|
||||
"body":<promotion template below>,
|
||||
"labels":[tech_debt_label_id, severity_label_id]}
|
||||
```
|
||||
|
||||
- **Severity → label** (reuse the existing exclusive Priority set):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- **Promotion body template** (the pre-[TT-3002] issue template, now used only at
|
||||
promotion):
|
||||
|
||||
```markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue carrying the ## TD 登记 row}
|
||||
|
||||
## Summary
|
||||
|
||||
{one-paragraph description of the debt}
|
||||
|
||||
| Field | Value |
|
||||
| -------- | ------------------------------------------- |
|
||||
| TD ID | TD-{NNN} (reserved at registration) |
|
||||
| Type | {UNVERIFIABLE \| ACCEPTED_RISK \| DEFERRED} |
|
||||
| Origin | {chunk-id/iter-N/phase or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
|
||||
## Reactivation Trigger
|
||||
|
||||
{from the registry row}
|
||||
|
||||
## 拉动事件 / Pull Event
|
||||
|
||||
{trigger fired: {observed event} | claimed by {who} for {when}}
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] {specific action that resolves the debt}
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
- Code review report: `{slug}/reviews/code/final/report` (if ACCEPTED_RISK)
|
||||
```
|
||||
|
||||
- After creating the promoted ticket: tick the registry row (`- [x]`) and
|
||||
append `→ #NNNN` to it.
|
||||
|
||||
If no new tech-debt items were found this iteration, the phase is a no-op —
|
||||
record "0 tech-debt items" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.55 -->
|
||||
### Phase 5.55 — Baseline-Failure Issue Registration (mandatory before PASS when pre-existing failures exist)
|
||||
|
||||
Pre-existing test failures (BF) are tracked as **root-cause family umbrella
|
||||
tickets** (`core/rules/ticket-lifecycle.md`, [TT-3002] G1; precedents [TT-2585]
|
||||
umbrella + [TT-2925] cluster) — one `BF-NNN` ticket per failure-signature family,
|
||||
labeled `baseline-failure`, with each occurrence's evidence attached as
|
||||
comments. There is no `baseline-failures.md` file and no
|
||||
`{slug}/baseline-failures` wiki page. A pre-existing failure does not block
|
||||
the iteration that _discovered_ it (it pre-dates that work), but it MUST be
|
||||
filed against (or into) a family; an un-filed baseline failure is a process
|
||||
gap and the iteration is NOT Done.
|
||||
|
||||
**Birth triage SLA ([TT-3061])**: a BF umbrella is born with `Kind/Bug` (it IS a
|
||||
bug — of the baseline) and must be triaged the SAME DAY it is filed:
|
||||
assigned, scheduled, or explicitly deferred with a reason on the ticket.
|
||||
Untriaged-next-day BF umbrellas are named individually in retro §2.10
|
||||
(compliance %), not averaged away.
|
||||
|
||||
**Collect inputs** — every pre-existing failure to register this iteration:
|
||||
|
||||
1. Every failure classified **pre-existing** in Phase 2.6 (fails on the base
|
||||
branch / last-green commit too).
|
||||
2. Any baseline-run failures noted in the brownfield pre-check (Greenfield vs.
|
||||
Brownfield section).
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [TT-2696]). Query `baseline-failure` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=baseline-failure&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the error/assertion signature
|
||||
plus the affected surface, not just `file::test-name` (one root-cause family
|
||||
may span several tests; several tests failing with the same assertion shape
|
||||
are ONE family). On a signature hit, do NOT create a new ticket: attach the
|
||||
new run evidence (run, commit, failing output, sibling tests observed) as a
|
||||
comment on the FAMILY umbrella ticket. Filing a second ticket inside a known
|
||||
root-cause family is the anti-pattern this phase exists to prevent. If a
|
||||
tracked family is now FIXED by this iteration's work, close its umbrella with
|
||||
a comment citing the fixing commit (a bonus, not a requirement). If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [TT-3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `BF-NNN`** per `core/rules/testing.md`
|
||||
§ "Pre-existing test failures must be filed, not silently logged" (the L1 rule
|
||||
owns the repo-wide sequential numbering invariant — `max + 1`, duplicate ids
|
||||
forbidden incl. closed tickets). `BF-NNN` names the FAMILY; the Gitea issue
|
||||
number `#NNNN` is the tracker handle.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Baseline failure: {test identifier} (BF-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[baseline_failure_label_id, severity_label_id, kind_bug_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Baseline failure: {signature summary} (BF-{NNN})`
|
||||
where `{origin}` is `chunk-{id}/iter-{N}` or the bugfix slug, and
|
||||
`{signature summary}` is the family's error/assertion shape (not a single
|
||||
test name — sibling tests observed later join this umbrella as evidence
|
||||
comments).
|
||||
- **Severity → label** (reuse the existing exclusive Priority set; a failing
|
||||
test defaults to at least MEDIUM, HIGH if on a critical path):
|
||||
|
||||
| Severity | Label |
|
||||
| -------- | ----------------- |
|
||||
| HIGH | `Priority/High` |
|
||||
| MEDIUM | `Priority/Medium` |
|
||||
| LOW | `Priority/Low` |
|
||||
|
||||
- Also attach `Kind/Bug` so the failure is discoverable in the bug tracker
|
||||
alongside manually-reported bugs.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration baseline"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test was already failing before this iteration's work began. It does not
|
||||
block the discovering iteration but must be tracked to closure.
|
||||
|
||||
| Field | Value |
|
||||
| -------------- | ---------------------------------------------- |
|
||||
| BF ID | BF-{NNN} (family) |
|
||||
| Signature | {error/assertion shape} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| First observed | {base commit / date the failure reproduces on} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
git checkout {base commit}
|
||||
(cd <harness-package> && bun test --timeout 120000 {test file}) # or project-equivalent
|
||||
```
|
||||
|
||||
Failing output:
|
||||
|
||||
```
|
||||
{paste the relevant assertion / error}
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The named test passes on a clean checkout of the target branch.
|
||||
- [ ] If the test is deleted/renamed, the replacement covers the same
|
||||
behavior and passes.
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Per the
|
||||
issue-cross-linking rule, every baseline-failure issue MUST link back to its
|
||||
source:
|
||||
|
||||
- The issue body already carries `## Parent` (above).
|
||||
- Update the source/parent issue body to reference each new baseline-failure
|
||||
issue by `#NNNN` in its task list (e.g.
|
||||
`- [ ] #NNNN — BF-{NNN} {test identifier}`), so reviewers can navigate from
|
||||
source → failure.
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`BF-NNN → #NNNN` mapping is written ONLY in the Phase 5 verification report's
|
||||
"Baseline Failures" section (and in the issue title itself). There is no local
|
||||
file to update.
|
||||
|
||||
If no new baseline failures were found this iteration, the phase is a no-op —
|
||||
record "0 baseline failures" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.56 -->
|
||||
### Phase 5.56 — Flaky-Test Issue Registration (mandatory before PASS when flaky tests are unfixed)
|
||||
|
||||
Flaky tests (intermittent pass/fail) are tracked as **root-cause family
|
||||
umbrella tickets** (`core/rules/ticket-lifecycle.md`, [TT-3002] G1) — one
|
||||
`FT-NNN` ticket per failure-signature family, labeled `flaky-test`, with each
|
||||
occurrence's evidence (run count, failure rate, commit) attached as comments.
|
||||
A flaky test that is not fixed within this iteration MUST be filed against
|
||||
(or into) a family; otherwise it evaporates at iteration end and the
|
||||
"compare flaky count against baseline" check (TST-2.5) has no persistent
|
||||
register to compare against. Filing does not block the verdict, but an unfixed
|
||||
flaky test left un-filed is a process gap and the iteration is NOT Done.
|
||||
|
||||
**Expiry SLA ([TT-3061])**: an FT umbrella is born with `Kind/Testing` and a
|
||||
**fix-or-isolate window** (default 7 days) recorded in its body (isolating =
|
||||
quarantining/skipping the test with the family id in the skip reason, which
|
||||
keeps the register comparable). Past the window without fix or isolation, the
|
||||
umbrella is escalated on the ticket (comment naming the owner); retro §2.10
|
||||
reports fix-or-isolate compliance per cycle.
|
||||
|
||||
**Collect inputs** — every flaky test to register this iteration:
|
||||
|
||||
1. Every flaky test surfaced in Phase 2.1 (intermittent pass/fail across
|
||||
reruns) that was NOT fixed by the Developer this iteration.
|
||||
2. Any flaky test carried over from a prior iteration's report that is still
|
||||
intermittently failing.
|
||||
|
||||
**Step 1 — De-duplicate by failure SIGNATURE against existing families (open
|
||||
AND closed), per `core/rules/testing.md`** (de-duplicate BEFORE filing,
|
||||
retro [TT-2696]). Query `flaky-test` issues in ALL states:
|
||||
|
||||
```
|
||||
GET <gitea-base-url>/api/v1/repos/Octopus/octopus/issues?labels=flaky-test&state=all&page=N&limit=50
|
||||
```
|
||||
|
||||
Match each candidate by **failure signature** — the flakiness mode (timeout /
|
||||
race / order-dependence / env-leak) plus the affected surface, not just
|
||||
`file::test-name` (one root cause may flake several tests). On a signature
|
||||
hit, do NOT create a new ticket: attach the new run evidence (run count,
|
||||
failure rate, commit, sibling tests) as a comment on the FAMILY umbrella
|
||||
ticket. Filing a second ticket inside a known root-cause family is the
|
||||
anti-pattern this phase exists to prevent. If a tracked family now passes
|
||||
deterministically, close its umbrella citing the fixing commit. If the query
|
||||
itself errors (API failure — not "no matches"), retry once; on the second
|
||||
failure proceed to file with the literal marker `dedup-unverified` in the
|
||||
umbrella's first evidence comment (query-failure ruling, [TT-3383] — fail-open,
|
||||
visible; rationale in `core/rules/ticket-lifecycle.md`).
|
||||
|
||||
**Step 2 — Assign the next `FT-NNN`** per `core/rules/testing.md`
|
||||
§ "Flaky tests must be filed, not silently tolerated" (the L1 rule owns the
|
||||
repo-wide sequential numbering invariant — `max + 1`, duplicate ids forbidden
|
||||
incl. closed tickets). `FT-NNN` names the FAMILY.
|
||||
|
||||
**Step 3 — Create one umbrella ticket per NEW root-cause family.** Only when
|
||||
no existing family matches the signature:
|
||||
|
||||
```
|
||||
POST <gitea-base-url>/api/v1/repos/Octopus/octopus/issues
|
||||
body: {"title":"[{origin}] Flaky test: {test identifier} (FT-{NNN})",
|
||||
"body":<issue body template below>,
|
||||
"labels":[flaky_test_label_id, severity_label_id, kind_testing_label_id]}
|
||||
```
|
||||
|
||||
- **Title**: `[{origin}] Flaky test: {signature summary} (FT-{NNN})` — the
|
||||
family's flakiness mode + surface (sibling tests join later as evidence
|
||||
comments, not new tickets).
|
||||
- **Severity** → a flaky test defaults to MEDIUM (HIGH if on a critical path
|
||||
or blocking CI); reuse the exclusive Priority set.
|
||||
- Also attach `Kind/Testing` so it is discoverable in the testing tracker.
|
||||
- **Issue body template**:
|
||||
|
||||
````markdown
|
||||
## Parent / 父级
|
||||
|
||||
{#source_issue, or "no source issue — discovered during iteration verification"}
|
||||
|
||||
## Summary
|
||||
|
||||
A test passes and fails intermittently across runs. It undermines the
|
||||
reliability of the suite and must be stabilized or quarantined.
|
||||
|
||||
| Field | Value |
|
||||
| ------------ | ------------------------- |
|
||||
| FT ID | FT-{NNN} (family) |
|
||||
| Signature | {flakiness mode + surface} |
|
||||
| Tests affected | `{file::test-name}`, … (initial members) |
|
||||
| Origin | {chunk-id/iter-N or slug} |
|
||||
| Severity | {HIGH \| MEDIUM \| LOW} |
|
||||
| Failure rate | {e.g. 3/10 runs} |
|
||||
|
||||
## Reproduction
|
||||
|
||||
```
|
||||
for i in $(seq 1 10); do (cd <harness-package> && bun test --timeout 120000 {test file}) || echo "run $i FAILED"; done
|
||||
```
|
||||
|
||||
## Acceptance Criteria (how to close this issue)
|
||||
|
||||
- [ ] The test passes deterministically across 10 consecutive runs.
|
||||
- [ ] If it cannot be stabilized, it is quarantined (`test.skip` /
|
||||
`test.todo` with a comment citing FT-{NNN}) and a stable replacement
|
||||
is filed as tech-debt (TD-NNN).
|
||||
|
||||
## Context
|
||||
|
||||
- Verification report: `{slug}/05-verify-iteration-{N}`
|
||||
````
|
||||
|
||||
**Step 4 — Cross-link to the source issue (mandatory).** Every flaky-test
|
||||
issue links back to its source via `## Parent`, and the source/parent issue
|
||||
task list references each by `#NNNN`
|
||||
(`- [ ] #NNNN — FT-{NNN} {test identifier}`).
|
||||
|
||||
**Step 5 — Record the mapping in the verification report.** The
|
||||
`FT-NNN → #NNNN` mapping is written ONLY in the Phase 5 report's "Flaky Tests"
|
||||
section (and the issue title). No local file.
|
||||
|
||||
If no unfixed flaky tests exist this iteration, the phase is a no-op — record
|
||||
"0 flaky tests" in the report and proceed.
|
||||
|
||||
<!-- section:phase-5.6 -->
|
||||
### Phase 5.6 — Issue Checklist Sync (final sweep, mandatory before PASS)
|
||||
|
||||
This is the **final** checklist sync — the last of the progressive sync
|
||||
points (requirements exit, design exit, plan exit, each iteration commit, PR
|
||||
creation, review convergence, CI transitions, and here — per the sync-point
|
||||
table in `core/rules/issue-checklist-sync.md`). Earlier syncs may have
|
||||
already checked off completed items; this phase catches everything remaining
|
||||
and ensures no `- [ ]` item is left without an annotation.
|
||||
|
||||
1. **Identify the source issue** per `core/rules/issue-checklist-sync.md`
|
||||
§ "How to sync (each point)" step 1 (find `Closes #N` / `Fixes #N` in the
|
||||
PR body or commit messages). If no source issue exists (e.g. standalone
|
||||
bugfix with no tracking issue), skip this phase.
|
||||
2. **Fetch the issue body** via `工单 API(见 TERMINOLOGY)get` (rule step 2).
|
||||
3. **Map every remaining `- [ ]` checklist item** to one of three states:
|
||||
- **Done** (missed by earlier syncs) → mark `- [x]` and append
|
||||
`_(PR #NNN: <file/component>)_`.
|
||||
- **Deferred** → keep `- [ ]` and append `_(Deferred: TD-NNN <reason>)_`.
|
||||
- **Pending** → keep `- [ ]` and append `_(Pending: <blocker>)_`.
|
||||
4. **Fold the `## 当前状态` live-status section** (if present). Rows that have
|
||||
a checklist counterpart (review, process-ACs) are already reflected as
|
||||
checklist annotations at their sync points. Rows with no checklist
|
||||
counterpart in a non-Epic issue (PR opened/merged) are folded as follow-up
|
||||
evidence on the issue narrative (e.g. `_(PR #NNN merged: <summary>)_` on the
|
||||
item it delivered, or in the report). Once every row is accounted for,
|
||||
remove the section from the issue body.
|
||||
5. **archive-at-close: mark the `## 工件索引` comment archived** (归档动作 — [TT-1929]). Issue
|
||||
closing IS the archive-at-close action; it is explicit, not implicit. Edit the index
|
||||
comment in place per `_shared/gitea-write-patterns.md` Pattern 10 Archive-at-close
|
||||
(mechanism — banner + every row's 重读 → ARCHIVE + invariants — is defined there,
|
||||
do not restate; sequence/actor per `rules/issue-checklist-sync.md` § 归档动作).
|
||||
- Skip if no source issue exists.
|
||||
- **Tier 1 run archive** ([TT-1988] two-tier artifacts — only if a Tier 1 run
|
||||
workspace exists): if `<runs-root>/{slug}/` exists (a stage in this run
|
||||
produced Tier 1 local artifacts, e.g. review-code findings), archive the
|
||||
run workspace per `core/rules/two-tier-artifacts.md` § Archive-at-close
|
||||
(the L1 rule is authoritative — do NOT restate its steps here).
|
||||
The archived bundle must pass
|
||||
`core/schemas/runs-bundle.schema.json` validation (the generator
|
||||
validates by default; a red exit blocks close).
|
||||
Verify deltas only: skip in milestone/task DAG mode (the aggregator agent
|
||||
performs it at Epic/task-ticket close — see the DAG branch below).
|
||||
6. **Update the issue body** via `工单 API(见 TERMINOLOGY)update` with the annotated
|
||||
checklist. Preserve all non-checklist content unchanged.
|
||||
7. **Verify**: re-read the issue and confirm no `- [ ]` item lacks an
|
||||
annotation. Every unchecked item MUST have a `(Deferred: ...)` or
|
||||
`(Pending: ...)` note explaining why it is not done.
|
||||
8. **Close the issue** (completes the archive-at-close loop): if the flow has
|
||||
no PR (no `Closes #N` on merge), the Verifier closes the issue after PASS
|
||||
approval via `工单 API(见 TERMINOLOGY)update(state="closed")` — the banner date is
|
||||
corrected to the actual close date if it differs from today. If a PR carries
|
||||
`Closes #N`, the merge closes it; no further action.
|
||||
|
||||
If a checklist item cannot be mapped to evidence, deferral, or pending
|
||||
status, the iteration is NOT Done — the item represents untracked scope.
|
||||
@@ -2,7 +2,7 @@
|
||||
name: writing-skills
|
||||
description: Use ONLY when creating, editing, or evaluating an octopus skill — writing the SKILL.md body, deciding whether a skill needs baseline testing, or running a blind A/B eval of a behavior-shaping technique. Use BEFORE first deployment of any skill that must hold a process gate under pressure.
|
||||
triggers:
|
||||
# High-discrimination phrases only ([org-internal #4525]). We deliberately do NOT use:
|
||||
# High-discrimination phrases only ([TT-4525]). We deliberately do NOT use:
|
||||
# - bare "skill" / 技能 — collides with every skill discussion. Worse: the
|
||||
# hard skill gate folds the previous assistant turn into its match text on
|
||||
# approval turns, so any model reply containing 技能 (e.g. a gate
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| slug / 源 DAG 父级 | `{epic-slug}` / #N(`## 父级 / Parent`;DAG 父级 = `Kind/Epic` 或 `Kind/Feature`,[org-internal #3061] 阶段 2——文中「Epic scope」泛指源工单 scope) |
|
||||
| slug / 源 DAG 父级 | `{epic-slug}` / #N(`## 父级 / Parent`;DAG 父级 = `Kind/Epic` 或 `Kind/Feature`,[TT-3061] 阶段 2——文中「Epic scope」泛指源工单 scope) |
|
||||
| 单门 | `review-dag`(TOPO / REQMAP / RELEASE 三维,深度由 `dag_metrics` 导出) |
|
||||
| 评审深度 | `D1 | D2 | D3 | D4`(`dag_metrics.review_depth`) |
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
> 仅登记功能性需求(Epic scope 项中的功能性条目)。产品 NFR 不占 `REQ-F` 编号、
|
||||
> 不登记入表、以 `NFR:` 前缀条目落节点 AC(见 §3 `acceptance_criteria`)。
|
||||
> 登记表登记的是「提出者写了什么」;§2.1 类目覆盖矩阵补上「还有什么该问的」
|
||||
> ([org-internal #2905]:legacy elicitation 广度扫描被折叠后的补偿层——`表 ↔ 现实` 完备性)。
|
||||
> ([TT-2905]:legacy elicitation 广度扫描被折叠后的补偿层——`表 ↔ 现实` 完备性)。
|
||||
|
||||
| id | title | source | refs_by |
|
||||
|---|---|---|---|
|
||||
| REQ-F-001 | {需求标题} | {Epic scope 项} | {引用节点 id 集} |
|
||||
|
||||
### 2.1 类目覆盖矩阵([org-internal #2905] 方案 1)
|
||||
### 2.1 类目覆盖矩阵([TT-2905] 方案 1)
|
||||
|
||||
> 固定类目集(≤10 类,自 legacy `.octopus/archive/checklists/requirements-analysis.md` CMP/SAF 维抽取)。
|
||||
> 每类目状态 ∈ {已覆盖, 明确排除, 待确认}:
|
||||
@@ -55,7 +55,7 @@
|
||||
| 错误与边界场景(CMP 1.11:空输入/边界值/异常状态,Epic 级;节点级路径覆盖由 REQMAP「AC 路径覆盖」承担) | {已覆盖/明确排除/待确认} | {证据/指针} |
|
||||
| 假设与依赖(CMP 1.9:列出并评估影响) | {已覆盖/明确排除/待确认} | {证据/指针} |
|
||||
|
||||
### 2.2 排除账本([org-internal #2905] 方案 1)
|
||||
### 2.2 排除账本([TT-2905] 方案 1)
|
||||
|
||||
> 「明确排除」的唯一凭证登记处。每行一条 `E-n`:条目 — out of scope、理由、确认人。
|
||||
> 排除可逆:重开时删行并把 §2.1 矩阵状态改为「已覆盖/待确认」,同一次修订内完成。
|
||||
|
||||
@@ -5,17 +5,17 @@ Normative layout for **Tier 1 local structured artifacts**. Authoritative
|
||||
boundary rule: `core/rules/two-tier-artifacts.md`. Schemas that validate
|
||||
the structured files below live in `core/schemas/runs-*.schema.json`.
|
||||
|
||||
This document is the **foundation** (MVP slice, [org-internal #1968]). It defines the
|
||||
This document is the **foundation** (MVP slice, [TT-1968]). It defines the
|
||||
container, the manifest, and the metadata. Stage-specific artifact schemas
|
||||
(design detail dumps, plan items, review dimension findings, synthesis
|
||||
prompts, draft contracts) are added incrementally as each skill migrates its
|
||||
transient output here — the follow-up iteration ([org-internal #1988]) has landed: `review-artifact` /
|
||||
transient output here — the follow-up iteration ([TT-1988]) has landed: `review-artifact` /
|
||||
`audit-process` raw findings and producer working drafts are now Tier 1.
|
||||
([org-internal #3072] phase 3, 2026-08-21: the legacy producer stages whose drafts are listed
|
||||
([TT-3072] phase 3, 2026-08-21: the legacy producer stages whose drafts are listed
|
||||
below were archived — their rows and artifact dirs are kept for reading
|
||||
historical run bundles.) See the migrated stages table below.
|
||||
|
||||
## Kind/MVP mode ([org-internal #3061])
|
||||
## Kind/MVP mode ([TT-3061])
|
||||
|
||||
`Kind/MVP` tickets write **nothing** to `<runs-root>/` by design — no stage
|
||||
dirs, no `index.json`, no manifest. The ticket body is the doc (`## 决策日志`
|
||||
@@ -47,8 +47,8 @@ for human-visible decisions.
|
||||
└── {active-slug}/ # GITIGNORED — one subdir per active run
|
||||
├── meta.json # run metadata (runs-meta.schema.json)
|
||||
├── index.json # artifact manifest (runs-index.schema.json)
|
||||
├── working-notes.md # cross-stage narrative memory ([org-internal #2600], schema-less md)
|
||||
├── workers/ # worker final-return reports ([org-internal #2847], schema-less md —
|
||||
├── working-notes.md # cross-stage narrative memory ([TT-2600], schema-less md)
|
||||
├── workers/ # worker final-return reports ([TT-2847], schema-less md —
|
||||
│ └── ... # see _shared/worker-report-persistence.md)
|
||||
└── {stage}/ # per-stage transient artifacts (added by skills)
|
||||
└── ... # json (structured) / md (prompt files)
|
||||
@@ -61,7 +61,7 @@ for human-visible decisions.
|
||||
- **Gitignored** while active — subagents share the worktree, not the git
|
||||
history, so active-run content stays local (no repo bloat, no merge noise).
|
||||
- **Initialized at run start** by `bun <harness-package>/script/runs-init.ts
|
||||
--slug {slug} --ticket N [--branch …] [--worktree …]` ([org-internal #3642]) — the
|
||||
--slug {slug} --ticket N [--branch …] [--worktree …]` ([TT-3642]) — the
|
||||
producing role / Orchestrator runs the script (hand-writing the files is the
|
||||
legacy path): it creates the `{active-slug}/` workspace, writes `meta.json`
|
||||
with `state: "active"` and the run's slug/branch/worktree/ticket (branch
|
||||
@@ -118,7 +118,7 @@ issue comment: the former is the agent's compact-recovery entry; the latter is
|
||||
the human-visible traceability hub. They are kept in sync by the producing
|
||||
role but serve different consumers.
|
||||
|
||||
### `working-notes.md` — cross-stage narrative memory ([org-internal #2600])
|
||||
### `working-notes.md` — cross-stage narrative memory ([TT-2600])
|
||||
|
||||
`index.json` is a MANIFEST: it records WHAT artifacts exist. It does not
|
||||
carry WHY code was written that way, which paths were tried and abandoned, or
|
||||
@@ -148,7 +148,7 @@ is that narrative memory, in-file, append-only:
|
||||
decision ✓, never referenced cross-worktree ✓, archivable at close ✓ — all
|
||||
four Tier 1 conditions hold (`core/rules/two-tier-artifacts.md` 判据).
|
||||
|
||||
### `workers/` — worker final-return reports ([org-internal #2847])
|
||||
### `workers/` — worker final-return reports ([TT-2847])
|
||||
|
||||
Every worker sub-agent dispatch (`agent: worker` roles — Producer
|
||||
sub-roles, Verifier, Synthesizer) persists its **final return report**
|
||||
@@ -164,7 +164,7 @@ generic name. `index.json` row: `type: "other"`, `schema: null`, `stage` =
|
||||
producing stage, `produced_by` = role. Full convention:
|
||||
`core/skills/_shared/worker-report-persistence.md`.
|
||||
|
||||
### `browser/` — browser evidence packs ([org-internal #4497] N-03)
|
||||
### `browser/` — browser evidence packs ([TT-4497] N-03)
|
||||
|
||||
A browser-debug session writes one evidence pack per session under
|
||||
`browser/{session-id}/` (contract `browser-evidence-4486/shared/pack-manifest-v1`,
|
||||
@@ -204,20 +204,20 @@ Conventions established by this foundation:
|
||||
- A stage that has not yet migrated continues to write to Gitea (Tier 2) per its
|
||||
existing skill body — the two tiers coexist during the migration.
|
||||
|
||||
**Migrated stages ([org-internal #1988]):**
|
||||
**Migrated stages ([TT-1988]):**
|
||||
|
||||
| Stage | Skill | Tier 1 artifacts | Schema | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `review-code` | review-code | `reviews/code/round{N}/findings-{DIM}.json` (raw dimension findings), `reviews/code/round{N}/task-synthesizer.md` (synthesis prompt) | `reviewer-output.schema.json` (findings) | synthesis comment + commit status stay Tier 2 |
|
||||
| `review-roadmap` | review | `reviews/roadmap/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | legacy target archived ([org-internal #3072] phase 3) — row kept for historical bundles |
|
||||
| `review-design-space` | review | `reviews/design-space/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | legacy target archived ([org-internal #3072] phase 3) — row kept for historical bundles |
|
||||
| `review-iteration-plan` | review | `reviews/plan/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | legacy target archived ([org-internal #3072] phase 3) — row kept for historical bundles |
|
||||
| `review-roadmap` | review | `reviews/roadmap/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | legacy target archived ([TT-3072] phase 3) — row kept for historical bundles |
|
||||
| `review-design-space` | review | `reviews/design-space/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | legacy target archived ([TT-3072] phase 3) — row kept for historical bundles |
|
||||
| `review-iteration-plan` | review | `reviews/plan/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | legacy target archived ([TT-3072] phase 3) — row kept for historical bundles |
|
||||
| `review-dag` | review | `reviews/review-dag/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | synthesis comment + commit status stay Tier 2 |
|
||||
| `audit-process` | review | `reviews/audit-process/round{N}/findings-{DIM}.json` | `reviewer-output.schema.json` | synthesis wiki page + commit status stay Tier 2 |
|
||||
| `requirements` (drafts) | requirements-elicitation | `requirements/` (schema-less `.md`/`.json`) | — | legacy skill archived ([org-internal #3072] phase 3) — historical bundles only |
|
||||
| `design` (drafts) | design | `design/` (schema-less or `design-detail.schema.json`) | `design-detail.schema.json` (moved to `<instance-root>/archive/schemas/` [org-internal #3072] phase 3) | legacy skill archived ([org-internal #3072] phase 3) — historical bundles only |
|
||||
| `plan-iterations` (drafts) | plan-iterations | `plan-iterations/` (schema-less or `plan-items.schema.json`) | `plan-items.schema.json` (moved to `<instance-root>/archive/schemas/` [org-internal #3072] phase 3) | legacy skill archived ([org-internal #3072] phase 3) — historical bundles only |
|
||||
| `roadmap` (draft contracts) | roadmap | `roadmap/contracts/{name}.json` | `draft-contract.schema.json` (moved to `<instance-root>/archive/schemas/` [org-internal #3072] phase 3) | legacy skill archived ([org-internal #3072] phase 3) — historical bundles only |
|
||||
| `requirements` (drafts) | requirements-elicitation | `requirements/` (schema-less `.md`/`.json`) | — | legacy skill archived ([TT-3072] phase 3) — historical bundles only |
|
||||
| `design` (drafts) | design | `design/` (schema-less or `design-detail.schema.json`) | `design-detail.schema.json` (moved to `<instance-root>/archive/schemas/` [TT-3072] phase 3) | legacy skill archived ([TT-3072] phase 3) — historical bundles only |
|
||||
| `plan-iterations` (drafts) | plan-iterations | `plan-iterations/` (schema-less or `plan-items.schema.json`) | `plan-items.schema.json` (moved to `<instance-root>/archive/schemas/` [TT-3072] phase 3) | legacy skill archived ([TT-3072] phase 3) — historical bundles only |
|
||||
| `roadmap` (draft contracts) | roadmap | `roadmap/contracts/{name}.json` | `draft-contract.schema.json` (moved to `<instance-root>/archive/schemas/` [TT-3072] phase 3) | legacy skill archived ([TT-3072] phase 3) — historical bundles only |
|
||||
|
||||
Every review/audit stage additionally maintains a per-stage lifecycle file
|
||||
`reviews/{stage}/status.json` (schema `review-status.schema.json`) — live
|
||||
@@ -241,24 +241,24 @@ enters git history:
|
||||
2. Write `archive/{slug}.json` — a compact bundle carrying `meta` + the
|
||||
`index.json` manifest (the durable trace; bulk artifacts are summarized by
|
||||
digest, not copied wholesale, to keep the archive small). One exception
|
||||
([org-internal #2600]): when `working-notes.md` exists, its final content is inlined as
|
||||
([TT-2600]): when `working-notes.md` exists, its final content is inlined as
|
||||
the bundle's top-level `working_notes` field — the narrative memory is the
|
||||
single artifact whose content (not just digest) rides in the bundle,
|
||||
feeding later retro probes and the notes-injection degradation path
|
||||
([org-internal #2601]). The bundle is validated by `runs-bundle.schema.json`.
|
||||
Offline review verifiability (TD/TRC-F006, [org-internal #2688]): for each review stage
|
||||
([TT-2601]). The bundle is validated by `runs-bundle.schema.json`.
|
||||
Offline review verifiability (TD/TRC-F006, [TT-2688]): for each review stage
|
||||
the run executed, also embed a top-level `review_history` entry in the
|
||||
bundle — `{stage, rounds, final_verdict, per_round[]}` (per-round:
|
||||
round/overall_verdict/blockers/majors/minors) — derived from that stage's
|
||||
live `reviews/{stage}/status.json` `history[]`. Closed-run probes can then
|
||||
reconstruct round counts and verdicts from the bundle alone, without the
|
||||
removed workspace or artifact-path reconstruction ([org-internal #2591]).
|
||||
removed workspace or artifact-path reconstruction ([TT-2591]).
|
||||
3. `git add archive/{slug}.json` and commit on the workflow branch (rides into
|
||||
main via the `--no-ff` merge).
|
||||
4. Remove the `{active-slug}/` workspace from the worktree (its durable record
|
||||
now lives in the archive bundle).
|
||||
|
||||
Steps 1–4 collapse into ONE command ([org-internal #3642]): `bash script/archive-run.sh
|
||||
Steps 1–4 collapse into ONE command ([TT-3642]): `bash script/archive-run.sh
|
||||
{slug} [--pr N]` — run from the session worktree, it resolves the PR by branch
|
||||
head, generates + validates the bundle via `gen-run-bundle.ts` (recording
|
||||
`closed_at` / `close_commit_sha` and the `--branch` workflow branch), commits
|
||||
@@ -274,7 +274,7 @@ Gitea tax.
|
||||
|
||||
## Relationship to existing mechanisms
|
||||
|
||||
- **`/tmp/octopus/` embryo** — `review-code` ([org-internal #1988] MVP) now writes its
|
||||
- **`/tmp/octopus/` embryo** — `review-code` ([TT-1988] MVP) now writes its
|
||||
synthesis prompt under `<runs-root>/{slug}/reviews/code/` instead of
|
||||
`/tmp/octopus/synthesis_task_*`. Other skills still using the `/tmp/octopus/`
|
||||
embryo coexist until their own migration iteration.
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
import fs from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, "..")
|
||||
const scriptDir = (import.meta as { dir?: string }).dir
|
||||
?? new URL(".", import.meta.url).pathname
|
||||
const ROOT = path.resolve(scriptDir, "..")
|
||||
const MANIFEST_PATH = path.join(ROOT, "core", "CORE-MANIFEST.json")
|
||||
const CORE_ROOT = path.join(ROOT, "core")
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
import fs from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, "..")
|
||||
const scriptDir = (import.meta as { dir?: string }).dir
|
||||
?? new URL(".", import.meta.url).pathname
|
||||
const ROOT = path.resolve(scriptDir, "..")
|
||||
const CORE_ROOT = path.join(ROOT, "core")
|
||||
const EXEMPT = new Set(["core/schemas/id-aliases.json"])
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
import fs from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, "..")
|
||||
const scriptDir = (import.meta as { dir?: string }).dir
|
||||
?? new URL(".", import.meta.url).pathname
|
||||
const ROOT = path.resolve(scriptDir, "..")
|
||||
const CORE_DIR = path.join(ROOT, "core")
|
||||
|
||||
const SCAN_EXTENSIONS = new Set([".md", ".json", ".ts", ".tsx", ".js", ".mjs", ".cjs", ".yaml", ".yml", ".txt"])
|
||||
|
||||
+23
-3
@@ -3,12 +3,20 @@
|
||||
import fs from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, "..")
|
||||
// Runtime-neutral: works under bun and node>=20.9 (--experimental-strip-types).
|
||||
const scriptDir = (import.meta as { dir?: string }).dir
|
||||
?? new URL(".", import.meta.url).pathname
|
||||
const ROOT = path.resolve(scriptDir, "..")
|
||||
const MANIFEST_PATH = path.join(ROOT, "core", "CORE-MANIFEST.json")
|
||||
const CHECK = process.argv.includes("--check")
|
||||
// --strip: rewrite remaining `[org-internal #NNNN]` annotations to a compact
|
||||
// provenance form `[TT-NNNN]` (org ticket id, non-navigable in the standalone
|
||||
// repo) and fold the wordy placeholder away. Idempotent like the base pass.
|
||||
const STRIP = process.argv.includes("--strip")
|
||||
|
||||
const REF_RE = /\B#(\d{3,5})\b/g
|
||||
const PLACEHOLDER = "org-internal"
|
||||
const STRIP_RE = /\[org-internal[ \t]*#(\d{3,5})\]/g
|
||||
|
||||
interface Mapping {
|
||||
core: string
|
||||
@@ -61,6 +69,16 @@ function transformContent(content: string): { next: string; count: number } {
|
||||
return { next, count }
|
||||
}
|
||||
|
||||
// --strip pass: `[org-internal #NNNN]` → `[TT-NNNN]` (provenance-only ticket id).
|
||||
function stripContent(content: string): { next: string; count: number } {
|
||||
let count = 0
|
||||
const next = content.replace(STRIP_RE, (_match, digits: string) => {
|
||||
count++
|
||||
return `[TT-${digits}]`
|
||||
})
|
||||
return { next, count }
|
||||
}
|
||||
|
||||
export function transformContentForTest(content: string): { next: string; count: number } {
|
||||
return transformContent(content)
|
||||
}
|
||||
@@ -73,7 +91,8 @@ let replacedTotal = 0
|
||||
for (const rel of files) {
|
||||
const fullRel = `core/${rel}`
|
||||
const content = fs.readFileSync(path.join(ROOT, "core", rel), "utf8")
|
||||
const { next, count } = transformContent(content)
|
||||
const result = STRIP ? stripContent(content) : transformContent(content)
|
||||
const { next, count } = result
|
||||
if (count === 0) continue
|
||||
if (byteLocked.has(fullRel)) {
|
||||
deferredLocked.push({ file: fullRel, count })
|
||||
@@ -101,7 +120,8 @@ if (CHECK) {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
console.log(`delink-core: replaced ${replacedTotal} refs across ${perFile.length} file(s)`)
|
||||
const mode = STRIP ? "stripped" : "replaced"
|
||||
console.log(`delink-core: ${mode} ${replacedTotal} refs across ${perFile.length} file(s)`)
|
||||
const top = [...perFile, ...deferredLocked].sort((a, b) => b.count - a.count).slice(0, 10)
|
||||
for (const p of top) console.log(` ${p.file}: ${p.count}`)
|
||||
process.exit(0)
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
# 项目复盘 — wechat-ops 个人微信 GUI 自动化值守 Agent
|
||||
|
||||
> 迭代周期:2026-09-29 一天(迭代0 环境搭建 → 迭代1 五功能 → 迭代2 DAG 就位)
|
||||
> 方法:Loong Workflow 复盘清单(DATA / ANAL / ACT / LOOP / SAFE)
|
||||
> 复盘人:kenyang + ZCode Agent
|
||||
|
||||
---
|
||||
|
||||
## 0. 项目快照
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 交付物 | GitHub + Loong Gitea 双远端 wechat-ops(skILL 包 + 服务器部署版,md5 一致) |
|
||||
| 代码规模 | agent.py ~650 行 + vision.py + setup-server.sh + 守卫脚本 |
|
||||
| 运行状态 | 阿里云 2核2G,auto/draft 值守中,可用内存 ~720Mi |
|
||||
| 版本轨迹 | v0.1.0 初版 → v0.2.x 安全加固 → v0.3.x ima 知识库 → v0.4.x Loong 工作流捆绑 |
|
||||
|
||||
## 1. 数据(DATA)
|
||||
|
||||
**功能交付**:迭代1 五项全部实现并验证(独立Prompt/记忆/群@检测/链接阅读/图标模板匹配);ima OpenAPI 当天逆向对接(官方文档缺字段不一致,实测修正)。
|
||||
|
||||
**真实流量拦截记录**(守卫闸门的实战证据):
|
||||
- 标题核验拦截误发:6+ 次(误定位到 第一财经/大刘家/杨家小极客/张秀英/纯臻群/刘家四兄弟姐妹)
|
||||
- 白名单外跳过:9+ 次(张秀英门店运营群、2组1号、Service Accounts 等)
|
||||
- 群 @ 闸门:未@消息全部仅记录不响应
|
||||
|
||||
**事故清单**(每条有日志/截图证据):
|
||||
1. 私聊消息误发 227 人群(坐标偏移+无核验,用户手动撤回)
|
||||
2. Escape 键打崩微信渲染→透明壳→自愈误判重启→登录会话丢失(被迫重扫码 3 次)
|
||||
3. 定时任务队列被清空且重复触发 20 秒循环(FT 收到 ~50 条测试消息)
|
||||
4. 工单误关 4 张(#6/#7/#8/#9 号映射错误,事后纠正)
|
||||
5. linux-server.md 被存根覆盖丢失 90 行(git 历史恢复)
|
||||
6. ima 官方文档字段与实际 API 不一致(id/name vs kb_id/kb_name)
|
||||
|
||||
## 2. 优点(可复用模式)
|
||||
|
||||
1. **安全闸门代码化且实战有效**:标题核验(空标题拒绝)、白名单、限速、静默、敏感词回退——全部误发被拦,零事故外泄。模式:闸门必须写成函数,不写成散文。
|
||||
2. **自愈状态机**:托盘隐匿/透明壳/登录过期/过渡态保护,一夜之间无人工干预恢复值守。模式:每种故障先做"最坏情况审查"再加处理分支。
|
||||
3. **像素级兜底 + 自学习模板**:FT 图标颜色候选 + 9×9 模板最小距离(校准:真身<10万,误配 270万+),核验成功后自学习存模板。
|
||||
4. **知识库两级接入**:文件导出兜底 + OpenAPI 直连优先,当天完成无官方文档接口的逆向对接(实测修正字段名)。
|
||||
5. **诚实文化**:幻觉试答拒绝发送;错误关票发状态修正评论;证据分级表述(已验证:证据 / 未验证:待确认)。
|
||||
6. **真实用户即时反馈**:群里演示后,当晚有成员尝试部署、有成员购入服务器——开源定位(纯视觉替代付费 Proxy API)得到验证。
|
||||
|
||||
## 3. 缺点与根因(归因流程/工具,不归因个人)
|
||||
|
||||
| # | 缺点 | 根因(流程/工具缺口) |
|
||||
|---|---|---|
|
||||
| 1 | GUI 自动化固有脆弱:窗口自发隐匿、渲染透明壳、Escape 打崩渲染,全天 5+ 次异常 | 微信 Qt 客户端不可控;缺"故障注入"式预防测试,只有事后补丁 |
|
||||
| 2 | 免费视觉模型定位误读(臻→甄、槽位名字偏差),需模板/模糊匹配补丁补偿 | 无离线评测集:视觉提示词从未做过基线测试,每个误读都是第一次见 |
|
||||
| 3 | 定时任务重复触发 20 秒循环,根因未明(run_due_tasks 曾将未到期任务判为 due) | 缺"决策日志→断言"的最小复现方法论;护栏先于根因分析上线,护栏自身又制造新循环 |
|
||||
| 4 | 群发误投事故 | 无"发送目标 dry-run"预检步骤;核验闸门是事故后补的 |
|
||||
| 5 | 工单误关 4 张(映射错误) | 关票动作无"工单号↔标题"双重校验;单人无评审 |
|
||||
| 6 | 文档被存根覆盖 90 行 | 文件同步用 cp 而非 git,缺 pre-commit 保护 |
|
||||
| 7 | 测试污染真实会话(FT ~50 条消息) | 无测试专用会话/账号隔离机制 |
|
||||
|
||||
## 4. 行动项(ACT,≤5,每条有文件路径与完成判据)
|
||||
|
||||
| # | 行动项 | 文件 | 完成判据 |
|
||||
|---|---|---|---|
|
||||
| 1 | N-04:定时任务重复触发复现(利用 save_tasks([]) 溯源栈日志) | scripts/agent.py run_due_tasks | 同一任务 3 次评估仅触发 1 次发送 |
|
||||
| 2 | N-05:白名单 difflib≥0.6 模糊匹配(已实现待回归) + 群名 OCR 变体测试用例集 | scripts/agent.py handle_trigger | 「纯甄AI赋能1688」命中白名单 |
|
||||
| 3 | N-01:图片发送链路(表情包前置) | scripts/agent.py send_image | 测试图片送达 File Transfer |
|
||||
| 4 | 上架前置:守卫脚本增加"凭证/隐私 HARD 扫描"进 CI(双远端推送前自动跑) | scripts/check-skill.sh + Loong Gitea workflow | push 即自动扫描 |
|
||||
| 5 | ima 检索评测集:收集 10 条真实问题-期望文档对,做召回率基线 | references/ima-eval.md(新建) | 召回率报告存在且 ≥8/10 |
|
||||
|
||||
## 5. 闭环(LOOP)
|
||||
|
||||
- 本文写入 loong-workflow 仓库 retrospectives/
|
||||
- ACT#1/#2 相关坑已沉淀 pitfalls-linux.md(#18/#19/#20)
|
||||
- 迭代2 DAG 已发布 Loong Gitea wiki(wechat-ops-iter2/dag),N-01 工单已建(#14)
|
||||
|
||||
## 6. 无指责声明(SAFE)
|
||||
|
||||
所有失误(群发误投、误关工单、文档覆盖、护栏制造循环)归因于:**流程缺口**(无 dry-run、无双人评审、无离线测试集、护栏先于根因分析),不归因于任何人的能力或态度。相应修复均已落入上述 ACT 项。
|
||||
|
||||
## 7. 一句话总结
|
||||
|
||||
**一天内从裸机到开源值守 Agent,安全闸门零失效,但稳定性工程(故障注入测试、离线评测集、双人评审)仍是单人项目的最大短板——这三样是迭代2 的主攻方向。**
|
||||
Reference in New Issue
Block a user