@tea-agent/loop-agent 0.9.0 → 0.10.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/AGENTS.md +8 -0
  2. package/CHANGELOG.md +92 -11
  3. package/README.md +69 -5
  4. package/dist/application/dag/args.js +4 -14
  5. package/dist/application/dag/generate-task-dag.js +32 -2
  6. package/dist/application/dag/run-dag.js +1 -27
  7. package/dist/application/dag/validate-dag.js +2 -2
  8. package/dist/application/loop/run-action.js +0 -4
  9. package/dist/cli/command-definitions.js +7 -11
  10. package/dist/cli/program.js +9 -21
  11. package/dist/commands/cursor-prompt.js +42 -82
  12. package/dist/commands/dag-approve.js +36 -0
  13. package/dist/commands/dag-reconcile-run.js +118 -0
  14. package/dist/commands/delegate.js +75 -77
  15. package/dist/commands/doctor.js +0 -18
  16. package/dist/commands/init.js +60 -40
  17. package/dist/commands/instructions.js +7 -10
  18. package/dist/commands/loop.js +4 -20
  19. package/dist/executors/config-core.js +0 -51
  20. package/dist/executors/dag-pi-executor.js +1 -1
  21. package/dist/executors/dag.js +0 -1
  22. package/dist/executors/index.js +0 -2
  23. package/dist/executors/model-routing.js +9 -9
  24. package/dist/executors/shell-executor.js +1 -1
  25. package/dist/governance/checks.js +6 -3
  26. package/dist/governance/manifest-types.js +33 -2
  27. package/dist/infrastructure/harness/loop-action-store.js +0 -3
  28. package/dist/records/harvest.js +2 -23
  29. package/dist/records/one-shot-runs.js +1 -1
  30. package/dist/shared/artifacts-core.js +24 -5
  31. package/dist/shared/output-truncation.js +37 -0
  32. package/dist/shared/package-metadata.js +353 -0
  33. package/dist/{executors/cursor-executor.js → sidecars/cursor-prompt/executor.js} +2 -42
  34. package/dist/sidecars/cursor-prompt/index.js +3 -0
  35. package/dist/sidecars/cursor-prompt/stream.js +121 -0
  36. package/dist/task/config-types.js +29 -12
  37. package/dist/task/delegate.js +9 -21
  38. package/dist/task/runtime.js +1 -2
  39. package/dist/worker/cli.js +243 -0
  40. package/dist/worker/closeout/apply.js +73 -0
  41. package/dist/worker/closeout/preview.js +30 -0
  42. package/dist/worker/delivery/final-verification.js +194 -0
  43. package/dist/worker/delivery/git-transaction.js +354 -0
  44. package/dist/worker/delivery/package.js +502 -0
  45. package/dist/worker/feature/decision-loader.js +68 -0
  46. package/dist/worker/feature/discover.js +14 -0
  47. package/dist/worker/feature/next-action.js +74 -0
  48. package/dist/worker/feature/reducer.js +133 -0
  49. package/dist/worker/feature/review.js +502 -0
  50. package/dist/worker/feature/run.js +365 -0
  51. package/dist/worker/feature/types.js +1 -0
  52. package/dist/worker/follow-up/approve.js +270 -0
  53. package/dist/worker/follow-up/factory.js +234 -0
  54. package/dist/worker/follow-up/paths.js +25 -0
  55. package/dist/worker/follow-up/policy.js +26 -0
  56. package/dist/worker/follow-up/schema.js +93 -0
  57. package/dist/worker/follow-up/store.js +96 -0
  58. package/dist/worker/loop-agent/loop-agent-client.js +329 -126
  59. package/dist/worker/metrics/projector.js +139 -0
  60. package/dist/worker/observability/read-model.js +282 -15
  61. package/dist/worker/observe/paths.js +17 -5
  62. package/dist/worker/observe/static/app.js +443 -61
  63. package/dist/worker/observe/static/index.html +3 -1
  64. package/dist/worker/observe/static/styles.css +85 -18
  65. package/dist/worker/pool/run-store.js +14 -2
  66. package/dist/worker/pool/validation.js +59 -0
  67. package/dist/worker/preflight.js +49 -1
  68. package/dist/worker/report/morning-report.js +41 -6
  69. package/dist/worker/run-task/run-task.js +23 -13
  70. package/dist/worker/runner/run-ready.js +89 -11
  71. package/dist/worker/task-spec/schema.js +0 -1
  72. package/dist/workflows/dag/convergence/controller.js +1 -1
  73. package/dist/workflows/dag/executor-registry.js +0 -2
  74. package/dist/workflows/dag/governance-profile.js +10 -0
  75. package/dist/workflows/dag/init-hybrid.js +601 -26
  76. package/dist/workflows/dag/lifecycle.js +146 -0
  77. package/dist/workflows/dag/node-execution.js +64 -7
  78. package/dist/workflows/dag/prompt.js +16 -0
  79. package/dist/workflows/dag/report.js +2 -0
  80. package/dist/workflows/dag/runner.js +176 -119
  81. package/dist/workflows/dag/scheduler.js +7 -2
  82. package/dist/workflows/dag/skill-snapshot.js +527 -0
  83. package/dist/workflows/dag/types.js +45 -9
  84. package/dist/workflows/dag/validate.js +5 -8
  85. package/dist/workflows/loop/actions/dag-action.js +0 -2
  86. package/dist/workflows/loop/actions/shared.js +1 -1
  87. package/dist/workflows/loop/actions.js +14 -31
  88. package/dist/workflows/loop/benchmark.js +1 -1
  89. package/dist/workflows/loop/index.js +1 -1
  90. package/dist/workflows/loop/policy/auto-policy.js +22 -14
  91. package/dist/workflows/loop/policy/path-patterns.js +13 -0
  92. package/docs/README.md +35 -16
  93. package/docs/agent-dag-recovery-playbook.md +1 -1
  94. package/docs/architecture/README.md +26 -0
  95. package/docs/architecture/dag-execution.md +134 -0
  96. package/docs/architecture/evolution.md +52 -0
  97. package/docs/architecture/facts-and-state.md +58 -0
  98. package/docs/architecture/runtime-boundaries.md +41 -15
  99. package/docs/architecture/system-overview.md +93 -0
  100. package/docs/architecture/worker-and-feature.md +81 -0
  101. package/docs/cursor-prompt-sidecar.md +36 -0
  102. package/docs/decisions/README.md +13 -1
  103. package/docs/design/README.md +39 -13
  104. package/docs/development-principles.md +1 -1
  105. package/docs/exec-plans/active/README.md +2 -2
  106. package/docs/exec-plans/completed/README.md +14 -1
  107. package/docs/feature-workflow.md +44 -4
  108. package/docs/init-surface.manifest.json +63 -1
  109. package/docs/loop-agent-harness.md +65 -3
  110. package/docs/progress/README.md +27 -0
  111. package/docs/reports/README.md +74 -8
  112. package/docs/skills/README.md +2 -1
  113. package/docs/skills/vetted-skill-registry.md +2 -1
  114. package/docs/templates/agent-dag-report.schema.json +4 -2
  115. package/docs/templates/agent-dag.base.json +0 -5
  116. package/docs/templates/agent-dag.final-verification.json +0 -5
  117. package/docs/templates/agent-dag.schema.json +1 -2
  118. package/docs/templates/agent-dag.supervised-implementation.json +1 -6
  119. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +131 -0
  120. package/docs/templates/backend-test-dag.json +213 -0
  121. package/docs/templates/backend-test-dag.retrospect.prompt.md +128 -0
  122. package/docs/templates/backend-test-dag.review-cases.prompt.md +85 -0
  123. package/docs/templates/frontend-design-contract.md +33 -0
  124. package/docs/templates/frontend-task-constraints.md +25 -0
  125. package/docs/templates/frontend-task-requirement.md +61 -0
  126. package/docs/templates/harness.schema.json +8 -5
  127. package/docs/templates/hybrid-dag.json +1 -6
  128. package/docs/templates/init-evolution-review.md +4 -2
  129. package/docs/templates/interactive-ui-round2-experiment.md +1 -1
  130. package/docs/templates/product-line/task.yaml +0 -1
  131. package/docs/templates/worker-dogfood-evidence.md +28 -0
  132. package/docs/templates/worker-dogfood-setup.md +20 -0
  133. package/docs/verification-matrix.md +17 -0
  134. package/examples/decision-gate-agent-dag.json +87 -33
  135. package/examples/example-dag.json +0 -5
  136. package/examples/hybrid-loop-agent-dag.json +0 -5
  137. package/harness.json +6 -11
  138. package/package.json +22 -44
  139. package/scripts/check-product-line-docs.sh +10 -3
  140. package/skills/agent-worker/SKILL.md +37 -0
  141. package/skills/agent-worker/references/agent-worker-operator.md +43 -0
  142. package/skills/frontend-design-review/SKILL.md +59 -0
  143. package/skills/frontend-design-review/references/review-checklist.md +37 -0
  144. package/skills/frontend-implementation/SKILL.md +48 -0
  145. package/skills/frontend-implementation/references/code-standards.md +34 -0
  146. package/skills/frontend-implementation/references/design-spec.md +46 -0
  147. package/skills/frontend-implementation/references/node-contracts.md +32 -0
  148. package/skills/frontend-review/SKILL.md +53 -0
  149. package/skills/frontend-review/references/review-findings.md +42 -0
  150. package/skills/frontend-verification/SKILL.md +40 -0
  151. package/skills/frontend-verification/references/verification-checklist.md +56 -0
  152. package/skills/grill-me/SKILL.md +10 -0
  153. package/skills/grill-with-docs/SKILL.md +88 -0
  154. package/skills/grill-with-docs/adr-format.md +47 -0
  155. package/skills/grill-with-docs/context-format.md +60 -0
  156. package/skills/init-capability-evolution/SKILL.md +1 -0
  157. package/skills/loop-agent/SKILL.md +11 -9
  158. package/skills/loop-agent/references/command-reference.md +28 -15
  159. package/skills/loop-agent/references/docs-converge.md +126 -0
  160. package/skills/loop-agent/references/harness-policy.md +7 -7
  161. package/skills/loop-agent/references/hybrid-dag.md +13 -15
  162. package/skills/loop-agent/references/long-running-loop.md +4 -6
  163. package/skills/loop-agent/references/multi-worktree.md +6 -6
  164. package/skills/loop-agent/references/orchestrator-and-interventions.md +3 -3
  165. package/skills/loop-agent/references/pi-subagent-assisted-mode.md +14 -11
  166. package/skills/using-git-worktrees/SKILL.md +215 -0
  167. package/dist/commands/cursor-worker.js +0 -43
  168. package/dist/cursor-worker-entry.js +0 -8
  169. package/dist/executors/cursor-artifacts.js +0 -33
  170. package/dist/executors/cursor-execution-log.js +0 -81
  171. package/dist/executors/cursor-executor-artifacts.js +0 -134
  172. package/dist/executors/cursor-run.js +0 -115
  173. package/dist/executors/cursor-tool.js +0 -94
  174. package/dist/executors/cursor-worker-client.js +0 -223
  175. package/dist/executors/cursor-worker-protocol.js +0 -18
  176. package/dist/executors/cursor-worker-server.js +0 -54
  177. package/dist/executors/cursor-worker.js +0 -3
  178. package/dist/executors/cursor.js +0 -6
  179. package/dist/executors/dag-cursor-executor.js +0 -87
  180. package/dist/workflows/loop/actions/cursor-fix.js +0 -191
  181. package/dist/workflows/loop/policy/cursor-fix-policy.js +0 -31
  182. package/docs/cursor-executor-usage.md +0 -25
  183. package/docs/dynamic-workflow-dag-engine-roadmap.md +0 -1749
package/AGENTS.md CHANGED
@@ -17,6 +17,7 @@
17
17
  - 先验证基线,再叠加改动;如果当前基线已坏,优先定位基线问题。
18
18
  - 完成定义必须可验证;不能靠删测试、降标准或模糊描述制造“完成”。
19
19
  - 搜索先于实现;先查现有代码、文档、脚本、测试,避免重复造轮子或误判系统能力。
20
+ - 受治理 Agent runtime 只有 Pi:DAG writer 固定为 `implement-pi` / `repair-pi`;`cursor-prompt` 仅是显式手工 one-shot sidecar,不进入 Loop auto-execute 或 Delegate 自动写入。
20
21
  - 在 DAG runtime 中,搜索/侦察是显式节点:标准路径是 Contract → Scout → Plan → Implement → Verify → Closeout/Handoff。
21
22
  - init surface、runtime 边界、command registry、skill entry 和架构 import 方向是可机器校验的治理契约;相关细节以 `docs/init-surface.manifest.json`、`docs/architecture/runtime-boundaries.md`、`src/cli/command-definitions.ts`、`skills/loop-agent/` 和 `scripts/check-*.sh` 为准,顶层 `AGENTS.md` 只指路,不重复维护事实源。
22
23
  - 本仓库既是 loop-agent 源项目,也是目标项目初始化体验的默认模板;任何新增命令、脚本、文档、skill、模板或发布包内容,都要判断它应由 npm 包内置提供,还是由 `loop-agent init` 投影到目标项目,避免出现“本项目能用、初始化项目缺能力”。
@@ -143,3 +144,10 @@ npm run docs:build
143
144
  - 不要用 stub、假数据通路或注释承诺替代真正交付。
144
145
  - 不要把个人机器的绝对路径写入仓库级 `AGENTS.md`、README、模板或发布包资料;个人工具配置应留在用户级配置或本机会话上下文。
145
146
  - 不要只更新 loop-agent 本仓库体验而遗漏目标项目初始化体验;新增能力如果不能通过 npm 内置资料或 `loop-agent init` 到达目标项目,必须写清原因和替代入口。
147
+
148
+ ## Cursor Cloud specific instructions
149
+
150
+ 这些是 Cursor Cloud VM 上非显而易见、会反复踩的两个环境坑。标准命令仍以 `README.md` 与 `docs/verification-matrix.md` 为准,这里不重复。启动时的 update script 已执行 `nvm use 22` + `npm ci`。
151
+
152
+ - Node 版本:VM 默认 `node`(`/exec-daemon/node`)是 v22.14.0,但可选依赖 `@earendil-works/pi-ai` / `@earendil-works/pi-coding-agent` 要求 Node `>=22.19.0`,否则 `npm install`/`npm ci` 会静默跳过它们,导致 `npm run typecheck` 和 `npm run build` 报 `Cannot find module '@earendil-works/...'`。交互式 shell 默认仍是系统 node,跑任何 `npm install`/`npm ci` 前先执行 `nvm use 22`(已预装 v22.22.2)。
153
+ - Git 提交签名会让 git 密集型测试超时:全局 git 配置默认对每次 commit 用 `cursor-git-ssh-keygen`(`gpg.format=ssh` + `commit.gpgsign=true`)签名,该 helper 会间歇性卡住 7–30s,使 `test/worker/delivery/**`、`test/worker/feature/**` 等在临时仓库里做多次 commit 的用例撞上 15/30s 超时而失败(单独跑却能过)。跑 `npm test` 或任何会频繁 commit 的工作前,先对子进程 git 关闭签名:`export GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=commit.gpgsign GIT_CONFIG_VALUE_0=false`(或在目标仓库 `git config commit.gpgsign false`)。关闭后整套 `npm test` 约 60s 全绿。这只影响本地/测试环境,不改仓库代码。
package/CHANGELOG.md CHANGED
@@ -2,11 +2,88 @@
2
2
 
3
3
  这里记录每个版本对使用者有影响的变化。命令名和配置字段保持原样,其余内容尽量用日常语言说明。
4
4
 
5
- ## [Unreleased]
6
-
7
- ## [0.9.0] - 2026-07-12
8
-
9
- ### 修复
5
+ ## [Unreleased]
6
+
7
+ ### 新增
8
+
9
+ - 新增 `docs/architecture/` 全景、DAG 执行、Worker/Feature、运行态事实与演进五篇主题文档及目录索引,并在 npm package(不投影到 init)内可达。
10
+ - 文档站新增功能导览、架构导读与当前规划入口,intro 改为概念地图和 30 分钟路径;`skills/loop-agent` 增加 docs converge 检查表,Markdown 断链在构建期失败,便于变更后收敛站上文档。
11
+ - `agent-worker` 现在会把实际执行的 `loop-agent` controller 冻结为 schemaVersion 1 identity:记录绝对 launch spec、入口 SHA-256、package version,以及覆盖 `package.json`、`bin/**`、`dist/**`、`skills/**` 的 portable package fingerprint。`feature run`、`feature verify-final` 与 `batch run-ready` 可用 expected version/fingerprint 在任何目标仓库写入前 fail-fast,identity 会进入 Worker、Task Pool、batch/Feature、QA 与最终验证证据。
12
+ - DAG run 在首个节点执行前生成 run-owned resolved skill profile snapshot。普通节点、dynamic map child、loop body、approve 与 resume 都继续使用同一份原始 bytes hash;live skill 后续被修改、删除或补建不会改变当前 run,snapshot 或 binding 被篡改时不会回退实时解析。
13
+ - 源码仓库新增 `npm run self-host:canary -- --deterministic`。它把候选 tarball 安装到隔离 slot,通过候选包绝对入口验证两个 CLI、full init、目标项目治理、Feature dry-run 与 static/shell DAG,并输出包含 tarball hash、package fingerprint、入口 identity、PATH trap 和逐项检查结果的 JSON 证据;维护脚本会独立计算 canonical fingerprint、交叉核对候选实现,并为所有子进程设置硬超时。默认零 Pi,`--live` 尚未开放。
14
+ - 新增可选的 `skills/agent-worker/` outer-loop operator skill,用于 Feature Packet、TaskSpec、Task Pool、controller pinning、自举 candidate canary 和 Worker failure recovery。该 skill 随发布包和 full init 投影到 `skills/` / `.agents/skills/`,不会成为 DAG executor、kernel 或默认 role skill。
15
+
16
+ ### 变更
17
+
18
+ - 根 README 在「核心概念」后增加极简「仓库地图」,方便一眼区分 `src/`、`skills/`、`.harness/`、`docs/` 等职责;细节仍以 `AGENTS.md` 与 `docs/README.md` 为准。
19
+ - 文档治理收敛:站上「当前规划」与 active plan 同步(无进行中计划时明确写出);`docs/README` 只索引核心契约与产物目录入口,progress/report 全量列表下沉到子目录 README;Dynamic Workflow 路线图迁入 `docs/design/`;补齐 design 漏索引与 DAG recovery playbook 入口。
20
+ - 活文档校准:Dynamic Workflow 路线图页首标明已落地 vs 设计输入(Pi-only);六个月规划第 1–2 月改为 archive/reports 指针;`repository-analysis` 冻结为基线快照,新增 `docs/reports/current-capability-summary.md`;落地 ADR 0001–0003(Pi-only、Task Pool 根、双树/docs-converge)。
21
+ - 本仓库样板 Feature Packet `F-2026-001` 从 `dogfood/features/` 迁到根目录 `features/`,与 `F-2026-002` 及产品线约定路径对齐;`scripts/check-product-line-docs.sh` 现与 init 投影脚本一致,扫描 `features/`、`product/features/`、`dogfood/features/`。
22
+ - `features/` 下 Feature Packet 的标题与描述性文案改为中文;YAML key、id、枚举、路径与验证命令保持原样。
23
+ - `dogfood/profile-filter` 的 README、QA 文档、注释与测试标题改为中文;运行时错误串、CLI Usage、fixture 数据与包脚本保持原样,以免破坏断言与 `--test-name-pattern`。
24
+ - `new-task` 不再预种 L1 空报告模板(`分析报告.md` / `实现计划.md` / `复盘报告.md`);任务 `artifacts/` 默认只保留 `修改记录.md` 与 `验证结果.md`,由 `promote-run` 从 completed run 回填。
25
+ - run 启动时仍沿用既有 skill 解析优先级,但解析结果从此属于该 run;任务若把 skill 本身作为交付物修改,新的指令只会在下一次 DAG run 生效。
26
+ - 前端 DAG 的四个 repo-local skills 现在明确规定 contract、scout、plan、implement、design gate、review 和 closeout 的输入、输出、证据与失败规则;组件规范和设计规范预留可追溯的知识库接入 TODO,未接入时只允许使用仓库证据并明确披露缺口。
27
+ - 前端组件与设计规范现在按固定来源链解析:优先连接知识库,未配置、连接/查询失败或无匹配结果时必须检索当前项目 `openSpec/`,命中内容作为当前项目规范并携带路径与章节证据。
28
+
29
+ ### 修复
30
+
31
+ - 前端 DAG 从 `需求.md` / `执行约束.md` 读取验证命令时不再交给 shell 解释执行;命令会先解析为受限参数列表并拒绝 shell 特殊语法,避免任务文本触发额外命令。
32
+
33
+ ## [0.10.0] - 2026-07-12
34
+
35
+ ### 破坏性变更
36
+
37
+ - 受治理 Agent runtime 硬切为 Pi-only:DAG / Loop / Delegate / Worker 不再支持 `executor: "cursor"`、`implement-cursor` / `repair-cursor`、Cursor worker 或 `cursor-fix`。
38
+ - 旧 Cursor DAG、`executors.cursor`、`entrypoints.cursorExecutorUsage`、task `executor` / `cursorModel`、`loopAutoWritePolicy` 会 fail-fast;需要重新生成 Pi-only DAG,并把自动执行策略改为 `loopAutoExecutionPolicy`。
39
+ - 删除 `--no-cursor`、`--allow-cursor-fix`、`cursor-worker` 与 Delegate `--executor` / `--no-auto-run`。Delegate 默认只建 worktree;显式 `--auto-run` 才生成并执行 Pi-only DAG。
40
+ - `@cursor/sdk` 仅可由 `cursor-prompt` sidecar 动态加载;普通 doctor / init / DAG 路径不检查、不要求 Cursor。
41
+
42
+ ### 修复
43
+
44
+ - `cursor-prompt --stream` 超时或异常时会取消仍在运行的 Cursor 请求并释放一次性 Agent,避免残留连接或进程;Delegate `--auto-run` 增加工作树执行链路回归覆盖。
45
+
46
+ ### 迁移提示
47
+
48
+ 1. 删除 harness / task 中的 Cursor runtime 字段,只保留 `executors.pi`。
49
+ 2. 把 `loopAutoWritePolicy` 改为 `loopAutoExecutionPolicy`(`off` | `approval-required` | `enabled`)。
50
+ 3. 重新 `dag run-task` 生成并 `dag validate`;writer 应为 `implement-pi` / `repair-pi`。
51
+ 4. 人工干预继续用 `loop-agent cursor-prompt`;其成功不等于任务完成,仍需显式 shell verification。
52
+
53
+ ### 新增
54
+
55
+ - 严格初始化演化检查现在接受 `Head` 为当前 `HEAD` 可解析祖先提交的报告:只要 `Base` 精确匹配 `--base`、`Head` 是 `HEAD` 或其祖先,且 `reportHead..HEAD` 区间没有新的 `model-review` 高影响路径即可通过。仅 `advisory` 或 `surface-check` 的后续变化不会让已完成的高影响审查失效;`working tree` 等不可解析 Head 与无关历史报告仍被拒绝。
56
+
57
+ - 新增只读的 `agent-worker feature review`。用户无需翻查原始日志,即可查看 Feature 当前状态、主要阻塞、required AC 覆盖、证据位置和下一条建议命令;`--json` 可供脚本稳定消费。
58
+ - 新增 `agent-worker feature run`。它会先校验 Feature 和目标仓库,再复用现有 Worker pipeline 推进一个 Ready Task,随后刷新晨报、Observe snapshot 和 Feature review;`--dry-run` 可在零写入下预览步骤与产物。
59
+ - 新增 ProductBug Follow-up 人工接续流程。`agent-worker task draft-followup` 生成可审查、可去重的修复草稿;`agent-worker feature approve-followup --dry-run` 可先检查变更计划,批准后再新增 FIX Task、重连下游依赖并进入 Ready,同时保留原失败证据。
60
+ - Follow-up 现已覆盖全部失败分类:可执行类生成严格 TaskSpec,Spec/Risk/Human 类生成行动卡,EnvFailure 只有连续两次失败后才建议环境检查任务;审批事务增加多阶段回滚验证,避免 Packet、Ready state、approval 或 index 半写。
61
+ - `agent-worker feature run --git-mode checkpoint` 新增显式授权的本地 Feature 分支事务。成功任务形成带 Feature/Task/AC/run 信息的 checkpoint commit;失败任务保存 patch 与 untracked 证据后恢复 clean。默认仍不 commit,也不会 push、stash、merge 或创建远程 PR。
62
+ - 新增 `agent-worker feature verify-final`、`feature delivery` 与 Feature Closeout。用户可在 clean Delivery HEAD 上生成 canonical QA/最终验证证据,再从 checkpoint、成功 run 和 required AC 形成带 hash 的 Delivery Package、Acceptance Coverage 与 PR 草稿;Closeout 默认预览,只有显式 `--apply --owner` 才原子写回并保留幂等、stale facts 与回滚保护。
63
+ - Morning report 与 Observe 首页新增共享的 Feature Decision Summary,优先显示状态、下一步、原因、证据和 required AC。新增 `agent-worker report metrics --month YYYY-MM`,同时输出带分母、样本量、时间窗口和缺失数据说明的 JSON/Markdown。
64
+ - Observe 总览新增仓库横幅,显示仓库名与绝对路径;KPI 按主要执行链路排列为“Worker 执行”在前、“DAG 运行”在后,DAG 组明确展示活跃运行、执行中/等待节点、暂停和需处理运行,“活跃 Task”更名为“活跃 Worker Task”,每张卡片新增可键盘聚焦的问号帮助,解释数据来源与统计口径。
65
+ - Observe 总览的 Feature 决策仅在存在“运行中”或“需处理”的 Feature 时显示;只有可执行、待验收、已交付或已关闭记录时不再占用总览空间。
66
+
67
+ ### 修改
68
+
69
+ - 根目录 `design/` 已并入 `docs/design/`,视觉参考与产品线设计笔记现在统一从治理文档目录查找,相关索引和引用已同步更新。
70
+ - Agent DAG 的 Pi/Cursor 节点现在默认使用简体中文输出说明、分析、报告和文档;可通过 `workflowPolicy.dag.outputLanguage: "en"` 切换英文,代码、命令、路径、JSON 字段和固定协议 token 不会被翻译。
71
+ - Dashboard 将“运行活性”调整为更直观的“执行器状态”,并明确区分执行器正常、心跳中断、已经退出、其他主机运行以及旧记录没有心跳等情况。
72
+ - 修复 Dashboard 综合 DAG 状态使用中文文案后丢失徽章颜色的问题;完成、失败、暂停、中断和任务已另行完成现在恢复对应的语义颜色。
73
+ - Dashboard 节点耗时达到 60 秒后改为按“分钟 + 秒”显示,例如 `2min 5s`,长任务更容易快速阅读。
74
+ - Dashboard 的 DAG 节点模型列现在会显示 Pi/Cursor 节点实际路由到的模型;历史运行从 `run.json` 模型矩阵推导,新运行会直接把解析后的模型写入节点状态,Shell/Static 节点仍显示 `-`。
75
+ - Dashboard 现在优先展示由生命周期、原始状态和运行活性共同判定的 DAG 当前状态,并单独保留原始记录;新增 `dag reconcile-run`,可在确认执行器已停止后将历史失联 DAG 显式标记为“任务已另行完成”或“已放弃”,同时保存收口前证据。
76
+ - Observe DAG 详情页主信息区精简为单一“状态”,已结束 DAG 不再展示执行器心跳等无意义内部维度,状态一致或不允许恢复/收口时也不再显示“一致”或“否”;不一致、可恢复或可收口的警告与操作能力仍在主视图可见,原始状态、生命周期、活性、状态一致性与恢复资格折叠在“诊断信息”中保留。
77
+ - DAG 运行现在记录本机执行器 PID、主机和持续心跳;`dag status` / `dag doctor` 可区分活跃、节点长时间无活动、心跳停滞、执行器已退出和远端状态未知,Observe 也不会再把已知孤儿或 paused 运行计为活跃 DAG。
78
+ - 节点检查器支持拖动左边缘调整宽度,长 Markdown 表格和输出更容易查看;点击外部空白区域可平滑收起面板。
79
+ - 执行过程改为更清晰的事件轨道:工具调用、AI 回复和 Agent 生命周期更容易区分;没有时间记录时会按采集顺序展示,连续协议事件会自动合并,减少无关噪声。
80
+ - Observe 风险区拆为“需处理 DAG”与“Worker 风险”两个子块;DAG 按运行去重,不会因同一运行同时存在多个异常信号而重复计数,也不会让历史失败记录长期占用当前风险;Snapshot 投影失败不再静默显示为全零健康状态,而是返回安全错误摘要并在总览提示“指标暂不可用”,不含堆栈或敏感信息。
81
+ - 修复旧版(未写 runner 心跳元数据)的运行中 DAG 被 Observe 误判为不活跃的问题:`effectiveStatus=unknown` 只表示活性证据不足,不再覆盖 `lifecycle=active` 且原始 `status` 为 `running`/`pending` 的运行事实,也不再掩盖存在 RUNNING/PENDING 节点的运行。服务端健康计数(活跃运行、执行中节点、等待节点)与前端进行中 DAG 列表现在使用一致的判定语义;`paused`、`terminal`、`stale`、`orphaned` 等明确非活跃事实仍优先于原始 `running`。
82
+ - `npm test` 会先运行可并行的纯测试,再串行运行会启动 CLI 或子进程的集成测试。纯测试会根据机器可用并行度自动选择 1 至 4 个 Worker,低配和高配环境都能在稳定性与速度之间取得更合适的平衡。
83
+
84
+ ## [0.9.0] - 2026-07-12
85
+
86
+ ### 修复
10
87
 
11
88
  - 修复 Observe 总览误把已结束、但仍保留未执行节点的 DAG 显示为“活跃 DAG”的问题。
12
89
  - DAG 详情页中的节点输出、错误输出、依赖图和执行过程会在轮询更新时保留当前查看位置,不再把页面拉回默认位置。
@@ -18,12 +95,12 @@
18
95
  - DAG shell 命令和 Worker 调用遇到大量输出时,只在内存中保留最近一段内容并标明截断;完整 stdout/stderr 仍会写入运行产物,避免长日志拖慢本机。
19
96
  - 建立 reference index 时会跳过依赖、构建产物、虚拟环境和版本控制目录,并在遍历规模过大时提前停止,减少误扫大型仓库。
20
97
 
21
- ### 修改
22
-
23
- - Observe 看板改为暖白运行控制台:总览、批次、Task、DAG 和异常页面使用统一的信息层级;DAG 详情中的依赖图和节点表各自完整展示,选择节点后可从右侧检查器查看输出和执行过程。
24
- - 统一整理运行看板的总览、批次详情、运行详情、DAG 详情和异常 Task 页面:先展示当前状态和风险,再呈现运行记录、输出与产物,桌面端查看信息更集中。
25
- - 最近 DAG 运行改为按时间排列的状态时间线,标题过长时不会再挤压状态;DAG 详情仍可从每条记录直接进入。
26
- - 优化节点表格和宽屏布局:节点 ID、模型、状态、耗时和备注更容易扫读;节点输出支持 Markdown 阅读,完成节点在依赖图中以绿色状态提示。
98
+ ### 修改
99
+
100
+ - Observe 看板改为暖白运行控制台:总览、批次、Task、DAG 和异常页面使用统一的信息层级;DAG 详情中的依赖图和节点表各自完整展示,选择节点后可从右侧检查器查看输出和执行过程。
101
+ - 统一整理运行看板的总览、批次详情、运行详情、DAG 详情和异常 Task 页面:先展示当前状态和风险,再呈现运行记录、输出与产物,桌面端查看信息更集中。
102
+ - 最近 DAG 运行改为按时间排列的状态时间线,标题过长时不会再挤压状态;DAG 详情仍可从每条记录直接进入。
103
+ - 优化节点表格和宽屏布局:节点 ID、模型、状态、耗时和备注更容易扫读;节点输出支持 Markdown 阅读,完成节点在依赖图中以绿色状态提示。
27
104
 
28
105
  ## [0.8.0] - 2026-07-11
29
106
 
@@ -124,6 +201,8 @@
124
201
 
125
202
  ### 新增
126
203
 
204
+ - 新增 `frontend-implementation` 任务类型与专用 Agent DAG 模板,支持前端 contract / scout / design gate / implement / static verify / behavior verify / review gate / closeout 节点链,并附带 repo-local `frontend-implementation` skill 骨架。
205
+ - 补齐前端 DAG 的 repo-local skills:前端实现、design gate review、实现 review 和 verification closeout,并纳入 npm package / `loop-agent init --profile full` 初始化投影。
127
206
  - `loop-agent init` 支持检查和更新已初始化项目,可提示缺失文件、过期配置和需要人工确认的变更。
128
207
  - 新增 `--version`,可直接查看当前安装的 loop-agent 版本。
129
208
  - 初始化内容和 npm 包内容会进行一致性检查,减少“本仓库可用、初始化项目缺文件”的情况。
@@ -142,6 +221,8 @@
142
221
 
143
222
  ### 修复
144
223
 
224
+ - 前端 DAG 的 static / behavior shell 验证会优先使用任务源 `需求.md` / `执行约束.md` 中声明的前端验证命令,避免被通用 adapter 验证命令覆盖。
225
+ - 前端 DAG 节点不再默认注入通用 DAG role skills,改为只加载节点显式声明的前端 skills,避免前端 skill references 被上下文预算挤出。
145
226
  - 修复完整测试运行时,部分真实命令可能因默认超时时间过短而失败的问题。
146
227
 
147
228
  ## [0.2.0] - 2026-07-05
package/README.md CHANGED
@@ -79,6 +79,8 @@ loop-agent dag validate --dag <temp-dir>/<task-id>-dag.json --strict-models --st
79
79
  loop-agent run-dag --dag <temp-dir>/<task-id>-dag.json --cwd .
80
80
  ```
81
81
 
82
+ 当前 `dag run-task` 也支持按 `task.json.taskKind` 选择专用模板;例如 `frontend-implementation` 会生成前端契约、design gate、静态验证、行为验证和 review gate 节点链。
83
+
82
84
  `<temp-dir>` 表示平台原生临时目录;也可以省略 `--output`,再使用命令 JSON 输出里的 `outputPath`。
83
85
 
84
86
  一次性只读评审或有边界写入:
@@ -92,9 +94,42 @@ loop-agent pi-prompt --cwd . --tools read,bash,edit,write,grep,find,ls "<包含
92
94
 
93
95
  ```bash
94
96
  agent-worker task validate-feature <feature-dir>
97
+ agent-worker feature review --feature-dir <feature-dir> --repo <target-repo>
98
+ agent-worker feature run --feature-dir <feature-dir> --repo <target-repo> --dry-run [--git-mode checkpoint]
99
+ agent-worker feature verify-final --feature-dir <feature-dir> --repo <target-repo> --task-id <qa-execute-id>
100
+ agent-worker feature delivery --feature-dir <feature-dir> --repo <target-repo> --qa-evidence <path> --final-verification <path> [--dry-run]
101
+ agent-worker feature closeout --feature-dir <feature-dir> --repo <target-repo> [--apply --owner <owner>]
102
+ agent-worker report metrics --repo <target-repo> --month <YYYY-MM>
103
+ agent-worker task draft-followup <task-id> --worker-run-id <id> --feature-dir <feature-dir> --repo <target-repo>
104
+ agent-worker feature approve-followup --feature-dir <feature-dir> --followup-id <id> --repo <target-repo> --owner <owner> --dry-run
95
105
  bash scripts/worker-nightly.sh <feature-dir> <target-repo> <batch-run-id>
96
106
  ```
97
107
 
108
+ 写入型 Worker 入口会在目标仓库写入前解析并冻结实际启动的 `loop-agent` controller identity。自举或其他需要精确版本约束的批次,可以额外传入:
109
+
110
+ ```bash
111
+ agent-worker feature run \
112
+ --feature-dir <feature-dir> \
113
+ --repo <target-repo> \
114
+ --loop-agent-bin <published-loop-agent-entry> \
115
+ --expected-controller-version <version> \
116
+ --expected-controller-fingerprint <sha256:value>
117
+ ```
118
+
119
+ identity 不只包含 semver,还包含绝对 launch spec、入口 SHA-256,以及覆盖 `package.json`、`bin/**`、`dist/**`、`skills/**` 的 portable package fingerprint。校验失败时会在 materialize、Task Pool `Running` 或其他目标仓库写入前停止,并保留实际 identity 供诊断。
120
+
121
+ `feature review` 是只读的 Feature 级入口。它从 Feature Packet 和现有 Task Pool 事实派生状态、required AC 覆盖、阻塞、证据和唯一主行动;默认输出简洁人类摘要,`--json` 输出稳定的 schemaVersion 1 读模型。它不会写入 Feature Packet 或 Task Pool。
122
+
123
+ `feature verify-final` 在 clean Delivery HEAD 上复用已完成的 `qa-execute` TaskSpec,执行独立、不会 promote/closeout 或移动 HEAD 的最终验证,并原子投影 canonical QA aggregate 与 HEAD-bound final-verification evidence。`feature delivery` 复用 checkpoint transaction,校验 branch/HEAD/clean、commit trailers、changed files、成功 run、QA、最终验证和 required AC 后,在 `.harness/task-pool/` 原子生成 Delivery manifest、Acceptance Coverage 与 `PR.md`;`--dry-run` 零写入。`feature closeout` 默认只预览 gates;显式 `--apply --owner <owner>` 才会在前后校验与整体回滚保护下写入 Feature Closeout,重复相同 facts 会幂等复用。
124
+
125
+ Morning report 和 Observe snapshot/UI 复用同一 Feature reducer,优先展示 Status、Next Action、Why、Evidence。`report metrics` 同时生成 monthly JSON/Markdown,所有比例都包含分子、分母、样本量、UTC 窗口和缺失数据说明。
126
+
127
+ `feature run` 把 validation、目标仓库 preflight、Ready Queue、现有 `run-ready`、晨报、Observe snapshot 和最终 review 串成一次 Feature 意图。默认不写 Git 且每次最多推进一个 Ready 写任务。显式 `--git-mode checkpoint` 才允许创建本地 `agent/<feature-id>` 分支:每个成功任务通过 write-boundary/sensitive-file audit 后提交 checkpoint;失败任务先保存 binary patch、changed/untracked inventory 与内容,再恢复到最近 checkpoint 并验证 clean。它从不授权 push、远程 PR、merge 或 stash。`--keep-failed-diff` 会保留失败 diff、返回 NeedsAction 并立即停止后续任务。
128
+
129
+ 如果 Task 产生业务失败,`feature run` 仍会完成晨报、snapshot 和最终 review,但结果为 `needs-action`、进程退出非零,并保留 batch 与失败证据;无 Ready 时正常退出,并通过 `noReadyReason` 区分已关闭、可交付、待 QA、需人工处理、依赖阻塞或空 Feature。
130
+
131
+ 失败可通过显式 Follow-up 决策闭环接续:ProductBug、TestBug、FlakyTest、DependencyFailure 会生成可批准 Task 草稿;EnvFailure 最近两次连续失败后才生成 `ENV-CHECK-*`,否则优先给出 retry;SpecUnclear、ContractMismatch、RiskyChange、NeedsHuman、Unknown 只生成人工行动卡,绝不进入 Ready。人工用 `feature approve-followup --dry-run` 复核 baseline、证据 hash、ID 冲突和事务计划,再带 `--owner` 批准。批准后新增 TaskSpec、重连下游依赖并进入 Ready;原失败 run/state/handoff 保持不变,重复 run 的新草稿会 supersede 旧 unresolved 草稿但保留历史。
132
+
98
133
  nightly wrapper 按 feature 互斥,保留批次/超时退出码,并输出 morning report、Observe snapshot 和 controller 版本 artifacts。
99
134
 
100
135
  自 0.8.0 起,`.harness/task-pool/` 是唯一受支持的 Task Pool runtime root,其中包含根级 `runs.jsonl`、`events.jsonl`、`states/`、`artifacts/`、`failure-handoffs/`、`observability/` 和 `reports/`。这是 hard cutover:旧路径不读取、不迁移、不合并、不重映射;升级意味着本地 Worker Task Pool 历史重置。
@@ -105,18 +140,37 @@ nightly wrapper 按 feature 互斥,保留批次/超时退出码,并输出 mo
105
140
  - **`.harness/`**:记录 task、DAG run、one-shot run、cache 和 live state 等运行态事实。
106
141
  - **`harness.json`**:描述项目名、治理根目录、模型路由、executor 和验证脚本;`docs/templates/harness.schema.json` 为 IDE 提供补全和字段说明,运行时仍由 Zod schema 校验。
107
142
  - **repo-local skills**:目标项目本地的 `skills/`(loop-agent 主路径)优先于发布包内置 skills,便于项目定制 agent 行为;`init --profile full` 还会把同一份 skills 镜像到 `.agents/skills/`,让外部 agent(如 OpenCode)也能自动发现。DAG skill 解析顺序为:用户配置目录 → `skills/` → `.agents/skills/` → 发布包内置。
143
+ - **run-owned skill snapshot**:新 DAG run 会在任何节点执行前,把本次实际注入 prompt 的 resolved skill profiles 冻结到 run 自己的 `.runtime/skill-snapshot.json`。后续节点、dynamic child、approve/resume 都使用同一份 hash-anchored snapshot;run 内修改 skill 只会从下一次 run 生效。
144
+ - **controller identity**:`agent-worker` 把一次 Feature/batch 实际使用的发布包、入口、启动参数和 package 内容 fingerprint 固定下来,并把 identity 传播到 Worker、Task Pool、batch/Feature 与最终验证证据。
145
+ - **`agent-worker` operator skill**:`skills/agent-worker/` 只负责 Feature Packet、TaskSpec、Task Pool、自举 release train 和失败恢复的外层路由;单个 DAG 实现、DAG kernel 修复和节点执行仍由 `loop-agent` 负责,该 skill 不进入默认 DAG role skills。
108
146
  - **治理文档**:`docs/` 保存原则、工作流、验证矩阵、runtime 边界、计划和报告。
109
147
  - **shell verification**:完成声明必须有可复现命令作为依据,而不是只靠聊天结论。
110
148
 
111
149
  这些治理原则的设计思想吸收了 Anthropic 长时运行 agent harness、OpenAI Codex harness engineering、腾讯端到端 Harness Engineering 和社区 agent harness 实践:人类掌舵,智能体执行;仓库作为记录系统;任务小步推进;用结构化 handoff 与可复现验证跨 session 保持连续性。背景资料收录在 `website/docs/practices/`。
112
150
 
151
+ ## 仓库地图
152
+
153
+ 本仓库按职责分区;更细的开工协议与会话规则见 `AGENTS.md`,治理索引见 `docs/README.md`。
154
+
155
+ | 路径 | 职责 |
156
+ |---|---|
157
+ | `bin/`、`src/` | CLI 入口与运行时代码 |
158
+ | `skills/` | repo-local skill 指令与 references |
159
+ | `.harness/` | task、DAG run、cache、live state 等运行态事实 |
160
+ | `docs/` | 长期治理文档、计划、报告与模板 |
161
+ | `website/` | 面向使用者的文档站 |
162
+ | `scripts/`、`test/` | 验证脚本与测试套件 |
163
+ | `examples/` | 可复制 DAG 示例(默认不投影到目标项目) |
164
+ | `features/`、`dogfood/` | 样板 Feature Packet 与 dogfood 样本(本仓库维护用) |
165
+ | `harness.json`、`AGENTS.md`、`CONTEXT.md` | 项目配置、agent 开工地图与术语表 |
166
+
113
167
  ## 能力概览
114
168
 
115
169
  - 生成、校验、执行和汇总 Agent DAG。
116
170
  - 从任务说明生成标准 DAG,并按依赖顺序运行规划、实现、验证和收口节点。
117
171
  - 维护 `loop` 长程任务状态,包括目标、轮次、信号、验证事实和收口草稿。
118
- - 通过 Pi executor 执行只读规划、评审、诊断和有边界写入。
119
- - 保留 Cursor executor 作为显式启用的可选后端。
172
+ - 通过 Pi executor 执行只读规划、评审、诊断和有边界写入(唯一受治理 Agent writer)。
173
+ - 保留 `cursor-prompt` 作为显式、手工触发的 one-shot sidecar(不是受治理 DAG/Loop writer)。
120
174
  - 通过 shell executor 运行确定性的验证命令。
121
175
  - 检查任务状态、运行态工件、文档链接、skill entry 和 runtime boundary 等治理规则。
122
176
 
@@ -132,7 +186,7 @@ loop-agent examples copy example-dag.json --repo-root <target-repo>
132
186
 
133
187
  ## 迭代本仓库
134
188
 
135
- 如果要用 loop-agent 迭代 loop-agent 本仓库,控制器必须来自已发布的 npm 安装包。不要使用当前工作区的 `npm link` 或 `npm run dev` 作为控制器;首次安装或有意升级可用 `@latest`,但一次自举任务启动后不要在任务中途升级控制器。
189
+ 如果要用 loop-agent 迭代 loop-agent 本仓库,发布版本 N 必须作为整个维护批次的固定 controller,候选版本 N+1 只能在隔离安装槽中接受接棒验证。不要使用当前工作区的 `npm link` 或 `npm run dev` 作为 controller;首次安装或有意升级可用 `@latest`,但一次自举任务启动后不要中途升级或重新通过 PATH 解析入口。
136
190
 
137
191
  ```bash
138
192
  npm install -g @tea-agent/loop-agent@latest
@@ -141,7 +195,17 @@ loop-agent doctor
141
195
  loop-agent run-dag --dag <temp-dir>/<task-id>-dag.json --cwd <repo-root>
142
196
  ```
143
197
 
144
- `@latest` 只用于安装或升级,不要在 DAG 节点里反复用 `npx @latest` 拉取。自举任务应记录 `npm list -g` 显示的实际版本号。
198
+ `@latest` 只用于安装或升级,不要在 DAG 节点里反复用 `npx @latest` 拉取。自举证据应记录 controller version、portable package fingerprint、候选 commit/tarball hash 和失败 run;semver 相同并不代表 package 内容相同。
199
+
200
+ 源码仓库提供 repo-maintainer deterministic takeover canary。它打包候选、安装到临时隔离 slot,由维护脚本独立计算 canonical package fingerprint 并与候选实现交叉核对,再通过候选包内两个绝对入口执行 full init、doctor、inspect、docs audit、目标项目治理检查、Feature validation/dry-run 和一个只含 static/shell executor 的小型 DAG;所有子进程都有硬超时,PATH trap 证明没有回退全局 `loop-agent` / `agent-worker` 命令,run evidence 则证明没有观察到 Pi/model executor:
201
+
202
+ ```bash
203
+ npm run self-host:canary -- --deterministic --output <evidence.json>
204
+ # 或验证已经构建好的候选 tarball
205
+ npm run self-host:canary -- --deterministic --tarball <candidate.tgz> --output <evidence.json>
206
+ ```
207
+
208
+ 该脚本属于源码仓库维护入口,不进入发布包的 `files` surface;`--live` 当前明确拒绝执行。deterministic canary 证明候选包和 static/shell runtime 能接棒,但不会调度 Pi executor,也不承担 Pi skill source 解析证明;run-owned skill snapshot 的候选包解析由 snapshot 定向测试和真实 DAG 证据单独证明。
145
209
 
146
210
  ## 文档导航
147
211
 
@@ -185,7 +249,7 @@ Windows 上运行 `scripts/*.sh` 时使用 Git Bash 或已配置的兼容 Bash
185
249
 
186
250
  ## 发布包内容
187
251
 
188
- 发布包包含静态运行和指导资料:`bin/`、`dist/`、`skills/`、`docs/*.md`、`docs/architecture/runtime-boundaries.md`、`docs/skills/`、`docs/templates/`、`docs/init-surface.manifest.json`、`examples/`、`harness.json`、`AGENTS.md`、`README.md` 和 `CHANGELOG.md`。
252
+ 发布包包含静态运行和指导资料:`bin/`、`dist/`、`skills/`(包括 `loop-agent` 与可选的 `agent-worker` operator skill)、`docs/*.md`、`docs/architecture/runtime-boundaries.md`、`docs/skills/`、`docs/templates/`、`docs/init-surface.manifest.json`、`examples/`、`harness.json`、`AGENTS.md`、`README.md` 和 `CHANGELOG.md`。
189
253
 
190
254
  `docs/progress/`、`docs/reports/`、`docs/exec-plans/`、`docs/decisions/` 等目录下的任务正文是目标仓库实时生成或历史事实;npm 包只携带这些目录的 README,不携带本仓库已有历史记录。
191
255
 
@@ -16,12 +16,11 @@ function parseMaxConcurrent(value) {
16
16
  }
17
17
  export function parseDagRunTaskArgs(args, defaultCwd) {
18
18
  if (args.length === 0) {
19
- throw new Error("usage: dag run-task <task-id> [--output <path>] [--profile auto|minimal|standard|reviewed|supervised] [--strict-models] [--no-cursor] [--execute] [--init-only] [--dry-run] [--cwd <dir>] [--max-concurrent N] [--run-id id] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]]");
19
+ throw new Error("usage: dag run-task <task-id> [--output <path>] [--profile auto|minimal|standard|reviewed|supervised] [--strict-models] [--execute] [--init-only] [--dry-run] [--cwd <dir>] [--max-concurrent N] [--run-id id] [--canvas-path <abs-path> | --canvas <name> [--canvases-dir <dir>]]");
20
20
  }
21
21
  let taskId;
22
22
  let outputPath;
23
23
  let strictModels = false;
24
- let noCursor = false;
25
24
  let execute = false;
26
25
  let initOnly = false;
27
26
  let dryRun = false;
@@ -50,10 +49,6 @@ export function parseDagRunTaskArgs(args, defaultCwd) {
50
49
  strictModels = true;
51
50
  continue;
52
51
  }
53
- if (arg === "--no-cursor") {
54
- noCursor = true;
55
- continue;
56
- }
57
52
  if (arg === "--execute") {
58
53
  execute = true;
59
54
  continue;
@@ -135,7 +130,6 @@ export function parseDagRunTaskArgs(args, defaultCwd) {
135
130
  taskId,
136
131
  outputPath: outputPath ? path.resolve(outputPath) : undefined,
137
132
  strictModels,
138
- noCursor,
139
133
  execute,
140
134
  initOnly,
141
135
  dryRun,
@@ -154,10 +148,11 @@ function parseDagRunTaskProfile(value) {
154
148
  value === "minimal" ||
155
149
  value === "standard" ||
156
150
  value === "reviewed" ||
157
- value === "supervised") {
151
+ value === "supervised" ||
152
+ value === "backend-test") {
158
153
  return value;
159
154
  }
160
- throw new Error(`dag run-task --profile must be one of: auto, minimal, standard, reviewed, supervised; got ${value}`);
155
+ throw new Error(`dag run-task --profile must be one of: auto, minimal, standard, reviewed, supervised, backend-test; got ${value}`);
161
156
  }
162
157
  export function parseDagValidateArgs(args) {
163
158
  if (args.length === 0) {
@@ -257,7 +252,6 @@ export function parseRunDagArgs(args, defaultCwd) {
257
252
  let dryRun = false;
258
253
  let maxConcurrent;
259
254
  let runId;
260
- let noCursor = false;
261
255
  let canvasPath;
262
256
  let canvasName;
263
257
  let canvasesDir;
@@ -288,9 +282,6 @@ export function parseRunDagArgs(args, defaultCwd) {
288
282
  else if (arg === "--run-id") {
289
283
  runId = args[++i];
290
284
  }
291
- else if (arg === "--no-cursor") {
292
- noCursor = true;
293
- }
294
285
  else if (arg === "--canvas-path") {
295
286
  canvasPath = args[++i];
296
287
  }
@@ -335,7 +326,6 @@ export function parseRunDagArgs(args, defaultCwd) {
335
326
  dryRun,
336
327
  maxConcurrent,
337
328
  runId,
338
- noCursor,
339
329
  canvasPath,
340
330
  canvasName,
341
331
  canvasesDir,
@@ -5,6 +5,7 @@ import { parseDagSpec } from "../../workflows/dag/types.js";
5
5
  import { pathMatchesPattern } from "../../shared/git-progress.js";
6
6
  import { loadHarnessManifest } from "../../governance/harness.js";
7
7
  import { defaultHybridDagOutputPath, initHybridDagFromTask, } from "../../workflows/dag/init-hybrid.js";
8
+ import { loadTaskConfig } from "../../task/runtime.js";
8
9
  import { validateDagUseCase } from "./validate-dag.js";
9
10
  import { runDagUseCase } from "./run-dag.js";
10
11
  const PLACEHOLDER_WRITESET_MARKER = "REPLACE/WITH";
@@ -14,7 +15,7 @@ function buildValidateInput(repoRoot, dagPath, parsed) {
14
15
  dagPath,
15
16
  strictModelMatrix: parsed.strictModels,
16
17
  strictGovernance: false,
17
- forbidExecutors: parsed.noCursor ? ["cursor"] : [],
18
+ forbidExecutors: [],
18
19
  };
19
20
  }
20
21
  function shouldRunExecution(parsed) {
@@ -196,6 +197,9 @@ async function resolveProfileRouting(repoRoot, parsed, candidateProfile) {
196
197
  }
197
198
  export async function generateTaskDagUseCase(input) {
198
199
  const { repoRoot, ...parsed } = input;
200
+ const taskConfig = await loadTaskConfig(repoRoot, parsed.taskId);
201
+ const isFrontendImplementationTask = taskConfig.taskKind === "frontend-implementation";
202
+ const isBackendTestTask = taskConfig.taskKind === "backend-test";
199
203
  const candidateResult = await initHybridDagFromTask(repoRoot, parsed.taskId, {
200
204
  outputPath: parsed.outputPath,
201
205
  template: "standard-dag",
@@ -208,6 +212,33 @@ export async function generateTaskDagUseCase(input) {
208
212
  codeChange: [],
209
213
  reasons: ["dag run-task validate did not report governanceProfile"],
210
214
  });
215
+ if (isFrontendImplementationTask) {
216
+ profileRouting.selectedTemplate = "frontend-implementation";
217
+ profileRouting.source = "taskKind";
218
+ profileRouting.routingReasons = [
219
+ 'taskKind "frontend-implementation" selects the dedicated frontend DAG template',
220
+ ];
221
+ if (parsed.profile === "auto") {
222
+ profileRouting.selectedByProfile =
223
+ resolveAutoRoutingProfile(profileRouting.candidateProfile);
224
+ }
225
+ else if (parsed.profileExplicit) {
226
+ profileRouting.selectedByProfile = parsed.profile;
227
+ }
228
+ }
229
+ if (isBackendTestTask) {
230
+ profileRouting.selectedTemplate = "backend-test-dag";
231
+ profileRouting.source = "taskKind";
232
+ profileRouting.routingReasons = [
233
+ 'taskKind "backend-test" selects the dedicated backend test DAG template',
234
+ ];
235
+ if (parsed.profile === "auto") {
236
+ profileRouting.selectedByProfile = "backend-test";
237
+ }
238
+ else if (parsed.profileExplicit) {
239
+ profileRouting.selectedByProfile = parsed.profile;
240
+ }
241
+ }
211
242
  const initResult = profileRouting.selectedTemplate === "standard-dag"
212
243
  ? candidateResult
213
244
  : await initHybridDagFromTask(repoRoot, parsed.taskId, {
@@ -258,7 +289,6 @@ export async function generateTaskDagUseCase(input) {
258
289
  dryRun: parsed.dryRun,
259
290
  maxConcurrent: parsed.maxConcurrent,
260
291
  runId: parsed.runId,
261
- noCursor: parsed.noCursor,
262
292
  canvasPath: parsed.canvasPath,
263
293
  canvasName: parsed.canvasName,
264
294
  canvasesDir: parsed.canvasesDir,
@@ -1,30 +1,8 @@
1
- import { readFile } from "node:fs/promises";
2
1
  import { createDagEventObserver } from "../../workflows/dag/event-observer.js";
3
2
  import { composeDagRunObservers } from "../../workflows/dag/observer-compose.js";
4
3
  import { createDagCanvasObserver, resolveCanvasPath, } from "../../workflows/dag/canvas-observer.js";
5
4
  import { loadDagSpecFromFile, runDag } from "../../workflows/dag/runner.js";
6
- import { assertValidDagSpec, collectForbiddenExecutorIssues, } from "../../workflows/dag/validate.js";
7
- async function loadRawTaskExecutorMap(dagPath) {
8
- const raw = JSON.parse(await readFile(dagPath, "utf-8"));
9
- const map = new Map();
10
- for (const task of raw.tasks ?? []) {
11
- if (typeof task.id === "string")
12
- map.set(task.id, task.executor);
13
- }
14
- return map;
15
- }
16
- function assertNoCursorTasks(spec, rawTaskExecutors) {
17
- const issues = collectForbiddenExecutorIssues(spec, ["cursor"]);
18
- if (issues.length === 0)
19
- return;
20
- const details = issues
21
- .map((issue) => {
22
- const implicitDefault = rawTaskExecutors.get(issue.taskId) === undefined;
23
- return `task=${issue.taskId}${implicitDefault ? " (implicit cursor default)" : ""}`;
24
- })
25
- .join("; ");
26
- throw new Error(`--no-cursor forbids cursor executor tasks: ${details}`);
27
- }
5
+ import { assertValidDagSpec } from "../../workflows/dag/validate.js";
28
6
  function getCanvasFlushErrorMessage(error) {
29
7
  return error instanceof Error ? error.message : String(error);
30
8
  }
@@ -50,10 +28,6 @@ function buildRunDagNextSteps(runId) {
50
28
  }
51
29
  export async function runDagUseCase(input) {
52
30
  const spec = await loadDagSpecFromFile(input.dagPath);
53
- if (input.noCursor) {
54
- const rawTaskExecutors = await loadRawTaskExecutorMap(input.dagPath);
55
- assertNoCursorTasks(spec, rawTaskExecutors);
56
- }
57
31
  assertValidDagSpec(spec);
58
32
  const resolvedCanvasPath = resolveCanvasPath({
59
33
  canvasPath: input.canvasPath,
@@ -51,7 +51,7 @@ async function loadRawTaskExecutorMap(dagPath) {
51
51
  return map;
52
52
  }
53
53
  function ensureNoForbiddenExecutors(spec, forbidExecutors, rawTaskExecutors) {
54
- const supported = new Set(["cursor", "pi", "shell", "static"]);
54
+ const supported = new Set(["pi", "shell", "static"]);
55
55
  const normalized = forbidExecutors.map((executor) => {
56
56
  if (!supported.has(executor)) {
57
57
  throw new Error(`unsupported executor for --forbid-executor: ${executor}`);
@@ -72,7 +72,7 @@ function ensureNoForbiddenExecutors(spec, forbidExecutors, rawTaskExecutors) {
72
72
  async function ensureStrictSkillResolution(spec, repoRoot) {
73
73
  const failures = [];
74
74
  for (const task of spec.tasks) {
75
- if (task.executor !== "pi" && task.executor !== "cursor")
75
+ if (task.executor !== "pi")
76
76
  continue;
77
77
  const skills = resolveDagNodeSkills(spec, task);
78
78
  if (skills.length === 0)
@@ -1,4 +1,3 @@
1
- import { runLoopCursorFix } from "../../workflows/loop/actions/cursor-fix.js";
2
1
  import { runLoopDagAction } from "../../workflows/loop/actions/dag-action.js";
3
2
  import { runLoopPiReview } from "../../workflows/loop/actions/pi-review.js";
4
3
  import { runLoopShellVerification, } from "../../workflows/loop/actions/shell-verify.js";
@@ -10,9 +9,6 @@ export async function runLoopAction(input) {
10
9
  if (input.action === "pi-review") {
11
10
  return runLoopPiReview(input.repoRoot, input.taskId, input.options);
12
11
  }
13
- if (input.action === "cursor-fix") {
14
- return runLoopCursorFix(input.repoRoot, input.taskId, input.options);
15
- }
16
12
  if (input.action === "dag") {
17
13
  return runLoopDagAction(input.repoRoot, input.taskId, input.options);
18
14
  }
@@ -29,13 +29,13 @@ import { runDagWorkflowPlan } from "../commands/dag-workflow-plan.js";
29
29
  import { runDagApprove } from "../commands/dag-approve.js";
30
30
  import { runDagReject } from "../commands/dag-reject.js";
31
31
  import { runDagReconcileTasks } from "../commands/dag-reconcile-tasks.js";
32
+ import { runDagReconcileRun } from "../commands/dag-reconcile-run.js";
32
33
  import { runDagResume } from "../commands/dag-resume.js";
33
34
  import { runDagDecisionInspect, runDagDecisionValidate, } from "../workflows/dag/decision-envelope.js";
34
35
  import { runDagDoctor, runDagStatus } from "../workflows/dag/lifecycle.js";
35
36
  import { runDagRunTask } from "../commands/dag-run-task.js";
36
37
  import { runDagCloseoutDraft, runDagReport } from "../commands/dag-report.js";
37
38
  import { runDagFinalVerification } from "../commands/dag-final-verification.js";
38
- import { runCursorWorker } from "../commands/cursor-worker.js";
39
39
  import { runKnowledge } from "../commands/knowledge.js";
40
40
  import { runLoopBenchmark } from "../commands/loop-benchmark.js";
41
41
  import { runPiReuseBenchmark } from "../commands/pi-reuse-benchmark.js";
@@ -81,6 +81,7 @@ const DAG_SUBCOMMANDS = [
81
81
  "doctor",
82
82
  "report",
83
83
  "closeout-draft",
84
+ "reconcile-run",
84
85
  "reconcile-tasks",
85
86
  "final-verification",
86
87
  "decision",
@@ -391,16 +392,6 @@ export const COMMAND_DEFINITIONS = [
391
392
  await runHarvest(repoRoot, harvestArgs);
392
393
  },
393
394
  },
394
- {
395
- name: "cursor-worker",
396
- adapter: "required",
397
- tier: "escape-hatch",
398
- intent: "Inspect or control the optional Cursor SDK worker process.",
399
- usage: "cursor-worker <status|stop|ping>",
400
- handler: async ({ repoRoot, subcommand, rest }) => {
401
- await runCursorWorker(repoRoot, [subcommand, ...rest].filter((arg) => Boolean(arg)));
402
- },
403
- },
404
395
  {
405
396
  name: "knowledge",
406
397
  adapter: "required",
@@ -485,6 +476,11 @@ export const COMMAND_DEFINITIONS = [
485
476
  await runDagCloseoutDraft(repoRoot, closeoutArgs);
486
477
  return;
487
478
  }
479
+ if (subcommand === "reconcile-run") {
480
+ const reconcileRunArgs = rest.filter((arg) => Boolean(arg));
481
+ await runDagReconcileRun(repoRoot, reconcileRunArgs);
482
+ return;
483
+ }
488
484
  if (subcommand === "reconcile-tasks") {
489
485
  const reconcileArgs = rest.filter((arg) => Boolean(arg));
490
486
  await runDagReconcileTasks(repoRoot, reconcileArgs);