@tea-agent/loop-agent 0.41.1-beta.0 → 0.42.0-next.1

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 (273) hide show
  1. package/CHANGELOG.md +61 -207
  2. package/dist/adapters/context-transfer/optional-pi-handoff.js +31 -0
  3. package/dist/adapters/context-transfer/pi-session.js +61 -0
  4. package/dist/application/dag/generate-task-dag.js +19 -75
  5. package/dist/application/task-lifecycle/advance.js +5 -24
  6. package/dist/application/task-lifecycle/observe.js +17 -171
  7. package/dist/application/task-lifecycle/plan-transitions.js +7 -42
  8. package/dist/application/task-lifecycle/recommendations.js +2 -13
  9. package/dist/build-stamp.json +3 -3
  10. package/dist/cli/command-definitions.js +12 -7
  11. package/dist/cli/program.js +23 -6
  12. package/dist/commands/client-recovery.js +0 -3
  13. package/dist/commands/dag-artifact.js +284 -0
  14. package/dist/commands/dag-context.js +184 -0
  15. package/dist/commands/dag-rerun.js +206 -1
  16. package/dist/commands/init.js +1 -27
  17. package/dist/commands/task-advance.js +0 -19
  18. package/dist/executors/dag-pi-executor.js +266 -3792
  19. package/dist/executors/pi-executor.js +4 -15
  20. package/dist/executors/pi-sdk-executor.js +3 -0
  21. package/dist/executors/shell-executor.js +217 -945
  22. package/dist/executors/shell-write-guard.js +0 -7
  23. package/dist/{worker → infrastructure}/console/app-data.js +4 -0
  24. package/dist/infrastructure/console/artifact-revision-store.js +430 -0
  25. package/dist/infrastructure/console/context-export-store.js +160 -0
  26. package/dist/infrastructure/console/dir-lock.js +132 -0
  27. package/dist/infrastructure/console/operation-store.js +197 -0
  28. package/dist/infrastructure/harness/artifact-store.js +10 -1
  29. package/dist/infrastructure/harness/atomic-write.js +12 -2
  30. package/dist/shared/context-transfer/artifact-revision.js +172 -0
  31. package/dist/shared/context-transfer.js +418 -0
  32. package/dist/shared/dag-failure-category.js +0 -12
  33. package/dist/shared/openspec-spec.js +4 -70
  34. package/dist/shared/operator/capabilities.js +14 -7
  35. package/dist/shared/operator/safe-run-summary.js +1 -0
  36. package/dist/shared/path-safety.js +93 -0
  37. package/dist/shared/preview.js +28 -4
  38. package/dist/task/config-types.js +9 -35
  39. package/dist/task/contract/adopt.js +0 -4
  40. package/dist/task/contract/import-revision.js +0 -4
  41. package/dist/task/contract/project.js +0 -3
  42. package/dist/task/contract/schema.js +1 -2
  43. package/dist/task/frontend-project-capability.js +20 -203
  44. package/dist/task/runtime.js +2 -5
  45. package/dist/task/source-prepare/build-draft.js +3 -3
  46. package/dist/task/source-prepare/fragment-inventory.js +9 -15
  47. package/dist/task/source-prepare/prepare.js +1 -89
  48. package/dist/task/source-prepare/semantic-intake.js +2 -6
  49. package/dist/task/source-references.js +1 -22
  50. package/dist/task/task-demand-routing.js +3 -0
  51. package/dist/worker/console/chat/chat-event-store.js +2 -2
  52. package/dist/worker/console/chat/pi-runtime.js +3 -2
  53. package/dist/worker/console/chat/resource-preferences-store.js +1 -1
  54. package/dist/worker/console/chat/routes.js +13 -4
  55. package/dist/worker/console/chat/semantic-activity.js +12 -11
  56. package/dist/worker/console/chat/session-stats.js +96 -0
  57. package/dist/worker/console/chat/session-store.js +1 -1
  58. package/dist/worker/console/chat/turn-process.js +28 -4
  59. package/dist/worker/console/chat/user-questions.js +1 -1
  60. package/dist/worker/console/console-update-runtime.js +1 -1
  61. package/dist/worker/console/context-transfer-diagnostics.js +198 -0
  62. package/dist/worker/console/dag-confirmation.js +1 -1
  63. package/dist/worker/console/dag-execution-receipt.js +1 -1
  64. package/dist/worker/console/doctor.js +1 -1
  65. package/dist/worker/console/draft-store.js +1 -1
  66. package/dist/worker/console/human-gate-token.js +1 -1
  67. package/dist/worker/console/index.js +3 -6
  68. package/dist/worker/console/interview/assessment.js +1 -1
  69. package/dist/worker/console/interview/session.js +1 -1
  70. package/dist/worker/console/operation-runner.js +45 -4
  71. package/dist/worker/console/operation-sse.js +1 -1
  72. package/dist/worker/console/operation-wait.js +1 -1
  73. package/dist/worker/console/operator-actions.js +107 -168
  74. package/dist/worker/console/operator-surface-health.js +1 -1
  75. package/dist/worker/console/operator-user-error.js +169 -0
  76. package/dist/worker/console/pi-plugins.js +60 -1
  77. package/dist/worker/console/routes.js +637 -8
  78. package/dist/worker/console/security.js +35 -0
  79. package/dist/worker/console/server.js +6 -6
  80. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Bho4we4c.js → abnfDiagram-N423BO3Z-DZZ8m3PO.js} +1 -1
  81. package/dist/worker/console/static/assets/{arc-TBDkTeK0.js → arc-D6PvaVd-.js} +1 -1
  82. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-BF_fZrn2.js → architectureDiagram-T3A2C74G-B_OTOiI8.js} +1 -1
  83. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CCnPgUe2.js → blockDiagram-VBNYF7ZC-Bv6rqHBg.js} +1 -1
  84. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BCYZJLAT.js → c4Diagram-5PPSVZJV-B8eHr0oz.js} +1 -1
  85. package/dist/worker/console/static/assets/channel-BU5gOilw.js +1 -0
  86. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-D8K6adhU.js → chunk-2GRJ4B5K-DYwR0im2.js} +1 -1
  87. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DkT1Q78b.js → chunk-2Q5K7J3B-D2WPGqXt.js} +1 -1
  88. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DuhvpIr7.js → chunk-5RXB4S5H-CQISJ_I7.js} +1 -1
  89. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BnK6dC49.js → chunk-5VM5RSS4-C0o2Du1e.js} +1 -1
  90. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DPz__z7r.js → chunk-6Q2QTUOP-4f8kr-U7.js} +1 -1
  91. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-0kkppM2j.js → chunk-GF5L2VYU-D_OWvXzX.js} +1 -1
  92. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BB41iK5t.js → chunk-JWPE2WC7-CasdPz5X.js} +1 -1
  93. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CiVrxKHU.js → chunk-KBJHAD2P-Cj8lRrla.js} +1 -1
  94. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-C2h9Xje1.js → chunk-RYQCIY6F-CUvD1FSd.js} +1 -1
  95. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-3iOSHdbM.js → chunk-XXDRQBXY-CqLw_eqB.js} +1 -1
  96. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DIzKJGHr.js +1 -0
  97. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DIzKJGHr.js +1 -0
  98. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BN3A7tkk.js → cose-bilkent-JH36ORCC-ku-WqJPx.js} +1 -1
  99. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CTuBy0Or.js → cynefin-VYW2F7L2-Bq_PYDhl.js} +1 -1
  100. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-wb6tUlMN.js → cynefinDiagram-MW4NZA55-BiGZV641.js} +1 -1
  101. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-GP1Ivx8B.js → dagre-VZM6K2ZE-C4JRlglF.js} +1 -1
  102. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-ejrcK6L0.js → diagram-7IWD3JNH-B0dNeWYG.js} +1 -1
  103. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-YFkCCvUU.js → diagram-B4RE2ZJO-Cj35YvYM.js} +1 -1
  104. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-B4rrvIaL.js → diagram-LBJQPF4R-uzQoJ2-8.js} +1 -1
  105. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-C-YIZcUf.js → diagram-Q27KOJAE-D1a-Buoz.js} +1 -1
  106. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BPF5wcL1.js → diagram-UB23O5K3-XjRrLRSs.js} +1 -1
  107. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CU5SzXjO.js → ebnfDiagram-BXEA7PRR-Da_O24cW.js} +1 -1
  108. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-CpL414DE.js → erDiagram-JOGREHBK-BLJ8jrYU.js} +1 -1
  109. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-MrhLzNau.js → flowDiagram-UKHOOZJN-B9GrLjM0.js} +1 -1
  110. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Bg4qFuUo.js → ganttDiagram-PKOTCBZU-CeJ0TqiK.js} +1 -1
  111. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-ColxSXLR.js → gitGraphDiagram-DS77QQ5N-Bm2eNNFX.js} +1 -1
  112. package/dist/worker/console/static/assets/index-H9rFJiGL.css +1 -0
  113. package/dist/worker/console/static/assets/index-xwu9GxEc.js +451 -0
  114. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Czvtm6gc.js → infoDiagram-6WML65LV-DB26i3d8.js} +1 -1
  115. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-B7Xp8HyJ.js → ishikawaDiagram-WSZJBQD7-BOGRyeZT.js} +1 -1
  116. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DWYZcvph.js → journeyDiagram-NVQOT4AX-CZRoBO_6.js} +1 -1
  117. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-KTLZRUjx.js → kanban-definition-27J2QSJJ-qlWhJyoB.js} +1 -1
  118. package/dist/worker/console/static/assets/{linear-_Exn7bfl.js → linear-CfUiDDB3.js} +1 -1
  119. package/dist/worker/console/static/assets/{mermaid.core-Cxg8kX8V.js → mermaid.core-BQe6fpqj.js} +5 -5
  120. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-oKrlo2Bt.js → mindmap-definition-FAOFIHXS-zFzWHw64.js} +1 -1
  121. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-XAeteiNd.js → pegDiagram-VL7TDLO6-DFGUqjZO.js} +1 -1
  122. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-BTf1K-lp.js → pieDiagram-7S7Q4E2Y-BB5i0l8Z.js} +1 -1
  123. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-C0IlY0Jf.js → quadrantDiagram-CIZ2JOQS-obbVZ_X5.js} +1 -1
  124. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BVbKtZhW.js → railroadDiagram-AXF67PYL-BwdaNzc1.js} +1 -1
  125. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-C5e4JFcr.js → requirementDiagram-LRYGKXZP-CkTJaugh.js} +1 -1
  126. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cz30hc29.js → sankeyDiagram-W5VNT64P-BwJ-hIgq.js} +1 -1
  127. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DS33n6d0.js → sequenceDiagram-SI44F4Z6-BzSgmm7w.js} +1 -1
  128. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-46w7v-9T.js → sizeCapture-X5ZJPWSS-Bn3oj5Q1.js} +1 -1
  129. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-pbcD5SsZ.js → stateDiagram-OKZ733FA-dxhGtL8K.js} +1 -1
  130. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Cld2qK9v.js +1 -0
  131. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DuivYBSj.js → swimlanes-SLNWSIFB-BLpEInya.js} +2 -2
  132. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-TIHpiT7w.js +8 -0
  133. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Cb9VZVIl.js → timeline-definition-Z64GVDOM-ChJGYcXy.js} +1 -1
  134. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-D2-mfOgR.js → vennDiagram-T6HMQDX7-DK-qjRer.js} +1 -1
  135. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-DeS2aC76.js → wardleyDiagram-T6FBY63Y-3qeaWAg-.js} +1 -1
  136. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-WGsrFjxH.js → xychartDiagram-ELKLHX3M-CootlyP9.js} +1 -1
  137. package/dist/worker/console/static/index.html +7 -2
  138. package/dist/worker/console/static-src/app/useOperatorActions.js +3 -2
  139. package/dist/worker/console/static-src/app/useRunProgress.js +9 -2
  140. package/dist/worker/console/static-src/operator-chat/dag-progress-link.js +22 -0
  141. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +2 -0
  142. package/dist/worker/console/static-src/operator-chat/useChatThread.js +6 -0
  143. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +28 -3
  144. package/dist/worker/console/static-src/pages/tasks/run-panel-progress.js +106 -0
  145. package/dist/worker/console/static-src/shell/console-update-reload.js +25 -0
  146. package/dist/worker/console/workspace-context.js +28 -112
  147. package/dist/worker/console/workspace-registry.js +2 -2
  148. package/dist/worker/continuation/worker-continuation.js +278 -0
  149. package/dist/worker/observability/read-model.js +4 -0
  150. package/dist/worker/observe/health.js +1 -1
  151. package/dist/worker/observe/node-transparency.js +572 -0
  152. package/dist/worker/observe/routes.js +51 -1
  153. package/dist/worker/observe/static/api.js +69 -5
  154. package/dist/worker/observe/static/dag-context-reason-labels.d.ts +9 -0
  155. package/dist/worker/observe/static/dag-context-reason-labels.js +120 -0
  156. package/dist/worker/observe/static/dag-node-purpose.js +0 -5
  157. package/dist/worker/observe/static/state.js +3 -1
  158. package/dist/worker/observe/static/styles.css +1037 -126
  159. package/dist/worker/observe/static/views/dag-inspector.js +1217 -65
  160. package/dist/worker/observe/static/views/session-timeline.js +121 -25
  161. package/dist/worker/outcomes/adapters.js +19 -0
  162. package/dist/worker/outcomes/types.js +1 -0
  163. package/dist/worker/pool/attempt-lease.js +97 -66
  164. package/dist/worker/pool/begin-attempt-with-lease.js +1 -0
  165. package/dist/worker/pool/reconcile.js +46 -1
  166. package/dist/worker/pool/run-store.js +2 -0
  167. package/dist/worker/pool/state-projection.js +2 -0
  168. package/dist/worker/task-spec/workflow-routing.js +8 -3
  169. package/dist/workflows/dag/artifact-bindings.js +149 -0
  170. package/dist/workflows/dag/artifact-revision-schema-registry.js +31 -0
  171. package/dist/workflows/dag/backend-test-result-contract.js +1 -1
  172. package/dist/workflows/dag/budget-enforcement.js +10 -0
  173. package/dist/workflows/dag/context-receipt.js +305 -0
  174. package/dist/workflows/dag/context-transfer/context-bundle.js +423 -0
  175. package/dist/workflows/dag/context-transfer/operator-actions.js +61 -0
  176. package/dist/workflows/dag/context-transfer/renderers.js +93 -0
  177. package/dist/workflows/dag/contract-validator-registrations.js +2 -1
  178. package/dist/workflows/dag/frontend-implementation-contract.js +162 -932
  179. package/dist/workflows/dag/frontend-plan-render.js +1 -2
  180. package/dist/workflows/dag/frontend-prewrite-gate.js +349 -255
  181. package/dist/workflows/dag/frontend-recovery-plan.js +10 -17
  182. package/dist/workflows/dag/frontend-recovery-run.js +20 -33
  183. package/dist/workflows/dag/frontend-repair.js +432 -1
  184. package/dist/workflows/dag/frontend-review-context.js +15 -261
  185. package/dist/workflows/dag/frontend-verification-trace.js +24 -249
  186. package/dist/workflows/dag/frontend-worktree-diff.js +17 -250
  187. package/dist/workflows/dag/frontend-writer-rollback.js +32 -0
  188. package/dist/workflows/dag/init-hybrid.js +640 -685
  189. package/dist/workflows/dag/interrupt-request.js +0 -7
  190. package/dist/workflows/dag/node-execution.js +116 -759
  191. package/dist/workflows/dag/path-safety.js +1 -0
  192. package/dist/workflows/dag/prompt.js +30 -38
  193. package/dist/workflows/dag/report.js +1 -37
  194. package/dist/workflows/dag/rerun-feedback.js +1 -256
  195. package/dist/workflows/dag/rerun-plan.js +557 -11
  196. package/dist/workflows/dag/rerun-run.js +601 -38
  197. package/dist/workflows/dag/rerun-task.js +0 -29
  198. package/dist/workflows/dag/retry-policy.js +104 -214
  199. package/dist/workflows/dag/runner.js +142 -430
  200. package/dist/workflows/dag/scheduler.js +16 -114
  201. package/dist/workflows/dag/skill-snapshot.js +17 -0
  202. package/dist/workflows/dag/types.js +195 -246
  203. package/dist/workflows/dag/validate.js +12 -28
  204. package/docs/architecture/runtime-boundaries.md +6 -6
  205. package/docs/architecture/worker-and-feature.md +1 -1
  206. package/docs/init-surface.manifest.json +12 -30
  207. package/docs/skills/vetted-skill-registry.md +2 -4
  208. package/docs/templates/README.md +0 -2
  209. package/docs/templates/agent-dag-report.schema.json +2 -8
  210. package/docs/templates/agent-dag.schema.json +33 -1
  211. package/docs/templates/frontend-implementation-contract.schema.json +1 -4
  212. package/docs/templates/product-line/task.yaml +1 -1
  213. package/harness.json +3 -3
  214. package/package.json +3 -1
  215. package/skills/frontend-bounded-implement/SKILL.md +14 -15
  216. package/skills/frontend-design-review/SKILL.md +41 -22
  217. package/skills/frontend-implementation/SKILL.md +52 -0
  218. package/skills/frontend-implementation/references/code-standards.md +33 -0
  219. package/skills/frontend-implementation/references/design-spec.md +56 -0
  220. package/skills/frontend-implementation/references/node-contracts.md +31 -0
  221. package/skills/frontend-review/SKILL.md +15 -20
  222. package/skills/frontend-review/references/review-findings.md +7 -6
  223. package/skills/frontend-verification/SKILL.md +1 -1
  224. package/skills/loop-agent/references/command-reference.md +6 -1
  225. package/skills/loop-agent/references/hybrid-dag.md +2 -2
  226. package/dist/commands/dag-follow-up.js +0 -138
  227. package/dist/executors/pi-read-budget-policy.js +0 -239
  228. package/dist/worker/console/frontend-human-decision-adapter.js +0 -19
  229. package/dist/worker/console/frontend-split-operation-adapter.js +0 -20
  230. package/dist/worker/console/operation-store.js +0 -389
  231. package/dist/worker/console/static/assets/channel-bnXW0U3C.js +0 -1
  232. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-rZpq_twR.js +0 -1
  233. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-rZpq_twR.js +0 -1
  234. package/dist/worker/console/static/assets/index-D3CC4eUz.css +0 -1
  235. package/dist/worker/console/static/assets/index-DLt4ZFvD.js +0 -437
  236. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-zBMYiUyi.js +0 -1
  237. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-d_rms-5i.js +0 -8
  238. package/dist/worker/console/static-src/active-run-badge.js +0 -17
  239. package/dist/worker/materialize/frontend-split-task-materializer.js +0 -72
  240. package/dist/workflows/dag/dag-retry-schema.js +0 -138
  241. package/dist/workflows/dag/frontend-closeout.js +0 -221
  242. package/dist/workflows/dag/frontend-design-policy.js +0 -400
  243. package/dist/workflows/dag/frontend-human-decision.js +0 -182
  244. package/dist/workflows/dag/frontend-provider-capability-matrix.js +0 -159
  245. package/dist/workflows/dag/frontend-read-budgets.js +0 -12
  246. package/dist/workflows/dag/frontend-recovery-capsule.js +0 -455
  247. package/dist/workflows/dag/frontend-recovery-controller.js +0 -202
  248. package/dist/workflows/dag/frontend-recovery-lineage.js +0 -178
  249. package/dist/workflows/dag/frontend-review-findings.js +0 -270
  250. package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -914
  251. package/dist/workflows/dag/frontend-shape-capsule-store.js +0 -191
  252. package/dist/workflows/dag/frontend-shape-facts.js +0 -409
  253. package/dist/workflows/dag/frontend-shape.js +0 -427
  254. package/dist/workflows/dag/frontend-source-fidelity-ledger.js +0 -108
  255. package/dist/workflows/dag/frontend-split-application-service.js +0 -203
  256. package/dist/workflows/dag/frontend-split-orchestrator.js +0 -899
  257. package/dist/workflows/dag/frontend-typed-event-store.js +0 -452
  258. package/dist/workflows/dag/frontend-typed-event-transaction.js +0 -180
  259. package/dist/workflows/dag/frontend-writer-admission.js +0 -285
  260. package/dist/workflows/dag/frontend-writer-status.js +0 -256
  261. package/dist/workflows/dag/recovery-lease.js +0 -80
  262. package/docs/templates/frontend-implementation-dag.json +0 -89
  263. package/docs/templates/spec-registry.schema.json +0 -45
  264. package/skills/frontend-bounded-implement/references/code-standards.md +0 -19
  265. package/skills/frontend-contract/SKILL.md +0 -23
  266. package/skills/frontend-contract/references/contract-protocol.md +0 -34
  267. package/skills/frontend-plan/SKILL.md +0 -26
  268. package/skills/frontend-plan/references/decision-contract.md +0 -37
  269. package/skills/frontend-plan/references/design-decisions.md +0 -17
  270. package/skills/frontend-scout/SKILL.md +0 -25
  271. package/skills/frontend-scout/references/design-evidence.md +0 -16
  272. package/skills/frontend-scout/references/scout-evidence.md +0 -23
  273. /package/dist/{worker → infrastructure}/console/repo-fingerprint.js +0 -0
@@ -13,8 +13,6 @@ import { runDagUseCase } from "./run-dag.js";
13
13
  import { getTaskPaths, loadTaskConfig } from "../../task/runtime.js";
14
14
  import { writeTaskConfig } from "../../infrastructure/harness/task-store.js";
15
15
  import { runFrontendPreflight } from "../../task/frontend-preflight.js";
16
- import { discoverFrontendProjectCapability } from "../../task/frontend-project-capability.js";
17
- import { classifyTaskDemand } from "../../task/task-demand-routing.js";
18
16
  import { observeTaskContract } from "../../task/contract/observe.js";
19
17
  import { adoptTaskContract } from "../../task/contract/adopt.js";
20
18
  const PLACEHOLDER_WRITESET_MARKER = "REPLACE/WITH";
@@ -90,63 +88,6 @@ function buildBasicValidationLevel(outputPath) {
90
88
  note: "Internal generation validation is basic only; standalone strict governance validation must be confirmed separately.",
91
89
  };
92
90
  }
93
- async function promoteAutomaticFrontendTaskKind(input) {
94
- if (input.taskConfig.taskKind !== "standard" ||
95
- input.taskConfig.taskKindExplicit) {
96
- return false;
97
- }
98
- let requirementMarkdown = "";
99
- try {
100
- requirementMarkdown = await readFile(path.join(getTaskPaths(input.repoRoot, input.taskId).sourceDir, "需求.md"), "utf8");
101
- }
102
- catch {
103
- return false;
104
- }
105
- if (!requirementMarkdown.trim())
106
- return false;
107
- let frontendProject;
108
- try {
109
- frontendProject = await discoverFrontendProjectCapability(input.repoRoot);
110
- }
111
- catch {
112
- // The existing standard route remains the safe fallback when capability
113
- // discovery is unavailable.
114
- }
115
- const classification = classifyTaskDemand({
116
- title: input.taskConfig.title,
117
- requirementMarkdown,
118
- allowedPaths: input.taskConfig.allowedPaths,
119
- frontendProject: frontendProject
120
- ? {
121
- framework: frontendProject.framework,
122
- evidencePaths: frontendProject.evidencePaths,
123
- }
124
- : undefined,
125
- });
126
- if (classification.kind !== "frontend")
127
- return false;
128
- await writeTaskConfig(input.repoRoot, input.taskId, {
129
- ...input.taskConfig,
130
- taskKind: "frontend-implementation",
131
- dagFallbackReason: "Automatically classified as a high-confidence frontend implementation task.",
132
- });
133
- const state = await observeTaskContract({
134
- repoRoot: input.repoRoot,
135
- taskId: input.taskId,
136
- });
137
- if (!state.ref || !state.observedCanonicalHash) {
138
- throw new Error("automatic frontend routing could not reconcile the managed Task Contract");
139
- }
140
- await adoptTaskContract({
141
- repoRoot: input.repoRoot,
142
- taskId: input.taskId,
143
- expectedRevision: state.ref.revision,
144
- expectedObservedHash: state.observedCanonicalHash,
145
- requestId: `automatic-frontend-route-${input.taskId}-${randomUUID()}`,
146
- requestPayloadSha256: randomUUID().replaceAll("-", "").padEnd(64, "0"),
147
- });
148
- return true;
149
- }
150
91
  function isBroadWriteSetEntryForPacket(entry) {
151
92
  const normalized = entry.trim().replace(/\\/g, "/").replace(/^\.\//, "");
152
93
  if (!normalized || normalized === "." || normalized === "./")
@@ -339,25 +280,12 @@ export async function generateTaskDagUseCase(input) {
339
280
  requestPayloadSha256: randomUUID().replaceAll("-", "").padEnd(64, "0"),
340
281
  });
341
282
  }
342
- const routingTaskConfig = await loadTaskConfig(repoRoot, parsed.taskId);
343
- let initialTemplate = routingTaskConfig.taskKind === "frontend-implementation"
344
- ? "frontend-implementation"
345
- : "standard-dag";
346
- if (initialTemplate === "standard-dag") {
347
- const promoted = await promoteAutomaticFrontendTaskKind({
348
- repoRoot,
349
- taskId: parsed.taskId,
350
- taskConfig: routingTaskConfig,
351
- });
352
- if (promoted)
353
- initialTemplate = "frontend-implementation";
354
- }
355
- let candidateResult = await initHybridDagFromTask(repoRoot, parsed.taskId, {
283
+ const candidateResult = await initHybridDagFromTask(repoRoot, parsed.taskId, {
356
284
  outputPath: parsed.outputPath,
357
- template: initialTemplate,
285
+ template: "standard-dag",
358
286
  rerunFeedback: parsed.rerunFeedback,
359
287
  });
360
- let candidateValidateSummary = await validateDagUseCase(buildValidateInput(repoRoot, candidateResult.outputPath, parsed));
288
+ const candidateValidateSummary = await validateDagUseCase(buildValidateInput(repoRoot, candidateResult.outputPath, parsed));
361
289
  const profileRouting = await resolveProfileRouting(repoRoot, parsed, candidateValidateSummary.governanceProfile ?? {
362
290
  profile: "standard",
363
291
  process: [],
@@ -380,6 +308,22 @@ export async function generateTaskDagUseCase(input) {
380
308
  profileRouting.selectedByProfile = parsed.profile;
381
309
  }
382
310
  }
311
+ // Persist the automatic business workflow route while preserving the
312
+ // governance profile as a separate routing dimension.
313
+ if (hasAutomaticTaskSourceRoute &&
314
+ candidateResult.template === "frontend-implementation") {
315
+ const taskConfig = await loadTaskConfig(repoRoot, parsed.taskId);
316
+ // Human-explicit taskKind (incl. explicit standard) is a hard contract:
317
+ // never rewrite task.json taskKind via semantic classification.
318
+ if (!taskConfig.taskKindExplicit &&
319
+ (!taskConfig.taskKind || taskConfig.taskKind === "standard")) {
320
+ await writeTaskConfig(repoRoot, parsed.taskId, {
321
+ ...taskConfig,
322
+ taskKind: "frontend-implementation",
323
+ dagFallbackReason: "Automatically classified as a high-confidence frontend implementation task.",
324
+ });
325
+ }
326
+ }
383
327
  const initResult = profileRouting.selectedTemplate === candidateResult.template
384
328
  ? candidateResult
385
329
  : await initHybridDagFromTask(repoRoot, parsed.taskId, {
@@ -260,10 +260,6 @@ async function monitorRun(input) {
260
260
  failureCategory: "monitor-timeout",
261
261
  });
262
262
  }
263
- function isStartupGateEligible(snapshot) {
264
- const status = snapshot.source?.sourceFidelityStartup?.status;
265
- return status === undefined || status === "complete" || status === "not-applicable";
266
- }
267
263
  function nextMutationAction(actions) {
268
264
  for (const action of actions) {
269
265
  if (action.type !== "stop")
@@ -383,10 +379,7 @@ export async function advanceTaskLifecycle(input) {
383
379
  };
384
380
  }
385
381
  const token = parseGateToken(input.rejectGateToken);
386
- const currentGate = snapshot.gate ??
387
- (isStartupGateEligible(snapshot)
388
- ? await buildCurrentGate(input.repoRoot, input.taskId)
389
- : null);
382
+ const currentGate = snapshot.gate ?? (await buildCurrentGate(input.repoRoot, input.taskId));
390
383
  if (!currentGate || !gateMatches(currentGate, token)) {
391
384
  return {
392
385
  taskId: input.taskId,
@@ -450,12 +443,11 @@ export async function advanceTaskLifecycle(input) {
450
443
  dryRun,
451
444
  skipFinalize: Boolean(input.skipFinalize),
452
445
  forcePrepareContract: Boolean(input.fromDraftPath) && !preparedContractThisCall,
453
- startupRepairAttempted: preparedContractThisCall,
454
446
  });
455
447
  if (dryRun) {
456
448
  const plan = planOnce(snapshot);
457
449
  const plannedGate = snapshot.gate ??
458
- (isStartupGateEligible(snapshot) && snapshot.dagDraft?.exists
450
+ (snapshot.dagDraft?.exists
459
451
  ? await buildCurrentGate(input.repoRoot, input.taskId)
460
452
  : null);
461
453
  return {
@@ -507,10 +499,7 @@ export async function advanceTaskLifecycle(input) {
507
499
  }
508
500
  if (action.type === "create-task") {
509
501
  if (!snapshot.exists) {
510
- await createTask(input.repoRoot, input.taskId, input.title, {
511
- taskKind: input.taskKind,
512
- taskKindExplicit: input.taskKindExplicit,
513
- });
502
+ await createTask(input.repoRoot, input.taskId, input.title);
514
503
  record = appendTransition(record, "task-created");
515
504
  completed.push("task-created");
516
505
  await saveLifecycleRecord(input.repoRoot, record);
@@ -597,10 +586,6 @@ export async function advanceTaskLifecycle(input) {
597
586
  continue;
598
587
  }
599
588
  if (action.type === "prepare-contract") {
600
- const startupStatus = snapshot.source?.sourceFidelityStartup?.status;
601
- const startupRepairAction = startupStatus === "missing" ||
602
- startupStatus === "invalid" ||
603
- startupStatus === "coverage-incomplete";
604
589
  // 生产 source fidelity Pi 接线(AC-PROD-001/005):仅 frontend-implementation
605
590
  // 任务注入 reconcile executor + 独立 reviewer;ineligible 返回 undefined 不接线。
606
591
  // 主路径与 semantic-intake retry 路径共用同一接线,保证任意一条生产路径都实际
@@ -746,9 +731,7 @@ export async function advanceTaskLifecycle(input) {
746
731
  message: "structured requirement draft via semantic intake; projected managed source",
747
732
  });
748
733
  preparedContractThisCall = true;
749
- if (startupRepairAction ||
750
- refreshManagedContractThisCall ||
751
- input.fromDraftPath) {
734
+ if (refreshManagedContractThisCall || input.fromDraftPath) {
752
735
  refreshManagedContractThisCall = false;
753
736
  regenerateDagThisCall = true;
754
737
  }
@@ -842,9 +825,7 @@ export async function advanceTaskLifecycle(input) {
842
825
  break;
843
826
  }
844
827
  preparedContractThisCall = true;
845
- if (startupRepairAction ||
846
- refreshManagedContractThisCall ||
847
- input.fromDraftPath) {
828
+ if (refreshManagedContractThisCall || input.fromDraftPath) {
848
829
  // The old DAG and gate were bound to the pre-mutation contract.
849
830
  refreshManagedContractThisCall = false;
850
831
  regenerateDagThisCall = true;
@@ -1,11 +1,9 @@
1
- import { access, readFile, readdir } from "node:fs/promises";
1
+ import { access, readFile } from "node:fs/promises";
2
2
  import path from "node:path";
3
3
  import { getTaskDir, getTaskPaths, getTaskStatus, loadTaskConfig, } from "../../task/runtime.js";
4
4
  import { logicalRevisionForState, observeTaskContractState, } from "../../task/contract/index.js";
5
5
  import { assessDagRunLiveness, listAllDagRunEntries, readDagRunSpec, readDagRunState, } from "../../workflows/dag/lifecycle.js";
6
6
  import { resolveRunningControllerIdentity } from "../../shared/package-metadata.js";
7
- import { parseLedgerJson, validateRequirementLedger, } from "../../task/source-prepare/ledger.js";
8
- import { REQUIREMENT_LEDGER_FILE_NAME } from "../../task/source-prepare/types.js";
9
7
  import { loadLifecycleRecord } from "./record.js";
10
8
  import { buildGateBinding, buildWriteSetGate, buildWriteSetGateDelta, controllerIdentityAnchor, hashCanonicalPayload, normalizeWriteSet, sha256Hex, } from "./gates.js";
11
9
  async function exists(filePath) {
@@ -49,140 +47,6 @@ async function taskExists(repoRoot, taskId) {
49
47
  const paths = getTaskPaths(repoRoot, taskId);
50
48
  return exists(paths.taskConfigPath);
51
49
  }
52
- async function assessReferenceEvidence(referencesDir) {
53
- try {
54
- const entries = await readdir(referencesDir);
55
- const importedPrdCount = entries.filter((name) => name.endsWith(".md")).length;
56
- return importedPrdCount > 0
57
- ? { status: "present", importedPrdCount }
58
- : { status: "absent-or-empty", importedPrdCount: 0 };
59
- }
60
- catch (error) {
61
- if (error &&
62
- typeof error === "object" &&
63
- "code" in error &&
64
- error.code === "ENOENT") {
65
- return { status: "absent-or-empty", importedPrdCount: 0 };
66
- }
67
- return {
68
- status: "unknown",
69
- importedPrdCount: 0,
70
- error: error instanceof Error ? error.message : String(error),
71
- };
72
- }
73
- }
74
- function hasLedgerStructure(value) {
75
- if (!value || typeof value !== "object")
76
- return false;
77
- const ledger = value;
78
- return (typeof ledger.taskId === "string" &&
79
- typeof ledger.inputDigest === "string" &&
80
- typeof ledger.requirementSha256 === "string" &&
81
- Array.isArray(ledger.sourcePaths) &&
82
- Array.isArray(ledger.fragments) &&
83
- Array.isArray(ledger.canonicalRequirements) &&
84
- Boolean(ledger.stats && typeof ledger.stats === "object") &&
85
- Array.isArray(ledger.unresolved) &&
86
- Array.isArray(ledger.conflicts) &&
87
- Array.isArray(ledger.sourceResolutions) &&
88
- typeof ledger.schemaReconcilerVersion === "string" &&
89
- typeof ledger.builtAt === "string");
90
- }
91
- async function assessSourceFidelityStartup(input) {
92
- if (!input.applicable) {
93
- return {
94
- status: "not-applicable",
95
- ledgerPath: input.ledgerPath,
96
- diagnostics: [],
97
- };
98
- }
99
- if (input.referenceEvidenceError) {
100
- return {
101
- status: "invalid",
102
- ledgerPath: input.ledgerPath,
103
- diagnostics: [
104
- {
105
- code: "SOURCE_FIDELITY_LEDGER_STALE",
106
- message: `imported PRD reference evidence is unreadable: ${input.referenceEvidenceError}`,
107
- },
108
- ],
109
- };
110
- }
111
- let raw;
112
- try {
113
- raw = await readFile(input.ledgerPath, "utf-8");
114
- }
115
- catch (error) {
116
- const missing = !(await exists(input.ledgerPath));
117
- return {
118
- status: missing ? "missing" : "invalid",
119
- ledgerPath: input.ledgerPath,
120
- diagnostics: [
121
- {
122
- code: missing
123
- ? "SOURCE_FIDELITY_LEDGER_MISSING"
124
- : "SOURCE_FIDELITY_LEDGER_STALE",
125
- message: missing
126
- ? "managed frontend task has no requirement-ledger.json"
127
- : `requirement ledger is unreadable: ${error instanceof Error ? error.message : String(error)}`,
128
- },
129
- ],
130
- };
131
- }
132
- try {
133
- const ledger = parseLedgerJson(raw);
134
- if (!hasLedgerStructure(ledger)) {
135
- return {
136
- status: "invalid",
137
- ledgerPath: input.ledgerPath,
138
- diagnostics: [
139
- {
140
- code: "SOURCE_FIDELITY_LEDGER_STALE",
141
- message: "requirement ledger is missing required structural fields",
142
- },
143
- ],
144
- };
145
- }
146
- const nonDecisionErrors = validateRequirementLedger(ledger, {
147
- allowedUnresolved: true,
148
- allowedConflicts: true,
149
- });
150
- if (nonDecisionErrors.length > 0) {
151
- const coverageCodes = new Set([
152
- "SOURCE_FIDELITY_HIGH_RISK_UNCOVERED",
153
- "SOURCE_FIDELITY_REQUIREMENT_NOT_COVERED",
154
- ]);
155
- return {
156
- status: nonDecisionErrors.every((error) => coverageCodes.has(error.code))
157
- ? "coverage-incomplete"
158
- : "invalid",
159
- ledgerPath: input.ledgerPath,
160
- diagnostics: nonDecisionErrors,
161
- };
162
- }
163
- const decisionErrors = validateRequirementLedger(ledger);
164
- if (decisionErrors.length > 0) {
165
- return {
166
- status: "human-decision-blocked",
167
- ledgerPath: input.ledgerPath,
168
- diagnostics: decisionErrors,
169
- };
170
- }
171
- return { status: "complete", ledgerPath: input.ledgerPath, diagnostics: [] };
172
- }
173
- catch (error) {
174
- return {
175
- status: "invalid",
176
- ledgerPath: input.ledgerPath,
177
- diagnostics: [
178
- {
179
- code: "SOURCE_FIDELITY_LEDGER_STALE",
180
- message: error instanceof Error ? error.message : String(error),
181
- },
182
- ],
183
- };
184
- }
185
- }
186
50
  /**
187
51
  * Explicit Task↔DAG association only:
188
52
  * - lifecycle.json recorded runAssociations
@@ -318,12 +182,10 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
318
182
  const record = await loadLifecycleRecord(repoRoot, taskId);
319
183
  const contractState = await observeTaskContractState(repoRoot, taskId);
320
184
  let title;
321
- let taskKind;
322
185
  let taskConfigAllowed = [];
323
186
  try {
324
187
  const config = await loadTaskConfig(repoRoot, taskId);
325
188
  title = config.title;
326
- taskKind = config.taskKind;
327
189
  taskConfigAllowed = config.allowedPaths ?? [];
328
190
  }
329
191
  catch {
@@ -337,22 +199,19 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
337
199
  ...(requirementReady ? [] : [requirementPath]),
338
200
  ...(constraintsReady ? [] : [constraintsPath]),
339
201
  ];
340
- const contractManaged = contractState.effectiveStatus === "managed" || Boolean(contractState.ref);
202
+ let importedPrdCount = 0;
341
203
  const referencesDir = path.join(paths.sourceDir, "references");
342
- const referenceEvidence = await assessReferenceEvidence(referencesDir);
343
- const importedPrdCount = referenceEvidence.importedPrdCount;
344
- const ledgerPath = path.join(paths.sourceDir, REQUIREMENT_LEDGER_FILE_NAME);
345
- const sourceFidelityStartup = await assessSourceFidelityStartup({
346
- ledgerPath,
347
- applicable: contractManaged &&
348
- taskKind === "frontend-implementation" &&
349
- referenceEvidence.status !== "absent-or-empty",
350
- referenceEvidenceError: referenceEvidence.status === "unknown"
351
- ? referenceEvidence.error
352
- : undefined,
353
- });
354
- const sourceFidelityReady = sourceFidelityStartup.status === "complete" ||
355
- sourceFidelityStartup.status === "not-applicable";
204
+ if (await exists(referencesDir)) {
205
+ // Count is best-effort; absence is fine.
206
+ try {
207
+ const { readdir } = await import("node:fs/promises");
208
+ const entries = await readdir(referencesDir);
209
+ importedPrdCount = entries.filter((name) => name.endsWith(".md")).length;
210
+ }
211
+ catch {
212
+ importedPrdCount = 0;
213
+ }
214
+ }
356
215
  const dagDraftPath = paths.dagDraftPath;
357
216
  const dagDraftExists = await exists(dagDraftPath);
358
217
  let specHash = null;
@@ -426,11 +285,7 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
426
285
  // Open gate only when draft is strict-validated and the current binding is
427
286
  // not already approved/rejected. Rejected same-digest gates stay closed
428
287
  // until contract/source/DAG/writeSet/controller binding changes.
429
- const gate = gateBound &&
430
- strictValidated &&
431
- sourceFidelityReady &&
432
- !approvedCurrent &&
433
- !rejectedCurrent
288
+ const gate = gateBound && strictValidated && !approvedCurrent && !rejectedCurrent
434
289
  ? buildWriteSetGate({ taskId, bound: gateBound, delta: gateDelta })
435
290
  : null;
436
291
  const gateOpen = Boolean(gate);
@@ -455,10 +310,11 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
455
310
  activeRun.failureCategory === "needs-attention" ||
456
311
  activeRun.failureCategory === "suspected-stall" ||
457
312
  activeRun.failureCategory === "monitor-timeout"));
313
+ const contractManaged = contractState.effectiveStatus === "managed" || Boolean(contractState.ref);
458
314
  const lifecycleState = deriveLifecycleState({
459
315
  exists: true,
460
316
  contractManaged,
461
- sourceReady: requirementReady && sourceFidelityReady,
317
+ sourceReady: requirementReady,
462
318
  dagValidated: strictValidated,
463
319
  gateOpen: Boolean(gate),
464
320
  activeRun,
@@ -496,7 +352,6 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
496
352
  constraintsReady,
497
353
  importedPrdCount,
498
354
  missing,
499
- sourceFidelityStartup,
500
355
  },
501
356
  dagDraft: {
502
357
  path: dagDraftPath,
@@ -520,16 +375,7 @@ export async function observeTaskLifecycle(repoRoot, taskId) {
520
375
  exists: closeoutExists || Boolean(record?.closeout),
521
376
  },
522
377
  completedTransitions: record?.completedTransitions ?? [],
523
- blockers: sourceFidelityReady
524
- ? []
525
- : sourceFidelityStartup.diagnostics.map((diagnostic) => ({
526
- code: diagnostic.code,
527
- message: diagnostic.message,
528
- details: {
529
- startupStatus: sourceFidelityStartup.status,
530
- ledgerPath: sourceFidelityStartup.ledgerPath,
531
- },
532
- })),
378
+ blockers: [],
533
379
  warnings: [],
534
380
  next,
535
381
  };
@@ -46,37 +46,6 @@ export function planTransitions(input) {
46
46
  actions.push({ type: "recover-contract" });
47
47
  expectedTransitions.push("contract-recovered");
48
48
  }
49
- const startupStatus = snapshot.source?.sourceFidelityStartup?.status;
50
- const startupRepairDetected = startupStatus === "missing" ||
51
- startupStatus === "invalid" ||
52
- startupStatus === "coverage-incomplete";
53
- if (startupRepairDetected && input.startupRepairAttempted) {
54
- actions.push({ type: "stop", reason: "blocker" });
55
- return {
56
- actions,
57
- gate: null,
58
- blockers,
59
- next: {
60
- kind: "advance",
61
- command: `loop-agent task advance ${snapshot.taskId} --json`,
62
- },
63
- expectedTransitions,
64
- };
65
- }
66
- const startupRepairRequired = startupRepairDetected;
67
- if (startupStatus === "human-decision-blocked") {
68
- actions.push({ type: "stop", reason: "blocker" });
69
- return {
70
- actions,
71
- gate: null,
72
- blockers,
73
- next: {
74
- kind: "external-action",
75
- description: "Requirement ledger requires an existing human source decision; preserve sourceResolutions, resolve the blocker, then advance again.",
76
- },
77
- expectedTransitions,
78
- };
79
- }
80
49
  const sourceReady = snapshot.source?.requirementReady === true;
81
50
  const contractManaged = snapshot.contract?.effectiveStatus === "managed" ||
82
51
  Boolean(snapshot.contract?.revision && snapshot.contract.revision > 0);
@@ -84,9 +53,7 @@ export function planTransitions(input) {
84
53
  // Prefer prepare once PRDs are on disk; re-import only when caller still
85
54
  // signals hasPrdInput (advance.ts latches this after one import per call).
86
55
  const shouldImportPrd = input.hasPrdInput;
87
- if (input.forcePrepareContract ||
88
- input.refreshManagedContract ||
89
- startupRepairRequired) {
56
+ if (input.forcePrepareContract || input.refreshManagedContract) {
90
57
  if (shouldImportPrd) {
91
58
  actions.push({ type: "import-prd" });
92
59
  expectedTransitions.push("prd-imported");
@@ -157,8 +124,7 @@ export function planTransitions(input) {
157
124
  const strictValidated = snapshot.dagDraft?.strictValidated === true;
158
125
  const dagRefreshRequired = Boolean(input.forceDagRefresh ||
159
126
  input.refreshManagedContract ||
160
- input.forcePrepareContract ||
161
- startupRepairRequired);
127
+ input.forcePrepareContract);
162
128
  if (!dagExists || dagRefreshRequired) {
163
129
  actions.push({ type: "generate-dag" });
164
130
  expectedTransitions.push("dag-generated");
@@ -179,11 +145,10 @@ export function planTransitions(input) {
179
145
  snapshot.lifecycleState === "evidence-closed" ||
180
146
  snapshot.lifecycleState === "needs-attention" ||
181
147
  snapshot.lifecycleState === "awaiting-decision";
182
- const approveCurrentGate = input.approveGate && !dagRefreshRequired;
183
- const approvedForCurrent = postRunState || (approveCurrentGate && gate !== null);
148
+ const approvedForCurrent = postRunState || (input.approveGate && gate !== null);
184
149
  if (!approvedForCurrent && (strictValidated || !dagExists || dagRefreshRequired)) {
185
150
  // Gate opens after generate+validate in the advance loop; plan includes open.
186
- if (!approveCurrentGate) {
151
+ if (!input.approveGate) {
187
152
  actions.push({ type: "open-write-set-gate" });
188
153
  expectedTransitions.push("write-set-gate-opened");
189
154
  if (input.dryRun) {
@@ -212,14 +177,14 @@ export function planTransitions(input) {
212
177
  (snapshot.lifecycleState === "run-failed" && !failedRecoverable) ||
213
178
  snapshot.lifecycleState === "evidence-closed";
214
179
  if (!alreadyTerminalRun) {
215
- if (approveCurrentGate && !postRunState) {
180
+ if (input.approveGate && !postRunState) {
216
181
  expectedTransitions.push("write-set-approved");
217
182
  actions.push({ type: "start-or-monitor-run" });
218
183
  expectedTransitions.push("dag-run-started", "dag-run-monitored");
219
184
  }
220
185
  else if (snapshot.lifecycleState === "running" ||
221
186
  snapshot.activeRun ||
222
- (approveCurrentGate && Boolean(snapshot.activeRun))) {
187
+ (input.approveGate && Boolean(snapshot.activeRun))) {
223
188
  actions.push({ type: "start-or-monitor-run" });
224
189
  expectedTransitions.push("dag-run-monitored");
225
190
  }
@@ -253,7 +218,7 @@ export function planTransitions(input) {
253
218
  actions,
254
219
  gate,
255
220
  blockers,
256
- next: deriveNext(snapshot, gate, approveCurrentGate),
221
+ next: deriveNext(snapshot, gate, input.approveGate),
257
222
  expectedTransitions,
258
223
  };
259
224
  }
@@ -42,7 +42,6 @@ export async function buildTaskLifecycleRecommendations(input) {
42
42
  const allowedPaths = [];
43
43
  const verifyCommands = [];
44
44
  // 1) managed task config
45
- let hasDeclaredManagedVerify = false;
46
45
  try {
47
46
  const config = await loadTaskConfig(input.repoRoot, input.taskId);
48
47
  for (const glob of config.allowedPaths ?? []) {
@@ -54,9 +53,7 @@ export async function buildTaskLifecycleRecommendations(input) {
54
53
  source: "managed-task-config",
55
54
  });
56
55
  }
57
- const managedVerify = (config.verifyCommands ?? []).filter((cmd) => Boolean(cmd.command?.trim()));
58
- hasDeclaredManagedVerify = managedVerify.length > 0;
59
- for (const cmd of managedVerify) {
56
+ for (const cmd of config.verifyCommands ?? []) {
60
57
  const label = cmd.label?.trim() || "verify";
61
58
  const command = cmd.command?.trim();
62
59
  if (!command)
@@ -73,22 +70,14 @@ export async function buildTaskLifecycleRecommendations(input) {
73
70
  // task may not exist yet
74
71
  }
75
72
  // 2) package.json scripts (only if not already covered by managed config)
76
- // The full-suite `test` script is recommended only when the task declares
77
- // NO managed verifyCommands at all. Once a task configures a targeted
78
- // verify set (e.g. per-change typecheck + a scoped vitest run), the full
79
- // `npm run test` must never be auto-added: it validates the whole repo,
80
- // costs far more than the change under review, and can fail on unrelated
81
- // pre-existing breakage, turning a targeted verify green into a hard fail.
82
73
  const scripts = await readPackageScripts(input.repoRoot);
83
74
  const hasVerifyLabel = (label) => verifyCommands.some((entry) => entry.label === label);
84
75
  const scriptCandidates = [
85
76
  { label: "typecheck", script: "typecheck" },
77
+ { label: "test", script: "test" },
86
78
  { label: "check-repo", script: "check:repo" },
87
79
  { label: "check-repo", script: "check-repo" },
88
80
  ];
89
- if (!hasDeclaredManagedVerify) {
90
- scriptCandidates.push({ label: "test", script: "test" });
91
- }
92
81
  for (const candidate of scriptCandidates) {
93
82
  const scriptBody = scripts[candidate.script];
94
83
  if (!scriptBody)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.41.1-beta.0",
4
- "gitSha": "fbc12f26a410e65b74cb259639de202885609c15",
5
- "builtAt": "2026-08-31T10:40:48.916Z"
3
+ "version": "0.42.0-next.1",
4
+ "gitSha": "fdc98f1393f69abd9a052de266f7199f580e4061",
5
+ "builtAt": "2026-08-31T11:04:06.136Z"
6
6
  }
@@ -31,18 +31,19 @@ import { runDagWorkflowValidate } from "../commands/dag-workflow-validate.js";
31
31
  import { runDagWorkflowCompile } from "../commands/dag-workflow-compile.js";
32
32
  import { runDagWorkflowPlan } from "../commands/dag-workflow-plan.js";
33
33
  import { runDagApprove } from "../commands/dag-approve.js";
34
+ import { runDagArtifact } from "../commands/dag-artifact.js";
34
35
  import { runDagReject } from "../commands/dag-reject.js";
35
36
  import { runDagReconcileTasks } from "../commands/dag-reconcile-tasks.js";
36
37
  import { runDagReconcileRun } from "../commands/dag-reconcile-run.js";
37
38
  import { runDagRequestInterrupt } from "../commands/dag-request-interrupt.js";
38
39
  import { runDagRerunTask } from "../commands/dag-rerun-task.js";
39
- import { runDagFollowUp } from "../commands/dag-follow-up.js";
40
40
  import { runDagRerun } from "../commands/dag-rerun.js";
41
41
  import { runDagResume } from "../commands/dag-resume.js";
42
42
  import { runDagDecisionInspect, runDagDecisionValidate, } from "../workflows/dag/decision-envelope.js";
43
43
  import { runDagDoctor, runDagStatus } from "../workflows/dag/lifecycle.js";
44
44
  import { runDagCloseoutDraft, runDagReport } from "../commands/dag-report.js";
45
45
  import { runDagFinalVerification } from "../commands/dag-final-verification.js";
46
+ import { runDagContext } from "../commands/dag-context.js";
46
47
  import { runKnowledge } from "../commands/knowledge.js";
47
48
  import { runLoopBenchmark } from "../commands/loop-benchmark.js";
48
49
  import { runPiReuseBenchmark } from "../commands/pi-reuse-benchmark.js";
@@ -136,9 +137,10 @@ const DAG_SUBCOMMANDS = [
136
137
  "request-interrupt",
137
138
  "rerun",
138
139
  "rerun-task",
139
- "follow-up",
140
140
  "reconcile-tasks",
141
141
  "final-verification",
142
+ "context",
143
+ "artifact",
142
144
  "decision",
143
145
  ];
144
146
  const TASK_SUBCOMMANDS = ["advance", "status", "source"];
@@ -583,11 +585,6 @@ export const COMMAND_DEFINITIONS = [
583
585
  await runDagRerunTask(repoRoot, rerunTaskArgs);
584
586
  return;
585
587
  }
586
- if (subcommand === "follow-up") {
587
- const followUpArgs = rest.filter((arg) => Boolean(arg));
588
- await runDagFollowUp(repoRoot, followUpArgs);
589
- return;
590
- }
591
588
  if (subcommand === "reconcile-tasks") {
592
589
  const reconcileArgs = rest.filter((arg) => Boolean(arg));
593
590
  await runDagReconcileTasks(repoRoot, reconcileArgs);
@@ -598,6 +595,14 @@ export const COMMAND_DEFINITIONS = [
598
595
  await runDagFinalVerification(repoRoot, finalVerificationArgs);
599
596
  return;
600
597
  }
598
+ if (subcommand === "context") {
599
+ await runDagContext(repoRoot, rest.filter((arg) => Boolean(arg)));
600
+ return;
601
+ }
602
+ if (subcommand === "artifact") {
603
+ await runDagArtifact(repoRoot, rest.filter((arg) => Boolean(arg)));
604
+ return;
605
+ }
601
606
  if (subcommand === "decision") {
602
607
  const decisionSubcommand = rest[0];
603
608
  const decisionArgs = rest