@tea-agent/loop-agent 0.44.0-next.1 → 0.44.0-next.11

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 (245) hide show
  1. package/CHANGELOG.md +379 -416
  2. package/dist/application/evaluation/budget.js +21 -0
  3. package/dist/application/evaluation/corpus-hash.js +10 -15
  4. package/dist/application/evaluation/corpus.js +2 -1
  5. package/dist/application/evaluation/frontend-browser-acceptance.js +77 -0
  6. package/dist/application/evaluation/frontend-corpus-browser-acceptance.js +175 -0
  7. package/dist/application/evaluation/frontend-gateway-evidence.js +226 -0
  8. package/dist/application/evaluation/frontend-pair-registration.js +143 -0
  9. package/dist/application/evaluation/frontend-paired-summary.js +150 -0
  10. package/dist/application/evaluation/frontend-run-observation.js +144 -0
  11. package/dist/application/evaluation/frontend-shared-evidence.js +105 -0
  12. package/dist/application/evaluation/types.js +45 -12
  13. package/dist/application/task-lifecycle/observe.js +26 -1
  14. package/dist/build-stamp.json +3 -3
  15. package/dist/cli/command-definitions.js +11 -0
  16. package/dist/cli/program.js +4 -0
  17. package/dist/commands/task-advance.js +3 -5
  18. package/dist/commands/task-source-prepare.js +13 -1
  19. package/dist/executors/dag-pi/guards.js +4 -0
  20. package/dist/executors/dag-pi/model-config.js +30 -0
  21. package/dist/executors/dag-pi/plan/fact-adoption.js +55 -0
  22. package/dist/{workflows/dag/frontend-plan-completeness.js → executors/dag-pi/plan/facts.js} +22 -28
  23. package/dist/executors/dag-pi/plan/finalize-tools.js +259 -0
  24. package/dist/executors/dag-pi/plan/ledger-contract.js +55 -0
  25. package/dist/executors/dag-pi/plan/record-tools.js +861 -0
  26. package/dist/executors/dag-pi/plan/schema.js +129 -0
  27. package/dist/executors/dag-pi/plan/session.js +1 -0
  28. package/dist/executors/dag-pi/plan/tool-helpers.js +16 -0
  29. package/dist/executors/dag-pi/sessions/index.js +6 -0
  30. package/dist/executors/dag-pi/sessions/plan-batches.js +280 -0
  31. package/dist/executors/dag-pi/sessions/plan-prompts.js +367 -0
  32. package/dist/executors/dag-pi/sessions/scout-parallel.js +197 -0
  33. package/dist/executors/dag-pi/sessions/segmented-plan.js +1184 -0
  34. package/dist/executors/dag-pi/sessions/writer-evidence.js +60 -0
  35. package/dist/executors/dag-pi/tools/contract-tools.js +515 -0
  36. package/dist/executors/dag-pi/tools/design-terminal-tools.js +159 -0
  37. package/dist/executors/dag-pi/tools/plan-decision-tools.js +529 -0
  38. package/dist/executors/dag-pi/tools/review-terminal-tools.js +159 -0
  39. package/dist/executors/dag-pi/tools/scout-evidence-tools.js +270 -0
  40. package/dist/executors/dag-pi-executor.js +733 -5782
  41. package/dist/executors/pi-executor.js +6 -1
  42. package/dist/executors/pi-sdk-executor.js +112 -19
  43. package/dist/executors/shell-executor.js +88 -12
  44. package/dist/executors/shell-presets.js +1 -1
  45. package/dist/executors/shell-write-guard.js +26 -3
  46. package/dist/infrastructure/console/operation-store.js +48 -14
  47. package/dist/infrastructure/evaluation/corpus-store.js +37 -12
  48. package/dist/shared/file-identity.js +23 -0
  49. package/dist/shared/git-workspace-status.js +482 -0
  50. package/dist/shared/operator/capabilities.js +10 -5
  51. package/dist/shared/path-safety.js +2 -2
  52. package/dist/shared/wizard-local-telemetry.js +51 -0
  53. package/dist/task/config-types.js +22 -8
  54. package/dist/task/contract/project.js +13 -0
  55. package/dist/task/contract/schema.js +2 -7
  56. package/dist/task/frontend-preflight.js +1 -1
  57. package/dist/task/source-prepare/parse-intent.js +124 -5
  58. package/dist/task/source-prepare/prepare.js +6 -1
  59. package/dist/task/source-prepare/semantic-intake.js +18 -3
  60. package/dist/task/source-prepare/source-execution.js +65 -0
  61. package/dist/task/source-prepare/source-fidelity-pi.js +22 -9
  62. package/dist/task/source-prepare/source-provider-budget.js +290 -0
  63. package/dist/worker/console/chat/assistant-content.js +5 -34
  64. package/dist/worker/console/chat/chat-event-store.js +62 -10
  65. package/dist/worker/console/chat/context-insights.js +723 -0
  66. package/dist/worker/console/chat/conversation-nodes.js +383 -0
  67. package/dist/worker/console/chat/db-connections.js +854 -0
  68. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +1 -1
  69. package/dist/worker/console/chat/pi-runtime/custom-tools/sql-tools.js +655 -0
  70. package/dist/worker/console/chat/pi-runtime.js +445 -36
  71. package/dist/worker/console/chat/provider-error.js +0 -12
  72. package/dist/worker/console/chat/repo-browser.js +52 -4
  73. package/dist/worker/console/chat/routes.js +577 -72
  74. package/dist/worker/console/chat/sdd-data-alignment.js +8 -31
  75. package/dist/worker/console/chat/session-store.js +147 -19
  76. package/dist/worker/console/chat/shortcuts.js +7 -0
  77. package/dist/worker/console/chat/timeline-message-order.js +22 -0
  78. package/dist/worker/console/chat/tools.js +34 -0
  79. package/dist/worker/console/chat/turn-process.js +237 -66
  80. package/dist/worker/console/chat/user-turn-outline.js +19 -0
  81. package/dist/worker/console/console-update-runtime.js +2 -2
  82. package/dist/worker/console/dag-confirmation.js +3 -0
  83. package/dist/worker/console/dag-execution-receipt.js +3 -0
  84. package/dist/worker/console/operator-actions.js +32 -3
  85. package/dist/worker/console/operator-user-error.js +28 -1
  86. package/dist/worker/console/pi-readiness.js +4 -4
  87. package/dist/worker/console/prd-intake-bridge.js +5 -12
  88. package/dist/worker/console/recovery-cta.js +14 -14
  89. package/dist/worker/console/server.js +5 -1
  90. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-8-j6y-sd.js → abnfDiagram-N423BO3Z-r1NAPU_5.js} +1 -1
  91. package/dist/worker/console/static/assets/{arc-eoQiMvuk.js → arc-dT5T4sVL.js} +1 -1
  92. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-C4A3uMcI.js → architectureDiagram-T3A2C74G-CP_cOq46.js} +1 -1
  93. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-D4zD2F-Q.js → blockDiagram-VBNYF7ZC-sToEZxEf.js} +1 -1
  94. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-j1RkJziL.js → c4Diagram-5PPSVZJV-DSxwwi2m.js} +1 -1
  95. package/dist/worker/console/static/assets/channel-CyBY_yGk.js +1 -0
  96. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-YBHmhik1.js → chunk-2GRJ4B5K-B9fh0IkF.js} +1 -1
  97. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-COfWyo9P.js → chunk-2Q5K7J3B-CAUNl-A6.js} +1 -1
  98. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-I99OUkHY.js → chunk-5RXB4S5H-BomeqbNX.js} +1 -1
  99. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-XKxoJNJ4.js → chunk-5VM5RSS4-BNAuTOLE.js} +1 -1
  100. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DLT_cYx1.js → chunk-6Q2QTUOP-DfzjRD5y.js} +1 -1
  101. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CxcKZ9mV.js → chunk-GF5L2VYU-C3uE-yc2.js} +1 -1
  102. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-V1EqXdjY.js → chunk-JWPE2WC7-C3sQMMYr.js} +1 -1
  103. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DebTtdFp.js → chunk-KBJHAD2P-D_AtEYQL.js} +1 -1
  104. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-B-ivNRDf.js → chunk-RYQCIY6F-DW4TwhKv.js} +1 -1
  105. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DC_Ds11b.js → chunk-XXDRQBXY-CTQDmJcp.js} +1 -1
  106. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-D5lN4E_E.js +1 -0
  107. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-D5lN4E_E.js +1 -0
  108. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-sWEqKwIb.js → cose-bilkent-JH36ORCC-iMqPuBsL.js} +1 -1
  109. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BXa_dcu4.js → cynefin-VYW2F7L2-DktIuDWs.js} +1 -1
  110. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-C-Mle84F.js → cynefinDiagram-MW4NZA55-BgVnjyEs.js} +1 -1
  111. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-CXPDBITe.js → dagre-VZM6K2ZE-CR25E4bu.js} +1 -1
  112. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CC-WJQfa.js → diagram-7IWD3JNH-CPM2h5HY.js} +1 -1
  113. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CDAV5Vs4.js → diagram-B4RE2ZJO-DqF0x2g1.js} +1 -1
  114. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-CmFiAcNz.js → diagram-LBJQPF4R-G8BYp2eb.js} +1 -1
  115. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DPBZHuyn.js → diagram-Q27KOJAE-BbC4kT_D.js} +1 -1
  116. package/dist/worker/console/static/assets/{diagram-UB23O5K3-jUlm_Ds3.js → diagram-UB23O5K3-CKZwZ-G5.js} +1 -1
  117. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DWhQ3mfY.js → ebnfDiagram-BXEA7PRR-kJDmheia.js} +1 -1
  118. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Tr2gMqet.js → erDiagram-JOGREHBK-DFTVHyxB.js} +1 -1
  119. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-DJjVQHPA.js → flowDiagram-UKHOOZJN-BqdN5_os.js} +1 -1
  120. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-D74dQ4u0.js → ganttDiagram-PKOTCBZU-SYDjVakh.js} +1 -1
  121. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js → gitGraphDiagram-DS77QQ5N-Bf8bNpGA.js} +1 -1
  122. package/dist/worker/console/static/assets/index-B28Onmfy.css +1 -0
  123. package/dist/worker/console/static/assets/index-CTMZsDmh.js +486 -0
  124. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-ILCbxJyb.js → infoDiagram-6WML65LV-DIeAmJ45.js} +1 -1
  125. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-DeuWBQ89.js → ishikawaDiagram-WSZJBQD7-oikqUAlo.js} +1 -1
  126. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CF5ih8Fk.js → journeyDiagram-NVQOT4AX-mKEF_xYT.js} +1 -1
  127. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C7yOSuRO.js → kanban-definition-27J2QSJJ-BdWJHPnN.js} +1 -1
  128. package/dist/worker/console/static/assets/{linear-BDZ9riWi.js → linear-DGRlieMH.js} +1 -1
  129. package/dist/worker/console/static/assets/{mermaid.core-7pKqYtpZ.js → mermaid.core-4P9yPC9c.js} +5 -5
  130. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-LeJDybSU.js → mindmap-definition-FAOFIHXS-5PTSkos6.js} +1 -1
  131. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-BJvT3pMD.js → pegDiagram-VL7TDLO6-DONIFpG5.js} +1 -1
  132. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-_rGqpMan.js → pieDiagram-7S7Q4E2Y-D_Z4S70M.js} +1 -1
  133. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-DPcSv5aA.js → quadrantDiagram-CIZ2JOQS-CAsjh8iY.js} +1 -1
  134. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Drxx4hkJ.js → railroadDiagram-AXF67PYL-Cx4Dd6ac.js} +1 -1
  135. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BCTUdU4z.js → requirementDiagram-LRYGKXZP-cQb7mwyH.js} +1 -1
  136. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-B6wzbZmB.js → sankeyDiagram-W5VNT64P-Cd-DhUdf.js} +1 -1
  137. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BGt8d3QQ.js → sequenceDiagram-SI44F4Z6-AlKYRgIk.js} +1 -1
  138. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-7nlhJKo7.js → sizeCapture-X5ZJPWSS-CUy_ET4e.js} +1 -1
  139. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-Cv2stqMA.js → stateDiagram-OKZ733FA-CTuVe6Sa.js} +1 -1
  140. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BsWhs8O7.js +1 -0
  141. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-qDAo4Yc1.js → swimlanes-SLNWSIFB-ChFLJb-v.js} +2 -2
  142. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CJcioYGH.js +8 -0
  143. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKbDNKTr.js → timeline-definition-Z64GVDOM-DZZeiAPr.js} +1 -1
  144. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DI-9EHic.js → vennDiagram-T6HMQDX7-t4O91cZU.js} +1 -1
  145. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-BrzzRDpX.js → wardleyDiagram-T6FBY63Y-CV5qGHZu.js} +1 -1
  146. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-BclH5hGh.js → xychartDiagram-ELKLHX3M-DyXbytUI.js} +1 -1
  147. package/dist/worker/console/static/index.html +2 -2
  148. package/dist/worker/console/static-src/app/console-types.js +9 -1
  149. package/dist/worker/console/static-src/operator-chat/animation-frame-batcher.js +38 -0
  150. package/dist/worker/console/static-src/operator-chat/chat-link.js +20 -0
  151. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +186 -5
  152. package/dist/worker/console/static-src/operator-chat/chat-stream-continuity.js +101 -0
  153. package/dist/worker/console/static-src/operator-chat/compaction-message.js +18 -3
  154. package/dist/worker/console/static-src/operator-chat/context-insights-store.js +64 -0
  155. package/dist/worker/console/static-src/operator-chat/details-rail-surfaces.js +98 -0
  156. package/dist/worker/console/static-src/operator-chat/file-palette-nav.js +81 -0
  157. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +17 -3
  158. package/dist/worker/console/static-src/operator-chat/process-label.js +27 -5
  159. package/dist/worker/console/static-src/operator-chat/tools-catalog.js +16 -7
  160. package/dist/worker/console/static-src/operator-chat/transcript-mode.js +21 -0
  161. package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +4 -1
  162. package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +13 -5
  163. package/dist/worker/console/static-src/operator-chat/turn-state-projection.js +166 -0
  164. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +56 -2
  165. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +211 -40
  166. package/dist/worker/console/static-src/operator-chat/useChatStream.js +124 -27
  167. package/dist/worker/console/static-src/operator-chat/useChatThread.js +88 -20
  168. package/dist/worker/console/static-src/operator-chat/useComposer.js +80 -6
  169. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +13 -3
  170. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +36 -17
  171. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +18 -0
  172. package/dist/worker/console/static-src/operator-chat/useWorkspaceBrowserGate.js +4 -0
  173. package/dist/worker/console/static-src/shell/console-update-reload.js +1 -1
  174. package/dist/worker/console/workspace-context.js +2 -0
  175. package/dist/worker/console/workspace-initialization.js +3 -3
  176. package/dist/worker/observability/read-model.js +23 -2
  177. package/dist/worker/observe/node-context-insights.js +479 -0
  178. package/dist/worker/observe/static/console-theme.css +174 -0
  179. package/dist/worker/observe/static/console-theme.js +36 -0
  180. package/dist/worker/observe/static/operator-chrome.css +85 -0
  181. package/dist/worker/observe/static/operator-chrome.js +51 -0
  182. package/dist/worker/scheduler/scheduled-goal-dispatch.js +3 -2
  183. package/dist/worker/scheduler/scheduled-goal-evidence.js +66 -3
  184. package/dist/worker/scheduler/scheduled-goal-store.js +10 -0
  185. package/dist/workflows/dag/budget-enforcement.js +31 -2
  186. package/dist/workflows/dag/checkpoint.js +686 -0
  187. package/dist/workflows/dag/frontend-closeout.js +3 -1
  188. package/dist/workflows/dag/frontend-contract-facts.js +11 -8
  189. package/dist/workflows/dag/frontend-design-policy.js +6 -6
  190. package/dist/workflows/dag/frontend-durable-tools.js +90 -70
  191. package/dist/workflows/dag/frontend-implementation-contract.js +146 -57
  192. package/dist/workflows/dag/frontend-plan-canary.js +66 -16
  193. package/dist/workflows/dag/frontend-plan-decision-contract.js +13 -21
  194. package/dist/workflows/dag/frontend-plan-progress.js +92 -0
  195. package/dist/workflows/dag/frontend-recovery-plan.js +10 -5
  196. package/dist/workflows/dag/frontend-recovery-run.js +51 -46
  197. package/dist/workflows/dag/frontend-repair-assertions.js +36 -0
  198. package/dist/workflows/dag/frontend-review-context.js +29 -1
  199. package/dist/workflows/dag/frontend-review-scopes.js +92 -2
  200. package/dist/workflows/dag/frontend-risk.js +8 -3
  201. package/dist/workflows/dag/frontend-root-observation.js +261 -0
  202. package/dist/workflows/dag/frontend-session-budget.js +52 -39
  203. package/dist/workflows/dag/frontend-session-context.js +10 -0
  204. package/dist/workflows/dag/frontend-test-execution-evidence.js +206 -48
  205. package/dist/workflows/dag/frontend-typed-event-store.js +11 -1
  206. package/dist/workflows/dag/frontend-verification-trace.js +6 -0
  207. package/dist/workflows/dag/frontend-writer-admission.js +3 -1
  208. package/dist/workflows/dag/hybrid/sources.js +1812 -0
  209. package/dist/workflows/dag/hybrid/templates/backend-test.js +1807 -0
  210. package/dist/workflows/dag/hybrid/templates/frontend-test.js +702 -0
  211. package/dist/workflows/dag/hybrid/templates/frontend.js +1529 -0
  212. package/dist/workflows/dag/hybrid/templates/index.js +8 -0
  213. package/dist/workflows/dag/hybrid/templates/kg-bootstrap.js +449 -0
  214. package/dist/workflows/dag/hybrid/templates/knowledge-sync.js +495 -0
  215. package/dist/workflows/dag/hybrid/templates/shared.js +101 -0
  216. package/dist/workflows/dag/hybrid/templates/standard.js +265 -0
  217. package/dist/workflows/dag/hybrid/types.js +32 -0
  218. package/dist/workflows/dag/init-hybrid.js +57 -7106
  219. package/dist/workflows/dag/node-execution.js +11 -11
  220. package/dist/workflows/dag/output-protocol.js +1 -0
  221. package/dist/workflows/dag/rerun-feedback.js +35 -4
  222. package/dist/workflows/dag/rerun-task.js +62 -66
  223. package/dist/workflows/dag/runner.js +38 -1159
  224. package/dist/workflows/dag/terminal-status.js +502 -0
  225. package/dist/workflows/dag/types.js +15 -8
  226. package/dist/workflows/loop/benchmark.js +11 -8
  227. package/docs/README.md +1 -1
  228. package/docs/architecture/dag-execution.md +1 -1
  229. package/docs/architecture/runtime-boundaries.md +1 -1
  230. package/docs/governance/harness-methodology-verification.md +11 -0
  231. package/docs/templates/backend-test-dag.json +5 -4
  232. package/docs/templates/frontend-implementation-contract.schema.json +31 -11
  233. package/package.json +6 -4
  234. package/skills/frontend-design-review/SKILL.md +8 -11
  235. package/skills/frontend-design-review/references/review-checklist.md +3 -4
  236. package/skills/frontend-review/SKILL.md +5 -1
  237. package/skills/loop-agent/references/command-reference.md +8 -0
  238. package/skills/loop-agent/references/hybrid-dag.md +1 -1
  239. package/dist/worker/console/static/assets/channel-ChE7y-cx.js +0 -1
  240. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +0 -1
  241. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +0 -1
  242. package/dist/worker/console/static/assets/index-BWkIfcrK.css +0 -1
  243. package/dist/worker/console/static/assets/index-Cdkvw_H6.js +0 -469
  244. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +0 -1
  245. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +0 -8
@@ -1,3 +1,5 @@
1
+ import { reserveTaskSourceProviderRequest } from "../../task/source-prepare/source-provider-budget.js";
2
+ import { frontendPlanSemanticDigest } from "./frontend-plan-progress.js";
1
3
  import { collectFrontendExecutionGroups } from "./frontend-execution-groups.js";
2
4
  import { reserveDagProviderRequest } from "./budget-enforcement.js";
3
5
  import { createHash } from "node:crypto";
@@ -374,15 +376,11 @@ async function countContractRecordSubmissions(runDir, nodeId) {
374
376
  * `hasTerminalFact` reflects a committed `finalize_plan` terminal fact.
375
377
  */
376
378
  async function readFrontendPlanCommittedSnapshot(runDir, nodeId) {
377
- const records = await readTypedEventStoreFromJsonl(path.join(runDir, nodeId, "plan-typed-facts.jsonl"));
378
- const committed = records.filter((record) => record.phase === "committed");
379
- const digest = createHash("sha256")
380
- .update(committed
381
- .map((record) => record.payloadSha256)
382
- .sort()
383
- .join("\n"))
384
- .digest("hex");
385
- const hasTerminalFact = committed.some((record) => record.fact.kind === "finalize_plan");
379
+ const decisions = await readTypedEventStoreFromJsonl(path.join(runDir, nodeId, "plan-decision-facts.jsonl"));
380
+ const records = decisions.some(r => r.phase === "committed") ? decisions : await readTypedEventStoreFromJsonl(path.join(runDir, nodeId, "plan-typed-facts.jsonl"));
381
+ const committed = records.filter(record => record.phase === "committed");
382
+ const digest = frontendPlanSemanticDigest(committed);
383
+ const hasTerminalFact = committed.some((record) => ["finalize_plan", "finalize_decision"].includes(String(record.fact.kind)));
386
384
  return { digest, hasTerminalFact };
387
385
  }
388
386
  function planInputRecord(value) {
@@ -1564,6 +1562,7 @@ export async function executeDagNode(input) {
1564
1562
  // evidence so a late best-effort write cannot recreate an archived run dir.
1565
1563
  void input.persistState().catch(() => { });
1566
1564
  };
1565
+ const scoutCompletedShards = task.id === "frontend-scout-pi" && isSafeReadOnlyPiRetryCandidate(task) ? new Map() : undefined;
1567
1566
  let terminalResult;
1568
1567
  let previousFailureCategory;
1569
1568
  let previousProtocolReason;
@@ -1665,7 +1664,8 @@ export async function executeDagNode(input) {
1665
1664
  attemptPrompt,
1666
1665
  });
1667
1666
  result = await executeNode({
1668
- ...(state.budgetLedger?.mode === "hard" && state.budgetLedger.limits.maxProviderRequests !== undefined ? { reserveProviderRequest: () => reserveDagProviderRequest({ state, nodeId, attempt: attemptNumber, persist: input.persistState }) } : {}),
1667
+ ...(scoutCompletedShards ? { scoutCompletedShards } : {}),
1668
+ ...(state.budgetLedger?.mode === "hard" && state.budgetLedger.limits.maxProviderRequests !== undefined ? { reserveProviderRequest: () => reserveDagProviderRequest({ state, nodeId, attempt: attemptNumber, persist: input.persistState, ...(spec.sourceProviderBudget ? { reserveTaskRequest: () => reserveTaskSourceProviderRequest({ repoRoot: cwd, taskId: spec.sourceProviderBudget.ledger.taskId, maxProviderRequests: spec.sourceProviderBudget.ledger.maxProviderRequests, expectedBudgetId: spec.sourceProviderBudget.ledger.budgetId, minimumReservedRequests: spec.sourceProviderBudget.ledger.reservedRequests }) } : {}) }) } : {}),
1669
1669
  task,
1670
1670
  cwd,
1671
1671
  model,
@@ -1906,7 +1906,7 @@ export async function executeDagNode(input) {
1906
1906
  // reason, detect new committed facts, and escalate instead of re-running.
1907
1907
  if (frontendPlanLadderEnabled && !result.ok) {
1908
1908
  const afterSnapshot = await readFrontendPlanCommittedSnapshot(runDir, nodeId);
1909
- const hasNewCommittedFact = beforeCommittedDigest !== undefined &&
1909
+ const hasNewCommittedFact = !result.stderr?.includes("FRONTEND_PLAN_NO_PROGRESS") && beforeCommittedDigest !== undefined &&
1910
1910
  afterSnapshot.digest !== beforeCommittedDigest;
1911
1911
  const protocolReason = projectFrontendNodeProtocolFailureReason({
1912
1912
  failureCategory: result.failureCategory,
@@ -39,6 +39,7 @@ const reviewFindingSchema = z
39
39
  line: z.number().int().positive().optional(),
40
40
  issue: z.string().min(1),
41
41
  requiredChange: z.string().min(1).optional(),
42
+ repairAssertions: z.array(z.record(z.unknown())).optional(),
42
43
  })
43
44
  .strict();
44
45
  const reviewJsonVerdictSchema = z
@@ -1,9 +1,10 @@
1
+ import { z } from "zod";
1
2
  import { createHash } from "node:crypto";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import path from "node:path";
4
5
  import { parseJsonReviewVerdict } from "./output-protocol.js";
5
6
  import { FRONTEND_DESIGN_REVIEW_NODE_ID, FRONTEND_REVIEW_NODE_ID, readCommittedDesignRequestFact, readCommittedReviewRequestFact, } from "./frontend-review-findings.js";
6
- import { readTypedEventStoreFromJsonl } from "./frontend-typed-event-store.js";
7
+ import { readTypedEventStoreFromJsonl, reviewFindingSchema } from "./frontend-typed-event-store.js";
7
8
  export const MAX_RERUN_FEEDBACK_CHARS = 12_000;
8
9
  const RERUN_FEEDBACK_TRUNCATION_MARKER = "\n\n...[上一轮反馈已按长度上限截断]...\n\n";
9
10
  const MAX_EVIDENCE_REFS = 8;
@@ -236,6 +237,35 @@ async function readCommittedTerminalKind(input) {
236
237
  }
237
238
  return undefined;
238
239
  }
240
+ /** Current rejecting terminal, with final-review approval as a barrier to
241
+ * older design findings. Binds snapshot consumers to the actual ledger bytes. */
242
+ export async function readCurrentFrontendRepairFindings(runDir) {
243
+ for (const [sourceNodeId, file, approveKind, rejectKind] of [
244
+ [FRONTEND_REVIEW_NODE_ID, "review-typed-facts.jsonl", "approve_review", "request_review_changes"],
245
+ [FRONTEND_DESIGN_REVIEW_NODE_ID, "design-typed-facts.jsonl", "approve_design", "request_design_changes"],
246
+ ]) {
247
+ const ledger = path.join(runDir, sourceNodeId, file);
248
+ let raw;
249
+ try {
250
+ raw = await readFile(ledger, "utf8");
251
+ }
252
+ catch (error) {
253
+ if (error.code === "ENOENT")
254
+ continue;
255
+ throw error;
256
+ }
257
+ const terminal = (await readTypedEventStoreFromJsonl(ledger)).filter(record => record.phase === "committed" && [approveKind, rejectKind].includes(String(record.fact.kind))).at(-1);
258
+ if (!terminal)
259
+ continue;
260
+ const { sha256OfCanonicalJson } = await import("../../task/contract/hash.js");
261
+ if (terminal.payloadSha256 !== sha256OfCanonicalJson(terminal.fact))
262
+ throw new Error("frontend repair terminal payload hash mismatch");
263
+ const verdict = terminal.fact.kind === approveKind ? "approve" : "request";
264
+ const findings = verdict === "request" ? z.array(reviewFindingSchema).parse(terminal.fact.findings) : [];
265
+ return { sourceNodeId, ledgerSha256: sha256(raw), terminalEventId: terminal.eventId, verdict, findings, fact: terminal.fact };
266
+ }
267
+ return undefined;
268
+ }
239
269
  async function readReviewTerminalKind(runDir) {
240
270
  return readCommittedTerminalKind({
241
271
  runDir,
@@ -354,9 +384,10 @@ export async function deriveDagRerunFeedback(input) {
354
384
  // reviewer re-flags them as "unresolved previous-round feedback" (r18).
355
385
  // A committed approval is a resolution barrier and prevents older
356
386
  // findings from being resurrected.
357
- const typedFact = (await readTypedReviewRequestFact(input.runDir)) ??
358
- (await readTypedDesignRequestFact(input.runDir)) ??
359
- (await readAncestorTypedRequestFact(input.runDir));
387
+ const current = await readCurrentFrontendRepairFindings(input.runDir);
388
+ if (current?.verdict === "approve")
389
+ return undefined;
390
+ const typedFact = current ? { nodeId: current.sourceNodeId, fact: current.fact } : await readAncestorTypedRequestFact(input.runDir);
360
391
  if (typedFact) {
361
392
  const parentSourceBindingHash = sourceBindingHash(input.spec);
362
393
  return withDigest({
@@ -1,3 +1,4 @@
1
+ import { sha256OfCanonicalJson } from "../../task/contract/hash.js";
1
2
  import { access, mkdir, readFile } from "node:fs/promises";
2
3
  import { createHash } from "node:crypto";
3
4
  import path from "node:path";
@@ -28,7 +29,7 @@ export function parseDagRerunTaskArgs(args) {
28
29
  for (let index = 0; index < args.length; index += 1) {
29
30
  const arg = args[index];
30
31
  if (arg === undefined)
31
- break;
32
+ throw new Error("dag rerun-task argument is missing");
32
33
  if (arg === "--run-id")
33
34
  parentRunId = args[++index];
34
35
  else if (arg.startsWith("--run-id="))
@@ -103,6 +104,9 @@ async function readFrontendRecoveryDescriptor(runDir, parentRunId, requestId) {
103
104
  plan.schemaVersion !== 1 ||
104
105
  plan.parentRunId !== parentRunId ||
105
106
  plan.requestId !== requestId ||
107
+ plan.failureSource !== raw.failureSource ||
108
+ plan.failureOwner !== raw.failureOwner ||
109
+ plan.resetRootNodeId !== raw.resetRootNodeId ||
106
110
  !Array.isArray(plan.resetNodeIds) ||
107
111
  !Array.isArray(plan.importedNodeIds)) {
108
112
  throw new Error("frontend recovery descriptor is invalid or unbound");
@@ -126,6 +130,8 @@ function buildFrontendRecoveryIntent(input) {
126
130
  attemptIndex: input.parentRecovery?.attemptIndex ?? 0,
127
131
  continuationCount: input.parentRecovery?.continuationCount ?? 0,
128
132
  failureSource: input.failureSource,
133
+ ...(input.failureOwner ? { failureOwner: input.failureOwner } : {}),
134
+ ...(input.resetRootNodeId ? { resetRootNodeId: input.resetRootNodeId } : {}),
129
135
  revision: 0,
130
136
  };
131
137
  }
@@ -391,6 +397,8 @@ async function executeFrontendRecoveryContinuation(input) {
391
397
  parentRunId: input.parentRunId,
392
398
  requestId: input.requestId,
393
399
  failureSource: descriptor.failureSource,
400
+ failureOwner: descriptor.failureOwner,
401
+ resetRootNodeId: descriptor.resetRootNodeId,
394
402
  parentRecovery: parentState.frontendRecoveryState,
395
403
  }),
396
404
  recoveryPlan: descriptor.plan,
@@ -404,75 +412,63 @@ async function executeFrontendRecoveryContinuation(input) {
404
412
  // these through its own durable tools (normal commit entry, child binding)
405
413
  // and the model only corrects the rows the design review flagged; the
406
414
  // parent ledger is never rewritten and the finalize terminal is not
407
- // inherited. Best-effort: a parent without plan facts plans fresh.
408
- try {
415
+ // inherited. Only an absent parent ledger permits a fresh Plan.
416
+ if (descriptor.plan.resetRootNodeId === "frontend-plan-pi") {
409
417
  const parentPlanLedger = path.join(located.runDir, "frontend-plan-pi", "plan-decision-facts.jsonl");
410
- const parentRaw = await readFile(parentPlanLedger, "utf8");
411
- const parentRecords = await readTypedEventStoreFromJsonl(parentPlanLedger);
412
- // Collapse superseded records first: the parent ledger is append-only
413
- // (replace:true appends a corrected row), and replaying both the original
414
- // and its correction would trip FACT_IDENTITY_CONFLICT in the child.
415
- const { collapseDecisionEntriesByKind } = await import("./frontend-plan-decision-contract.js");
416
- const byKind = new Map();
417
- for (const record of parentRecords) {
418
- const kind = String(record.fact.kind);
419
- if (record.phase !== "committed" || kind === "finalize_decision")
420
- continue;
421
- const entry = record.fact.entry;
422
- if (typeof entry !== "object" || entry === null || Array.isArray(entry))
423
- continue;
424
- const bucket = byKind.get(kind) ?? [];
425
- bucket.push(entry);
426
- byKind.set(kind, bucket);
427
- }
428
- let parentCanonicalSha256;
429
- try {
430
- const parentCanonical = await readFile(path.join(located.runDir, "contracts", "frontend-implementation-contract.json"), "utf8");
431
- parentCanonicalSha256 = createHash("sha256").update(parentCanonical).digest("hex");
432
- }
433
- catch {
434
- // Parent canonical unavailable → the identical-plan guard is skipped.
435
- }
436
- // Carry the design findings that blocked the parent run: the child's
437
- // finalize runs a per-finding closure check against them.
438
- let designFindings = [];
439
- try {
440
- const designFacts = await readTypedEventStoreFromJsonl(path.join(located.runDir, "frontend-design-review-pi", "design-typed-facts.jsonl"));
441
- for (const record of designFacts) {
442
- const fact = record.fact;
443
- if (record.phase !== "committed" || fact.kind !== "design-finding")
418
+ const parentRaw = await readFile(parentPlanLedger, "utf8").catch((error) => {
419
+ if (error.code === "ENOENT")
420
+ return undefined;
421
+ throw error;
422
+ });
423
+ if (parentRaw !== undefined) {
424
+ const parentRecords = await readTypedEventStoreFromJsonl(parentPlanLedger);
425
+ // Collapse superseded records first: the parent ledger is append-only
426
+ // (replace:true appends a corrected row), and replaying both the original
427
+ // and its correction would trip FACT_IDENTITY_CONFLICT in the child.
428
+ const { collapseDecisionEntriesByKind } = await import("./frontend-plan-decision-contract.js");
429
+ const byKind = new Map();
430
+ for (const record of parentRecords) {
431
+ const kind = String(record.fact.kind);
432
+ if (record.phase !== "committed" || kind === "finalize_decision")
444
433
  continue;
445
- const finding = (fact.finding ?? {});
446
- designFindings.push({
447
- severity: typeof finding.severity === "string" ? finding.severity : "Important",
448
- issue: typeof finding.issue === "string" ? finding.issue : "",
449
- requiredChange: typeof finding.requiredChange === "string" ? finding.requiredChange : "",
450
- });
434
+ const entry = record.fact.entry;
435
+ if (typeof entry !== "object" || entry === null || Array.isArray(entry))
436
+ continue;
437
+ const bucket = byKind.get(kind) ?? [];
438
+ bucket.push(entry);
439
+ byKind.set(kind, bucket);
451
440
  }
441
+ let parentCanonicalSha256;
442
+ try {
443
+ const parentCanonical = await readFile(path.join(located.runDir, "contracts", "frontend-implementation-contract.json"), "utf8");
444
+ parentCanonicalSha256 = createHash("sha256").update(parentCanonical).digest("hex");
445
+ }
446
+ catch {
447
+ // Parent canonical unavailable → the identical-plan guard is skipped.
448
+ }
449
+ const { readCurrentFrontendRepairFindings } = await import("./rerun-feedback.js");
450
+ const feedback = await readCurrentFrontendRepairFindings(located.runDir);
451
+ const designFindings = feedback?.verdict === "request" ? feedback.findings : [];
452
+ const parentSpec = await readDagRunSpec(located.runDir);
453
+ const snapshot = {
454
+ schemaVersion: 1,
455
+ schemaId: "frontend-plan-parent-decision-snapshot-v1",
456
+ parentRunId: input.parentRunId,
457
+ parentLedgerSha256: createHash("sha256").update(parentRaw).digest("hex"),
458
+ sourceBindingSha256: sha256OfCanonicalJson(parentSpec.sourceBinding ?? null),
459
+ ...(feedback ? { feedbackBinding: { sourceNodeId: feedback.sourceNodeId, ledgerSha256: feedback.ledgerSha256, terminalEventId: feedback.terminalEventId } } : {}),
460
+ ...(parentCanonicalSha256 ? { parentCanonicalSha256 } : {}),
461
+ designFindings,
462
+ facts: [...byKind.entries()].flatMap(([kind, entries]) => collapseDecisionEntriesByKind(kind, entries).map((entry) => ({
463
+ kind,
464
+ entry,
465
+ }))),
466
+ };
467
+ await mkdir(path.join(locatedChild.runDir, "frontend-plan-pi"), {
468
+ recursive: true,
469
+ });
470
+ await writeJsonAtomic(path.join(locatedChild.runDir, "frontend-plan-pi", "parent-decision-snapshot.json"), snapshot);
452
471
  }
453
- catch {
454
- // No readable design findings → the closure check has no assertions.
455
- }
456
- const snapshot = {
457
- schemaVersion: 1,
458
- schemaId: "frontend-plan-parent-decision-snapshot-v1",
459
- parentRunId: input.parentRunId,
460
- parentLedgerSha256: createHash("sha256").update(parentRaw).digest("hex"),
461
- ...(parentCanonicalSha256 ? { parentCanonicalSha256 } : {}),
462
- designFindings,
463
- facts: [...byKind.entries()].flatMap(([kind, entries]) => collapseDecisionEntriesByKind(kind, entries).map((entry) => ({
464
- kind,
465
- entry,
466
- }))),
467
- };
468
- await mkdir(path.join(locatedChild.runDir, "frontend-plan-pi"), {
469
- recursive: true,
470
- });
471
- await writeJsonAtomic(path.join(locatedChild.runDir, "frontend-plan-pi", "parent-decision-snapshot.json"), snapshot);
472
- }
473
- catch {
474
- // No parent plan ledger (or unreadable) → the child plans fresh,
475
- // exactly like a run without recovery lineage.
476
472
  }
477
473
  const childSpec = await readDagRunSpec(locatedChild.runDir);
478
474
  const childState = await readDagRunState(locatedChild.runDir);