@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
@@ -3,7 +3,8 @@ import path from "node:path";
3
3
  import { isPauseOnHumanDecisionGate } from "./decision-envelope.js";
4
4
  import { evaluateConditionExpression } from "./dynamic-runtime/condition.js";
5
5
  import { sha256Hex } from "./frontend-implementation-contract.js";
6
- import { frontendPrewriteResultV1Schema, FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME, } from "./frontend-prewrite-gate.js";
6
+ import { boundaryForTargetNode, computeFrontendShapeNodeDigest, evaluateFrontendShapeBoundary, } from "./frontend-shape-facts.js";
7
+ import { FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT, frontendWriterAdmissionResultV1Schema, normalizeConcreteWriteSetPath, } from "./frontend-writer-admission.js";
7
8
  import { FRONTEND_RECOVERY_IMPORT_MANIFEST_REL_PATH, FRONTEND_RECOVERY_INTENT_REL_DIR, } from "./frontend-recovery-plan.js";
8
9
  export function isConditionSkippedReason(reason) {
9
10
  return Boolean(reason?.startsWith("condition "));
@@ -111,16 +112,25 @@ async function mapConcurrent(items, limit, fn) {
111
112
  }
112
113
  export const FRONTEND_WRITER_NODE_IDS = [
113
114
  "frontend-implement-pi",
114
- "frontend-repair-pi",
115
115
  ];
116
- /** Run-relative artifact location written by the prewrite gate generator. */
117
- export const FRONTEND_PREWRITE_RESULT_SOURCE_ARTIFACT = path.posix.join("contracts", FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME);
118
116
  /**
119
- * Read and validate the frontend-prewrite-result-v1 artifact. Fail-closed:
120
- * a missing file or invalid payload returns ok:false and never throws.
117
+ * Run-relative artifact location read by the frontend writer admission gate.
118
+ * M8 re-pointed the legacy prewrite-result source at the new
119
+ * frontend-writer-admission-result.json artifact (written by the
120
+ * frontend-writer-admission-shell); the exported name is retained because
121
+ * runner.ts / node-execution.ts reference it as the admission evidence source.
122
+ */
123
+ export const FRONTEND_PREWRITE_RESULT_SOURCE_ARTIFACT = FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT;
124
+ export { FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT };
125
+ /**
126
+ * Read and validate the writer admission result artifact.
127
+ * Fail-closed: a missing file or invalid payload returns ok:false and never
128
+ * throws. This is the M8 write authorization source (replaces the legacy
129
+ * frontend-prewrite-result-v1 for dispatch; the legacy artifact remains
130
+ * produced only by the shadow `runFrontendPrewriteGate` library export).
121
131
  */
122
132
  export async function readFrontendPrewriteResult(runDir) {
123
- const artifactPath = path.join(runDir, "contracts", FRONTEND_PREWRITE_RESULT_ARTIFACT_NAME);
133
+ const artifactPath = path.join(runDir, FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT);
124
134
  let raw;
125
135
  try {
126
136
  raw = await readFile(artifactPath, "utf8");
@@ -129,7 +139,7 @@ export async function readFrontendPrewriteResult(runDir) {
129
139
  if (error.code === "ENOENT") {
130
140
  return {
131
141
  ok: false,
132
- reason: `frontend prewrite result artifact missing: ${artifactPath}`,
142
+ reason: `frontend writer admission artifact missing: ${artifactPath}`,
133
143
  };
134
144
  }
135
145
  throw error;
@@ -142,24 +152,29 @@ export async function readFrontendPrewriteResult(runDir) {
142
152
  catch (error) {
143
153
  return {
144
154
  ok: false,
145
- reason: `frontend prewrite result artifact is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
155
+ reason: `frontend writer admission artifact is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,
146
156
  };
147
157
  }
148
- const result = frontendPrewriteResultV1Schema.safeParse(parsed);
158
+ const result = frontendWriterAdmissionResultV1Schema.safeParse(parsed);
149
159
  if (!result.success) {
150
160
  return {
151
161
  ok: false,
152
- reason: "frontend prewrite result artifact failed schema validation",
162
+ reason: "frontend writer admission artifact failed schema validation",
153
163
  };
154
164
  }
155
165
  return { ok: true, result: result.data, artifactHash };
156
166
  }
157
- /** Authorize only accepted / accepted-normalized classifications. */
167
+ /**
168
+ * M8 alias: read the writer admission result artifact under the explicit name.
169
+ * Same fail-closed semantics as `readFrontendPrewriteResult`.
170
+ */
171
+ export async function readFrontendWriterAdmissionResult(runDir) {
172
+ return readFrontendPrewriteResult(runDir);
173
+ }
174
+ /** Authorize only the `accepted` classification (four-state admission).
175
+ * `requires-human-approval`, `blocked`, and `stale` are all denied. */
158
176
  export function isFrontendWriterAuthorized(result) {
159
- return result.classification === "accepted" ||
160
- result.classification === "accepted-normalized"
161
- ? "authorized"
162
- : "denied";
177
+ return result.classification === "accepted" ? "authorized" : "denied";
163
178
  }
164
179
  /** Fail-closed: leave no PENDING nodes that look "still scheduled" after abort. */
165
180
  export function markPendingNodesControllerInterrupted(state, reason = "run aborted by controller (abortSignal)") {
@@ -399,6 +414,12 @@ export async function executeDagRanksOnce(input) {
399
414
  continue;
400
415
  }
401
416
  const decision = isFrontendWriterAuthorized(admission.result);
417
+ const normalizedWriteSet = admission.result.writeSet
418
+ .map(normalizeConcreteWriteSetPath)
419
+ .filter((entry) => entry !== undefined);
420
+ const concreteWriteSetValid = (admission.result.writeSet.length > 0 &&
421
+ normalizedWriteSet.length === admission.result.writeSet.length &&
422
+ new Set(normalizedWriteSet).size === normalizedWriteSet.length);
402
423
  node.frontendWriterAdmission = {
403
424
  schemaVersion: 1,
404
425
  writerNodeId: id,
@@ -410,18 +431,110 @@ export async function executeDagRanksOnce(input) {
410
431
  ? `classification: ${admission.result.classification}`
411
432
  : null,
412
433
  };
413
- if (decision === "denied") {
434
+ if (decision === "denied" || !concreteWriteSetValid) {
435
+ node.frontendWriterAdmission.reason = decision === "denied"
436
+ ? `classification: ${admission.result.classification}`
437
+ : "admission writeSet is not a concrete unique path set";
414
438
  node.status = "SKIPPED";
415
439
  node.skippedReason = "frontend-prewrite-not-authorized";
416
440
  node.finishedAt = checkedAt;
417
441
  frontendAdmissionSettled.push(id);
418
442
  }
443
+ else {
444
+ node.runtimeWriteAuthorization = {
445
+ schemaVersion: 1,
446
+ status: "validated",
447
+ approvalSourceNodeId: FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT,
448
+ approvalDigest: admission.result.admissionDigest,
449
+ effectiveWriteSet: normalizedWriteSet,
450
+ };
451
+ }
419
452
  }
420
453
  if (frontendAdmissionSettled.length > 0)
421
454
  await input.persistState();
422
455
  }
423
456
  const frontendAdmissionSkippedSet = new Set(frontendAdmissionSettled);
424
457
  const runnableAfterAdmission = actuallyRunnable.filter((id) => !frontendAdmissionSkippedSet.has(id));
458
+ // Shape boundaries are rank gates: evaluate every protected candidate
459
+ // before creating an executor or starting any sibling in the rank.
460
+ const shapeBlocked = new Set();
461
+ const checkedBoundaries = new Set();
462
+ let shapeTerminalCommitted = false;
463
+ for (const id of runnableAfterAdmission) {
464
+ const mapping = boundaryForTargetNode(id);
465
+ if (!mapping || checkedBoundaries.has(mapping.boundary))
466
+ continue;
467
+ checkedBoundaries.add(mapping.boundary);
468
+ const sourceNode = input.state.nodes[mapping.sourceNodeId];
469
+ const fact = input.state.frontendShapeState?.committedFacts[mapping.boundary];
470
+ const outcome = evaluateFrontendShapeBoundary({
471
+ boundary: mapping.boundary,
472
+ sourceNode: sourceNode
473
+ ? { status: sourceNode.status, digest: computeFrontendShapeNodeDigest(sourceNode) }
474
+ : undefined,
475
+ fact,
476
+ });
477
+ if (outcome.kind === "continue") {
478
+ if (input.state.frontendShapeState) {
479
+ input.state.frontendShapeState.lastBoundary = mapping.boundary;
480
+ input.state.frontendShapeState.lastOutcome = outcome.kind;
481
+ await input.persistState();
482
+ }
483
+ continue;
484
+ }
485
+ if (outcome.kind === "blocked") {
486
+ if (input.state.frontendShapeState) {
487
+ input.state.frontendShapeState.lastBoundary = mapping.boundary;
488
+ input.state.frontendShapeState.lastOutcome = outcome.kind;
489
+ }
490
+ const finishedAt = new Date().toISOString();
491
+ for (const targetId of mapping.targetNodeIds) {
492
+ if (!runnableAfterAdmission.includes(targetId))
493
+ continue;
494
+ const node = input.state.nodes[targetId];
495
+ if (!node || node.status !== "PENDING")
496
+ continue;
497
+ node.status = "SKIPPED";
498
+ node.skippedReason = outcome.reason;
499
+ node.finishedAt = finishedAt;
500
+ shapeBlocked.add(targetId);
501
+ }
502
+ await input.persistState();
503
+ continue;
504
+ }
505
+ if (!fact || !input.commitFrontendShapeTransition) {
506
+ const finishedAt = new Date().toISOString();
507
+ for (const targetId of mapping.targetNodeIds) {
508
+ const node = input.state.nodes[targetId];
509
+ if (!node || node.status !== "PENDING")
510
+ continue;
511
+ node.status = "SKIPPED";
512
+ node.skippedReason = "frontend-shape-transition-cas-unavailable";
513
+ node.finishedAt = finishedAt;
514
+ shapeBlocked.add(targetId);
515
+ }
516
+ await input.persistState();
517
+ continue;
518
+ }
519
+ const committed = await input.commitFrontendShapeTransition({
520
+ boundary: mapping.boundary,
521
+ outcome: outcome.kind,
522
+ reason: outcome.reason,
523
+ expectedRevision: input.state.frontendShapeState?.revision ?? 0,
524
+ fact,
525
+ });
526
+ if (committed.ok) {
527
+ shapeTerminalCommitted = true;
528
+ break;
529
+ }
530
+ // A failed transition CAS must remain zero-write. Stop the controller
531
+ // before any executor starts; never compensate with a capsule-less
532
+ // terminal state or mutate pending descendants.
533
+ throw new Error(`frontend shape transition CAS failed at ${mapping.boundary}: ${committed.reason}`);
534
+ }
535
+ if (shapeTerminalCommitted)
536
+ break;
537
+ const runnableAfterShape = runnableAfterAdmission.filter((id) => !shapeBlocked.has(id));
425
538
  const blocked = pending.filter((id) => {
426
539
  const task = input.tasksById.get(id);
427
540
  return (dependencyReadiness(task, input.state.nodes, input.tasksById) === "skip");
@@ -436,12 +549,12 @@ export async function executeDagRanksOnce(input) {
436
549
  if (blocked.length > 0) {
437
550
  await input.persistState();
438
551
  }
439
- const pauseGateRunnable = runnableAfterAdmission.filter((id) => {
552
+ const pauseGateRunnable = runnableAfterShape.filter((id) => {
440
553
  const task = input.tasksById.get(id);
441
554
  return isPauseOnHumanDecisionGate(task);
442
555
  });
443
- const regularRunnable = runnableAfterAdmission.filter((id) => !pauseGateRunnable.includes(id));
444
- const rankWriterNodeIds = runnableAfterAdmission.filter((id) => {
556
+ const regularRunnable = runnableAfterShape.filter((id) => !pauseGateRunnable.includes(id));
557
+ const rankWriterNodeIds = runnableAfterShape.filter((id) => {
445
558
  const task = input.tasksById.get(id);
446
559
  return (task?.executor === "pi" &&
447
560
  task.toolProfile === "write" &&
@@ -333,11 +333,27 @@ function parseSnapshot(value) {
333
333
  export async function cloneParentSkillSnapshotForContinuation(input) {
334
334
  const parentSnapshot = await readSkillSnapshot(input.parentRunDir, input.parentRef, { expectedRunId: input.parentRunId });
335
335
  const parentSnapshotSha256 = hashSkillSnapshot(parentSnapshot);
336
+ const initialTaskIds = input.spec
337
+ ? input.spec.tasks.map((task) => task.id)
338
+ : parentSnapshot.initialTaskIds;
339
+ const bindings = input.spec
340
+ ? collectDagSkillSnapshotBindings(input.spec, initialTaskIds)
341
+ : parentSnapshot.bindings;
342
+ const boundProfileIds = new Set(bindings.map((binding) => binding.profileId));
343
+ const profiles = parentSnapshot.profiles.filter((profile) => boundProfileIds.has(profile.id));
344
+ for (const profileId of boundProfileIds) {
345
+ if (!profiles.some((profile) => profile.id === profileId)) {
346
+ throw new DagSkillSnapshotIntegrityError(`continuation run spec requires profile missing from parent snapshot: ${profileId}`);
347
+ }
348
+ }
336
349
  const cloned = {
337
350
  ...structuredClone(parentSnapshot),
338
351
  runId: input.newRunId,
339
352
  createdAt: (input.now ?? new Date()).toISOString(),
340
353
  mode: "continuation-from-parent",
354
+ initialTaskIds,
355
+ bindings,
356
+ profiles,
341
357
  };
342
358
  const ref = await writeSkillSnapshot(input.newRunDir, cloned);
343
359
  await writeJsonAtomic(path.join(input.newRunDir, ...SKILL_SNAPSHOT_CONTINUATION_REL_PATH.split("/")), {
@@ -540,6 +556,7 @@ export function buildNodePromptFromSnapshot(input) {
540
556
  spec: input.spec,
541
557
  task: input.task,
542
558
  upstream: input.upstream,
559
+ runDir: input.runDir,
543
560
  resolvedSkills: skillNames,
544
561
  resolvedSkillInstructions,
545
562
  maxUpstreamChars: policy.resolveMaxUpstreamChars(input.task),