@tea-agent/loop-agent 0.41.1 → 0.42.0-next.10

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 (302) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +397 -5
  3. package/dist/adapters/context-transfer/optional-pi-handoff.js +31 -0
  4. package/dist/adapters/context-transfer/pi-session.js +61 -0
  5. package/dist/application/dag/generate-task-dag.js +75 -19
  6. package/dist/application/dag/run-dag.js +41 -0
  7. package/dist/application/task-lifecycle/advance.js +24 -5
  8. package/dist/application/task-lifecycle/observe.js +171 -17
  9. package/dist/application/task-lifecycle/plan-transitions.js +42 -7
  10. package/dist/application/task-lifecycle/recommendations.js +13 -2
  11. package/dist/build-stamp.json +3 -3
  12. package/dist/cli/command-definitions.js +19 -0
  13. package/dist/cli/program.js +29 -2
  14. package/dist/commands/client-recovery.js +3 -0
  15. package/dist/commands/dag-artifact.js +284 -0
  16. package/dist/commands/dag-context.js +184 -0
  17. package/dist/commands/dag-follow-up.js +138 -0
  18. package/dist/commands/dag-rerun-task.js +2 -0
  19. package/dist/commands/dag-rerun.js +206 -1
  20. package/dist/commands/init.js +27 -1
  21. package/dist/commands/task-advance.js +19 -0
  22. package/dist/executors/dag-pi-executor.js +4013 -86
  23. package/dist/executors/pi-executor.js +15 -4
  24. package/dist/executors/pi-read-budget-policy.js +239 -0
  25. package/dist/executors/pi-sdk-executor.js +3 -0
  26. package/dist/executors/shell-executor.js +978 -188
  27. package/dist/executors/shell-write-guard.js +7 -0
  28. package/dist/{worker → infrastructure}/console/app-data.js +4 -0
  29. package/dist/infrastructure/console/artifact-revision-store.js +430 -0
  30. package/dist/infrastructure/console/context-export-store.js +160 -0
  31. package/dist/infrastructure/console/dir-lock.js +132 -0
  32. package/dist/infrastructure/console/operation-store.js +417 -0
  33. package/dist/infrastructure/harness/artifact-store.js +10 -1
  34. package/dist/infrastructure/harness/atomic-write.js +12 -2
  35. package/dist/shared/context-transfer/artifact-revision.js +172 -0
  36. package/dist/shared/context-transfer.js +418 -0
  37. package/dist/shared/dag-failure-category.js +12 -0
  38. package/dist/shared/openspec-spec.js +70 -4
  39. package/dist/shared/operator/capabilities.js +21 -0
  40. package/dist/shared/operator/safe-run-summary.js +1 -0
  41. package/dist/shared/path-safety.js +93 -0
  42. package/dist/shared/preview.js +28 -4
  43. package/dist/task/config-types.js +107 -6
  44. package/dist/task/contract/adopt.js +4 -0
  45. package/dist/task/contract/import-revision.js +4 -0
  46. package/dist/task/contract/project.js +3 -0
  47. package/dist/task/contract/schema.js +2 -1
  48. package/dist/task/frontend-project-capability.js +203 -20
  49. package/dist/task/runtime.js +5 -2
  50. package/dist/task/source-prepare/build-draft.js +3 -3
  51. package/dist/task/source-prepare/fragment-inventory.js +64 -25
  52. package/dist/task/source-prepare/prepare.js +126 -21
  53. package/dist/task/source-prepare/semantic-intake.js +6 -2
  54. package/dist/task/source-references.js +22 -1
  55. package/dist/task/task-demand-routing.js +3 -0
  56. package/dist/worker/console/chat/chat-event-store.js +2 -2
  57. package/dist/worker/console/chat/model-resolver.js +7 -4
  58. package/dist/worker/console/chat/pi-runtime.js +86 -5
  59. package/dist/worker/console/chat/resource-preferences-store.js +1 -1
  60. package/dist/worker/console/chat/routes.js +136 -53
  61. package/dist/worker/console/chat/sdd-data-alignment.js +222 -0
  62. package/dist/worker/console/chat/session-catalog.js +2 -0
  63. package/dist/worker/console/chat/session-store.js +43 -1
  64. package/dist/worker/console/chat/shortcuts.js +18 -2
  65. package/dist/worker/console/chat/user-questions.js +1 -1
  66. package/dist/worker/console/console-update-runtime.js +1 -1
  67. package/dist/worker/console/context-transfer-diagnostics.js +198 -0
  68. package/dist/worker/console/dag-confirmation.js +1 -1
  69. package/dist/worker/console/dag-execution-receipt.js +1 -1
  70. package/dist/worker/console/doctor.js +1 -1
  71. package/dist/worker/console/draft-store.js +1 -1
  72. package/dist/worker/console/frontend-human-decision-adapter.js +19 -0
  73. package/dist/worker/console/frontend-split-operation-adapter.js +20 -0
  74. package/dist/worker/console/human-gate-token.js +1 -1
  75. package/dist/worker/console/index.js +6 -3
  76. package/dist/worker/console/interview/assessment.js +1 -1
  77. package/dist/worker/console/interview/session.js +1 -1
  78. package/dist/worker/console/operation-runner.js +45 -4
  79. package/dist/worker/console/operation-sse.js +1 -1
  80. package/dist/worker/console/operation-wait.js +1 -1
  81. package/dist/worker/console/operator-actions.js +273 -10
  82. package/dist/worker/console/operator-surface-health.js +1 -1
  83. package/dist/worker/console/operator-user-error.js +169 -0
  84. package/dist/worker/console/pi-plugins.js +57 -0
  85. package/dist/worker/console/pi-readiness.js +3 -2
  86. package/dist/worker/console/routes.js +637 -8
  87. package/dist/worker/console/security.js +35 -0
  88. package/dist/worker/console/server.js +29 -4
  89. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D7oU983t.js → abnfDiagram-N423BO3Z-CcS17TBr.js} +1 -1
  90. package/dist/worker/console/static/assets/{arc-BrKSRdFS.js → arc-COptKq2S.js} +1 -1
  91. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CiXV7L56.js → architectureDiagram-T3A2C74G-h4LKMHjP.js} +1 -1
  92. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-D_Hs_gIG.js → blockDiagram-VBNYF7ZC-COA1MOH0.js} +1 -1
  93. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DbM-Lqqh.js → c4Diagram-5PPSVZJV-DJUf0QPm.js} +1 -1
  94. package/dist/worker/console/static/assets/channel-DdBCaOJ6.js +1 -0
  95. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-D1M8uqJw.js → chunk-2GRJ4B5K-mtWfKrUX.js} +1 -1
  96. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-4D3RFHT6.js → chunk-2Q5K7J3B-B8pXsxDQ.js} +1 -1
  97. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-CdwpY_n9.js → chunk-5RXB4S5H-ipKzByl1.js} +1 -1
  98. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BLeLZ9PG.js → chunk-5VM5RSS4-DYi3Ald_.js} +1 -1
  99. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-CeRNEMvc.js → chunk-6Q2QTUOP-DQtGYoty.js} +1 -1
  100. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CjkHP8Vy.js → chunk-GF5L2VYU-BU0qS2YV.js} +1 -1
  101. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-B54ZUQY-.js → chunk-JWPE2WC7-DVH9dIGE.js} +1 -1
  102. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-4bKaMVmx.js → chunk-KBJHAD2P-Dt60SmgM.js} +1 -1
  103. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-Cyjfznu_.js → chunk-RYQCIY6F-BoaUGuEY.js} +1 -1
  104. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CDN-zGFV.js → chunk-XXDRQBXY-_WHFDTp2.js} +1 -1
  105. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DZFra1GO.js +1 -0
  106. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DZFra1GO.js +1 -0
  107. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-HxJmz411.js → cose-bilkent-JH36ORCC-BxkbTIRd.js} +1 -1
  108. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-DtSt5K2w.js → cynefin-VYW2F7L2-Bf2UVnoG.js} +1 -1
  109. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-VtkSpRmG.js → cynefinDiagram-MW4NZA55-Bo23q1J_.js} +1 -1
  110. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-Bj4DT4du.js → dagre-VZM6K2ZE-Dd_UU49i.js} +1 -1
  111. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-Bpuk6BmP.js → diagram-7IWD3JNH-ebUa1a9y.js} +1 -1
  112. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BHYGv_yO.js → diagram-B4RE2ZJO-BucthU8r.js} +1 -1
  113. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DEx3WwnT.js → diagram-LBJQPF4R-BgqNpAkm.js} +1 -1
  114. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-Cj0dS5e8.js → diagram-Q27KOJAE-DC4q5NGa.js} +1 -1
  115. package/dist/worker/console/static/assets/{diagram-UB23O5K3-B97h8l21.js → diagram-UB23O5K3-CBqCaMeb.js} +1 -1
  116. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DMSFAhBd.js → ebnfDiagram-BXEA7PRR-CGtnbQ3-.js} +1 -1
  117. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DhVOCbt6.js → erDiagram-JOGREHBK-CG3LUao5.js} +1 -1
  118. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-GlakITWL.js → flowDiagram-UKHOOZJN-D2ZVgoFS.js} +1 -1
  119. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-VxPpu9eQ.js → ganttDiagram-PKOTCBZU-DoYFZiKt.js} +1 -1
  120. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bs_e5DRT.js → gitGraphDiagram-DS77QQ5N-CKoP1s6j.js} +1 -1
  121. package/dist/worker/console/static/assets/index-CAZ2fC_X.css +1 -0
  122. package/dist/worker/console/static/assets/index-vbTcFnFs.js +449 -0
  123. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-BXYuU4Uw.js → infoDiagram-6WML65LV-Duofv8p2.js} +1 -1
  124. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C34erCbU.js → ishikawaDiagram-WSZJBQD7-D2nlCkA1.js} +1 -1
  125. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DZCAiOU3.js → journeyDiagram-NVQOT4AX-Dd4IHdus.js} +1 -1
  126. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C9gaTdUm.js → kanban-definition-27J2QSJJ-Bi20AOdt.js} +1 -1
  127. package/dist/worker/console/static/assets/{linear-CvI0Z17U.js → linear-D59YJ9kB.js} +1 -1
  128. package/dist/worker/console/static/assets/{mermaid.core-DMMSIx7j.js → mermaid.core-Bl13LpNa.js} +5 -5
  129. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-BKKP0EO6.js → mindmap-definition-FAOFIHXS-C6DLP5eY.js} +1 -1
  130. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-C3LiFbl5.js → pegDiagram-VL7TDLO6-BjO4cy64.js} +1 -1
  131. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-Bb3Om2Dz.js → pieDiagram-7S7Q4E2Y-D7i2qZTG.js} +1 -1
  132. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-DNthMjzc.js → quadrantDiagram-CIZ2JOQS-Dx8o_h0y.js} +1 -1
  133. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-miFsr4Tv.js → railroadDiagram-AXF67PYL-B55orI_t.js} +1 -1
  134. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-yXUncmn6.js → requirementDiagram-LRYGKXZP-zWaehp6f.js} +1 -1
  135. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-DLeWKLak.js → sankeyDiagram-W5VNT64P-CcA-pjvD.js} +1 -1
  136. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-CI3he1R3.js → sequenceDiagram-SI44F4Z6-BOFbzNHI.js} +1 -1
  137. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-B7jfDkS5.js → sizeCapture-X5ZJPWSS-BjAejah1.js} +1 -1
  138. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BmrZod7J.js → stateDiagram-OKZ733FA-DXYwxJwZ.js} +1 -1
  139. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Clg3V9t1.js +1 -0
  140. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-CDOlHVSY.js → swimlanes-SLNWSIFB-OYiOch8n.js} +2 -2
  141. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DX1dxAAW.js +8 -0
  142. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Cz-XX1gy.js → timeline-definition-Z64GVDOM-cZfH3nmU.js} +1 -1
  143. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-caV4cI8C.js → vennDiagram-T6HMQDX7-BDE7b3E1.js} +1 -1
  144. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-dImPlnIO.js → wardleyDiagram-T6FBY63Y-kyyGy9WJ.js} +1 -1
  145. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CtRYVJcn.js → xychartDiagram-ELKLHX3M-CJj6VTog.js} +1 -1
  146. package/dist/worker/console/static/index.html +7 -2
  147. package/dist/worker/console/static-src/active-run-badge.js +17 -0
  148. package/dist/worker/console/static-src/app/useOperatorActions.js +3 -2
  149. package/dist/worker/console/static-src/app/useRecoveryConsole.js +5 -5
  150. package/dist/worker/console/static-src/operator-chat/input-history.js +8 -6
  151. package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +10 -0
  152. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +258 -23
  153. package/dist/worker/console/static-src/operator-chat/useChatThread.js +112 -4
  154. package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -4
  155. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +29 -6
  156. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +8 -2
  157. package/dist/worker/console/static-src/shell/console-update-reload.js +52 -0
  158. package/dist/worker/console/static-src/shell/workspace-route.js +11 -0
  159. package/dist/worker/console/workspace-context.js +142 -2
  160. package/dist/worker/console/workspace-registry.js +2 -2
  161. package/dist/worker/continuation/worker-continuation.js +278 -0
  162. package/dist/worker/materialize/frontend-split-task-materializer.js +72 -0
  163. package/dist/worker/observe/health.js +1 -1
  164. package/dist/worker/observe/node-transparency.js +572 -0
  165. package/dist/worker/observe/routes.js +55 -1
  166. package/dist/worker/observe/static/api.js +69 -5
  167. package/dist/worker/observe/static/dag-context-reason-labels.d.ts +9 -0
  168. package/dist/worker/observe/static/dag-context-reason-labels.js +120 -0
  169. package/dist/worker/observe/static/dag-helpers.js +4 -2
  170. package/dist/worker/observe/static/dag-node-purpose.js +5 -0
  171. package/dist/worker/observe/static/inspect-workspace.js +23 -0
  172. package/dist/worker/observe/static/kpi.js +2 -2
  173. package/dist/worker/observe/static/operator-chrome.d.ts +10 -2
  174. package/dist/worker/observe/static/operator-chrome.js +37 -23
  175. package/dist/worker/observe/static/relations.js +2 -2
  176. package/dist/worker/observe/static/router.d.ts +12 -1
  177. package/dist/worker/observe/static/router.js +48 -6
  178. package/dist/worker/observe/static/run-processing.js +4 -2
  179. package/dist/worker/observe/static/shell-chrome.js +2 -2
  180. package/dist/worker/observe/static/state.js +8 -1
  181. package/dist/worker/observe/static/styles.css +1092 -86
  182. package/dist/worker/observe/static/views/dag-inspector.js +1228 -64
  183. package/dist/worker/observe/static/views/dag.js +10 -2
  184. package/dist/worker/observe/static/views/dags.js +3 -1
  185. package/dist/worker/observe/static/views/dashboard.js +14 -6
  186. package/dist/worker/observe/static/views/pool.js +7 -2
  187. package/dist/worker/observe/static/views/run.js +12 -3
  188. package/dist/worker/observe/static/views/session-timeline.js +142 -18
  189. package/dist/worker/observe/static/views/task.js +7 -2
  190. package/dist/worker/outcomes/adapters.js +19 -0
  191. package/dist/worker/outcomes/types.js +1 -0
  192. package/dist/worker/pool/attempt-lease.js +97 -66
  193. package/dist/worker/pool/begin-attempt-with-lease.js +1 -0
  194. package/dist/worker/pool/reconcile.js +46 -1
  195. package/dist/worker/pool/run-store.js +2 -0
  196. package/dist/worker/pool/state-projection.js +2 -0
  197. package/dist/worker/task-spec/workflow-routing.js +8 -3
  198. package/dist/workflows/dag/artifact-bindings.js +149 -0
  199. package/dist/workflows/dag/artifact-revision-schema-registry.js +31 -0
  200. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +215 -28
  201. package/dist/workflows/dag/backend-test-markdown-workflow.js +13 -1
  202. package/dist/workflows/dag/backend-test-plan-protocol.js +106 -0
  203. package/dist/workflows/dag/backend-test-scenario-param.js +172 -25
  204. package/dist/workflows/dag/backend-test-scenario-partitions.js +62 -1
  205. package/dist/workflows/dag/backend-test-writer-completeness.js +104 -12
  206. package/dist/workflows/dag/budget-enforcement.js +10 -0
  207. package/dist/workflows/dag/context-receipt.js +305 -0
  208. package/dist/workflows/dag/context-transfer/context-bundle.js +423 -0
  209. package/dist/workflows/dag/context-transfer/operator-actions.js +61 -0
  210. package/dist/workflows/dag/context-transfer/renderers.js +93 -0
  211. package/dist/workflows/dag/contract-validator-registrations.js +1 -2
  212. package/dist/workflows/dag/dag-retry-schema.js +138 -0
  213. package/dist/workflows/dag/frontend-closeout.js +221 -0
  214. package/dist/workflows/dag/frontend-design-policy.js +400 -0
  215. package/dist/workflows/dag/frontend-human-decision.js +182 -0
  216. package/dist/workflows/dag/frontend-implementation-contract.js +1237 -192
  217. package/dist/workflows/dag/frontend-plan-render.js +2 -1
  218. package/dist/workflows/dag/frontend-prewrite-gate.js +256 -350
  219. package/dist/workflows/dag/frontend-provider-capability-matrix.js +159 -0
  220. package/dist/workflows/dag/frontend-recovery-capsule.js +455 -0
  221. package/dist/workflows/dag/frontend-recovery-controller.js +226 -0
  222. package/dist/workflows/dag/frontend-recovery-lineage.js +178 -0
  223. package/dist/workflows/dag/frontend-recovery-plan.js +21 -10
  224. package/dist/workflows/dag/frontend-recovery-run.js +166 -34
  225. package/dist/workflows/dag/frontend-repair.js +1 -432
  226. package/dist/workflows/dag/frontend-review-context.js +261 -15
  227. package/dist/workflows/dag/frontend-review-findings.js +270 -0
  228. package/dist/workflows/dag/frontend-shadow-dual-write.js +941 -0
  229. package/dist/workflows/dag/frontend-shape-capsule-store.js +191 -0
  230. package/dist/workflows/dag/frontend-shape-facts.js +419 -0
  231. package/dist/workflows/dag/frontend-shape.js +435 -0
  232. package/dist/workflows/dag/frontend-source-fidelity-ledger.js +108 -0
  233. package/dist/workflows/dag/frontend-split-application-service.js +203 -0
  234. package/dist/workflows/dag/frontend-split-orchestrator.js +899 -0
  235. package/dist/workflows/dag/frontend-typed-event-store.js +452 -0
  236. package/dist/workflows/dag/frontend-typed-event-transaction.js +180 -0
  237. package/dist/workflows/dag/frontend-verification-trace.js +252 -25
  238. package/dist/workflows/dag/frontend-worktree-diff.js +250 -17
  239. package/dist/workflows/dag/frontend-writer-admission.js +319 -0
  240. package/dist/workflows/dag/frontend-writer-rollback.js +32 -0
  241. package/dist/workflows/dag/frontend-writer-status.js +256 -0
  242. package/dist/workflows/dag/init-hybrid.js +1174 -562
  243. package/dist/workflows/dag/interrupt-request.js +7 -0
  244. package/dist/workflows/dag/node-execution.js +940 -31
  245. package/dist/workflows/dag/path-safety.js +1 -0
  246. package/dist/workflows/dag/prompt.js +99 -7
  247. package/dist/workflows/dag/recovery-lease.js +170 -0
  248. package/dist/workflows/dag/report.js +37 -1
  249. package/dist/workflows/dag/rerun-feedback.js +315 -1
  250. package/dist/workflows/dag/rerun-plan.js +568 -3
  251. package/dist/workflows/dag/rerun-run.js +642 -18
  252. package/dist/workflows/dag/rerun-task.js +251 -13
  253. package/dist/workflows/dag/retry-policy.js +219 -104
  254. package/dist/workflows/dag/runner.js +596 -121
  255. package/dist/workflows/dag/scheduler.js +133 -20
  256. package/dist/workflows/dag/skill-snapshot.js +17 -0
  257. package/dist/workflows/dag/types.js +426 -22
  258. package/dist/workflows/dag/validate.js +28 -12
  259. package/docs/architecture/runtime-boundaries.md +6 -6
  260. package/docs/architecture/worker-and-feature.md +1 -1
  261. package/docs/examples/README.md +5 -0
  262. package/docs/init-surface.manifest.json +30 -12
  263. package/docs/skills/vetted-skill-registry.md +4 -2
  264. package/docs/templates/README.md +2 -0
  265. package/docs/templates/agent-dag-report.schema.json +8 -2
  266. package/docs/templates/agent-dag.schema.json +33 -1
  267. package/docs/templates/backend-test-dag.json +23 -20
  268. package/docs/templates/frontend-implementation-contract.schema.json +4 -1
  269. package/docs/templates/frontend-implementation-dag.json +89 -0
  270. package/docs/templates/product-line/task.yaml +1 -1
  271. package/docs/templates/spec-registry.schema.json +45 -0
  272. package/harness.json +1 -1
  273. package/package.json +6 -3
  274. package/skills/frontend-bounded-implement/SKILL.md +15 -14
  275. package/skills/frontend-bounded-implement/references/code-standards.md +19 -0
  276. package/skills/frontend-contract/SKILL.md +23 -0
  277. package/skills/frontend-contract/references/contract-protocol.md +34 -0
  278. package/skills/frontend-design-review/SKILL.md +22 -41
  279. package/skills/frontend-plan/SKILL.md +26 -0
  280. package/skills/frontend-plan/references/decision-contract.md +37 -0
  281. package/skills/frontend-plan/references/design-decisions.md +17 -0
  282. package/skills/frontend-review/SKILL.md +20 -15
  283. package/skills/frontend-review/references/review-findings.md +6 -7
  284. package/skills/frontend-scout/SKILL.md +25 -0
  285. package/skills/frontend-scout/references/design-evidence.md +16 -0
  286. package/skills/frontend-scout/references/scout-evidence.md +23 -0
  287. package/skills/frontend-verification/SKILL.md +1 -1
  288. package/skills/loop-agent/references/command-reference.md +7 -0
  289. package/skills/loop-agent/references/hybrid-dag.md +2 -2
  290. package/dist/worker/console/operation-store.js +0 -169
  291. package/dist/worker/console/static/assets/channel-D1xajGpe.js +0 -1
  292. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BmuGTfRr.js +0 -1
  293. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BmuGTfRr.js +0 -1
  294. package/dist/worker/console/static/assets/index-BLzcAykx.js +0 -451
  295. package/dist/worker/console/static/assets/index-Cs9JUSPs.css +0 -1
  296. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-D9ykKEWP.js +0 -1
  297. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BvPOXALT.js +0 -8
  298. package/skills/frontend-implementation/SKILL.md +0 -52
  299. package/skills/frontend-implementation/references/code-standards.md +0 -33
  300. package/skills/frontend-implementation/references/design-spec.md +0 -56
  301. package/skills/frontend-implementation/references/node-contracts.md +0 -31
  302. /package/dist/{worker → infrastructure}/console/repo-fingerprint.js +0 -0
@@ -1,14 +1,19 @@
1
1
  import { access, readFile } from "node:fs/promises";
2
+ import { createHash } from "node:crypto";
2
3
  import path from "node:path";
3
4
  import { generateTaskDagUseCase } from "../../application/dag/generate-task-dag.js";
5
+ import { buildDefaultFrontendRecoveryDeps, } from "../../application/dag/run-dag.js";
6
+ import { runDagContinuation, } from "./runner.js";
7
+ import { stageRecoveryChild } from "./frontend-recovery-run.js";
4
8
  import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
5
9
  import { DAG_RUNS_DIR, isTerminalDagRunStatus, locateDagRun, readDagRunSpec, readDagRunState, } from "./lifecycle.js";
6
10
  import { deriveDagRerunFeedback } from "./rerun-feedback.js";
11
+ import { acquireDagRecoveryLease, bindDagRecoveryLeaseExecution, } from "./recovery-lease.js";
7
12
  import { parseDagSpec, } from "./types.js";
8
13
  export const RERUN_TASK_LINEAGE_REL_PATH = ".runtime/rerun-task-lineage.json";
9
14
  export function parseDagRerunTaskArgs(args) {
10
15
  if (args.length === 0) {
11
- throw new Error("usage: dag rerun-task --run-id <id> --reason <text> --request-id <key> [--profile auto|minimal|standard|reviewed|supervised] [--task-id <id>] [--json]");
16
+ throw new Error("usage: dag rerun-task --run-id <id> --reason <text> --request-id <key> [--profile auto|minimal|standard|reviewed|supervised] [--task-id <id>] [--frontend-recovery --recovery-operation-id <id>] [--json]");
12
17
  }
13
18
  let parentRunId;
14
19
  let reason;
@@ -17,6 +22,8 @@ export function parseDagRerunTaskArgs(args) {
17
22
  let profileExplicit = false;
18
23
  let taskIdOverride;
19
24
  let execute = true;
25
+ let frontendRecovery = false;
26
+ let recoveryOperationId;
20
27
  for (let index = 0; index < args.length; index += 1) {
21
28
  const arg = args[index];
22
29
  if (arg === "--run-id")
@@ -47,6 +54,12 @@ export function parseDagRerunTaskArgs(args) {
47
54
  continue;
48
55
  else if (arg === "--no-execute")
49
56
  execute = false;
57
+ else if (arg === "--frontend-recovery")
58
+ frontendRecovery = true;
59
+ else if (arg === "--recovery-operation-id")
60
+ recoveryOperationId = args[++index];
61
+ else if (arg.startsWith("--recovery-operation-id="))
62
+ recoveryOperationId = arg.slice("--recovery-operation-id=".length);
50
63
  else if (arg.startsWith("-"))
51
64
  throw new Error(`unknown dag rerun-task flag: ${arg}`);
52
65
  else
@@ -69,6 +82,48 @@ export function parseDagRerunTaskArgs(args) {
69
82
  profileExplicit,
70
83
  ...(taskIdOverride?.trim() ? { taskIdOverride: taskIdOverride.trim() } : {}),
71
84
  execute,
85
+ frontendRecovery,
86
+ ...(recoveryOperationId ? { recoveryOperationId } : {}),
87
+ };
88
+ }
89
+ const frontendRecoveryDescriptorPath = (runDir, requestId) => path.join(runDir, ".runtime", "frontend-recovery", `${requestId}.json`);
90
+ async function readFrontendRecoveryDescriptor(runDir, parentRunId, requestId) {
91
+ const raw = JSON.parse(await readFile(frontendRecoveryDescriptorPath(runDir, requestId), "utf8"));
92
+ const plan = raw.plan;
93
+ if (raw.schemaVersion !== 1 ||
94
+ raw.parentRunId !== parentRunId ||
95
+ raw.requestId !== requestId ||
96
+ typeof raw.failureSource !== "string" ||
97
+ typeof raw.recoveryMode !== "string" ||
98
+ typeof raw.planHash !== "string" ||
99
+ !plan ||
100
+ plan.schemaVersion !== 1 ||
101
+ plan.parentRunId !== parentRunId ||
102
+ plan.requestId !== requestId ||
103
+ !Array.isArray(plan.resetNodeIds) ||
104
+ !Array.isArray(plan.importedNodeIds)) {
105
+ throw new Error("frontend recovery descriptor is invalid or unbound");
106
+ }
107
+ const expectedHash = createHash("sha256")
108
+ .update(JSON.stringify(plan))
109
+ .digest("hex");
110
+ if (raw.planHash !== expectedHash) {
111
+ throw new Error("frontend recovery descriptor plan hash mismatch");
112
+ }
113
+ return raw;
114
+ }
115
+ function buildFrontendRecoveryIntent(input) {
116
+ return {
117
+ schemaVersion: 1,
118
+ phase: "child-staging",
119
+ requestId: input.requestId,
120
+ recoveryRootRunId: input.parentRecovery?.recoveryRootRunId ?? input.parentRunId,
121
+ parentRunId: input.parentRunId,
122
+ attemptId: input.requestId,
123
+ attemptIndex: input.parentRecovery?.attemptIndex ?? 0,
124
+ continuationCount: input.parentRecovery?.continuationCount ?? 0,
125
+ failureSource: input.failureSource,
126
+ revision: 0,
72
127
  };
73
128
  }
74
129
  function parseDagRerunTaskProfile(value) {
@@ -135,6 +190,21 @@ function resolveTaskIdForRerun(spec, taskIdOverride) {
135
190
  function operatorRequestPath(cwd, requestId) {
136
191
  return path.join(cwd, DAG_RUNS_DIR, ".operator-requests", `${requestId}.json`);
137
192
  }
193
+ function computeRerunTaskRequestHash(input) {
194
+ return createHash("sha256")
195
+ .update(JSON.stringify({
196
+ parentRunId: input.parentRunId,
197
+ reason: input.reason,
198
+ requestId: input.requestId,
199
+ profile: input.profile ?? "auto",
200
+ profileExplicit: input.profileExplicit ?? false,
201
+ taskIdOverride: input.taskIdOverride ?? null,
202
+ execute: input.execute ?? true,
203
+ frontendRecovery: input.frontendRecovery ?? false,
204
+ recoveryOperationId: input.recoveryOperationId ?? null,
205
+ }))
206
+ .digest("hex");
207
+ }
138
208
  async function fileExists(filePath) {
139
209
  try {
140
210
  await access(filePath);
@@ -184,23 +254,45 @@ export async function assessGeneratedOutputConflict(spec, cwd) {
184
254
  }
185
255
  return conflictPaths;
186
256
  }
187
- async function readExistingOperatorRequest(cwd, requestId) {
257
+ async function readExistingOperatorRequest(cwd, requestId, expected) {
258
+ let raw;
188
259
  try {
189
- const raw = JSON.parse(await readFile(operatorRequestPath(cwd, requestId), "utf-8"));
190
- if (raw.result && typeof raw.result === "object") {
191
- return { ...raw.result, idempotentReplay: true };
260
+ raw = JSON.parse(await readFile(operatorRequestPath(cwd, requestId), "utf-8"));
261
+ }
262
+ catch (error) {
263
+ if (error &&
264
+ typeof error === "object" &&
265
+ "code" in error &&
266
+ error.code === "ENOENT") {
267
+ return undefined;
192
268
  }
269
+ throw new Error(`invalid persisted rerun-task operator request: ${error instanceof Error ? error.message : String(error)}`);
193
270
  }
194
- catch {
195
- // not found or unreadable
271
+ if (raw.schemaVersion !== 1 ||
272
+ raw.kind !== "standalone-task-rerun-request" ||
273
+ raw.requestId !== requestId) {
274
+ throw new Error("REQUEST_ID_REUSE_CONFLICT: operator request id belongs to a different request kind");
275
+ }
276
+ if (raw.parentRunId !== expected.parentRunId ||
277
+ raw.requestHash !== expected.requestHash) {
278
+ throw new Error("REQUEST_ID_REUSE_CONFLICT: rerun-task operator request payload drifted");
196
279
  }
197
- return undefined;
280
+ const result = raw.result;
281
+ if (!result ||
282
+ typeof result !== "object" ||
283
+ Array.isArray(result) ||
284
+ result.parentRunId !== expected.parentRunId ||
285
+ result.requestId !== requestId) {
286
+ throw new Error("invalid persisted rerun-task operator request result");
287
+ }
288
+ return { ...result, idempotentReplay: true };
198
289
  }
199
- async function persistOperatorRequest(cwd, result) {
290
+ async function persistOperatorRequest(cwd, result, requestHash) {
200
291
  await writeJsonAtomic(operatorRequestPath(cwd, result.requestId), {
201
292
  schemaVersion: 1,
202
293
  kind: "standalone-task-rerun-request",
203
294
  parentRunId: result.parentRunId,
295
+ requestHash,
204
296
  newRunId: result.newRunId,
205
297
  taskId: result.taskId,
206
298
  reason: result.reason,
@@ -263,8 +355,106 @@ function extractNewRunId(generateResult) {
263
355
  const runSummary = extractRunSummary(generateResult);
264
356
  return runSummary?.runId;
265
357
  }
358
+ async function executeFrontendRecoveryContinuation(input) {
359
+ const located = await locateDagRun(input.cwd, input.parentRunId);
360
+ if (!located || located.lifecycle !== "active") {
361
+ throw new Error(`frontend recovery parent run must remain active: ${input.parentRunId}`);
362
+ }
363
+ const lease = await acquireDagRecoveryLease({
364
+ cwd: input.cwd,
365
+ parentRunId: input.parentRunId,
366
+ requestId: input.requestId,
367
+ kind: "standalone-task-rerun",
368
+ });
369
+ if (lease.kind !== "held" ||
370
+ lease.lease.kind !== "auto-frontend-recovery" ||
371
+ lease.lease.requestId !== input.requestId ||
372
+ !input.recoveryOperationId ||
373
+ lease.lease.executionRef !== input.recoveryOperationId) {
374
+ return blockedResult({
375
+ parentRunId: input.parentRunId,
376
+ reason: input.reason,
377
+ requestId: input.requestId,
378
+ blockedReason: "recovery-lease-held",
379
+ note: "frontend recovery operation is not the owner of the parent recovery lease",
380
+ });
381
+ }
382
+ const descriptor = await readFrontendRecoveryDescriptor(located.runDir, input.parentRunId, input.requestId);
383
+ const parentState = await readDagRunState(located.runDir);
384
+ const staged = await stageRecoveryChild({
385
+ cwd: input.cwd,
386
+ parentRunId: input.parentRunId,
387
+ recoveryIntent: buildFrontendRecoveryIntent({
388
+ parentRunId: input.parentRunId,
389
+ requestId: input.requestId,
390
+ failureSource: descriptor.failureSource,
391
+ parentRecovery: parentState.frontendRecoveryState,
392
+ }),
393
+ recoveryPlan: descriptor.plan,
394
+ });
395
+ const locatedChild = await locateDagRun(input.cwd, staged.childRunId);
396
+ if (!locatedChild || locatedChild.runDir !== staged.childRunDir) {
397
+ throw new Error(`frontend recovery child lifecycle drift: ${staged.childRunId}`);
398
+ }
399
+ const childSpec = await readDagRunSpec(locatedChild.runDir);
400
+ const childState = await readDagRunState(locatedChild.runDir);
401
+ let runSummary;
402
+ if (locatedChild.lifecycle === "completed" ||
403
+ locatedChild.lifecycle === "paused") {
404
+ runSummary = {
405
+ title: childState.title,
406
+ runId: childState.runId,
407
+ status: childState.status,
408
+ ranks: childState.ranks,
409
+ nodes: childState.nodes,
410
+ runDir: locatedChild.runDir,
411
+ };
412
+ }
413
+ else {
414
+ const childRecovery = childSpec.tasks.some((task) => task.id === "frontend-implement-pi")
415
+ ? input.recovery ?? await buildDefaultFrontendRecoveryDeps(input.cwd)
416
+ : undefined;
417
+ runSummary = await runDagContinuation({
418
+ cwd: input.cwd,
419
+ spec: childSpec,
420
+ state: childState,
421
+ runDir: locatedChild.runDir,
422
+ ...(childRecovery ? { recovery: childRecovery } : {}),
423
+ });
424
+ }
425
+ const settledChild = await locateDagRun(input.cwd, staged.childRunId);
426
+ const settledChildState = settledChild
427
+ ? await readDagRunState(settledChild.runDir)
428
+ : childState;
429
+ const feedback = summarizeFeedback(childSpec.rerunFeedback, "no-unresolved-verify-review-feedback");
430
+ const result = {
431
+ ok: runSummary.status === "finished" ||
432
+ settledChildState.frontendRecoveryResult?.outcome === "recovered",
433
+ parentRunId: input.parentRunId,
434
+ newRunId: staged.childRunId,
435
+ taskId: childSpec.taskContractBinding?.taskId ??
436
+ childSpec.sourceBinding?.taskId,
437
+ reason: input.reason,
438
+ requestId: input.requestId,
439
+ mode: "generate+validate+execute",
440
+ feedback,
441
+ runSummary,
442
+ };
443
+ await writeRerunTaskLineage(input.cwd, staged.childRunId, {
444
+ parentRunId: input.parentRunId,
445
+ reason: input.reason,
446
+ requestId: input.requestId,
447
+ feedback,
448
+ });
449
+ await persistOperatorRequest(input.cwd, result, input.requestHash);
450
+ return result;
451
+ }
266
452
  export async function rerunStandaloneTask(input) {
267
- const existing = await readExistingOperatorRequest(input.cwd, input.requestId);
453
+ const requestHash = computeRerunTaskRequestHash(input);
454
+ const existing = await readExistingOperatorRequest(input.cwd, input.requestId, {
455
+ parentRunId: input.parentRunId,
456
+ requestHash,
457
+ });
268
458
  if (existing) {
269
459
  return existing;
270
460
  }
@@ -297,6 +487,17 @@ export async function rerunStandaloneTask(input) {
297
487
  note: eligibility.note,
298
488
  });
299
489
  }
490
+ if (input.frontendRecovery) {
491
+ return executeFrontendRecoveryContinuation({
492
+ cwd: input.cwd,
493
+ parentRunId: input.parentRunId,
494
+ reason: input.reason,
495
+ requestId: input.requestId,
496
+ requestHash,
497
+ recoveryOperationId: input.recoveryOperationId,
498
+ recovery: input.recovery,
499
+ });
500
+ }
300
501
  let parentFeedback;
301
502
  let missingFeedbackReason = "no-unresolved-verify-review-feedback";
302
503
  try {
@@ -308,12 +509,18 @@ export async function rerunStandaloneTask(input) {
308
509
  state,
309
510
  });
310
511
  }
311
- catch {
512
+ catch (error) {
513
+ if (state.terminalReason === "design-request-changes") {
514
+ throw new Error(`frontend design recovery feedback unavailable: ${error instanceof Error ? error.message : String(error)}`);
515
+ }
312
516
  // Feedback is additive recovery context. A corrupt/missing historical
313
517
  // artifact must be reported honestly but must not block an otherwise
314
518
  // eligible full rerun.
315
519
  missingFeedbackReason = "feedback-unavailable";
316
520
  }
521
+ if (state.terminalReason === "design-request-changes" && !parentFeedback) {
522
+ throw new Error("frontend design recovery feedback unavailable: no typed findings were found");
523
+ }
317
524
  const execute = input.execute ?? true;
318
525
  let effectiveFeedback;
319
526
  let expectedRerunFeedbackDigest;
@@ -369,6 +576,34 @@ export async function rerunStandaloneTask(input) {
369
576
  }
370
577
  }
371
578
  }
579
+ const recoveryLease = execute
580
+ ? await acquireDagRecoveryLease({
581
+ cwd: input.cwd,
582
+ parentRunId: input.parentRunId,
583
+ requestId: input.requestId,
584
+ kind: "standalone-task-rerun",
585
+ })
586
+ : undefined;
587
+ if (recoveryLease?.kind === "held") {
588
+ return blockedResult({
589
+ parentRunId: input.parentRunId,
590
+ reason: input.reason,
591
+ requestId: input.requestId,
592
+ blockedReason: "recovery-lease-held",
593
+ note: `parent run recovery is already claimed by ${recoveryLease.lease.kind} request ${recoveryLease.lease.requestId}`,
594
+ taskId: taskResolution.taskId,
595
+ });
596
+ }
597
+ if (recoveryLease?.kind === "acquired") {
598
+ // Persist a non-empty execution identity before generateTaskDagUseCase can
599
+ // execute its new DAG. The generated run id is not available yet, so the
600
+ // request id is the stable lineage handle for this entry point.
601
+ await bindDagRecoveryLeaseExecution({
602
+ leasePath: recoveryLease.leasePath,
603
+ lease: recoveryLease.lease,
604
+ executionRef: `standalone-task-rerun:${input.requestId}`,
605
+ });
606
+ }
372
607
  const generateResult = await generateTaskDagUseCase({
373
608
  repoRoot: input.cwd,
374
609
  taskId: taskResolution.taskId,
@@ -420,10 +655,13 @@ export async function rerunStandaloneTask(input) {
420
655
  ...(runSummary ? { runSummary } : {}),
421
656
  };
422
657
  if (await fileExists(operatorRequestPath(input.cwd, input.requestId))) {
423
- const replay = await readExistingOperatorRequest(input.cwd, input.requestId);
658
+ const replay = await readExistingOperatorRequest(input.cwd, input.requestId, {
659
+ parentRunId: input.parentRunId,
660
+ requestHash,
661
+ });
424
662
  if (replay)
425
663
  return replay;
426
664
  }
427
- await persistOperatorRequest(input.cwd, result);
665
+ await persistOperatorRequest(input.cwd, result, requestHash);
428
666
  return result;
429
667
  }