@tea-agent/loop-agent 0.43.0-next.9 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +31 -2309
- package/README.md +7 -0
- package/dist/application/dag/args.js +8 -0
- package/dist/application/task-lifecycle/advance.js +38 -7
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +2 -0
- package/dist/cli/program.js +3 -1
- package/dist/cli/update/init-surface-notifier.js +2 -0
- package/dist/cli/update/policy.js +2 -0
- package/dist/commands/client-recovery.js +20 -55
- package/dist/commands/cursor-prompt.js +2 -0
- package/dist/commands/dag-approve.js +2 -0
- package/dist/commands/dag-final-verification.js +2 -0
- package/dist/commands/dag-init-hybrid.js +2 -0
- package/dist/commands/dag-reconcile-tasks.js +2 -0
- package/dist/commands/dag-reject.js +2 -0
- package/dist/commands/dag-report.js +2 -0
- package/dist/commands/dag-rerun.js +2 -0
- package/dist/commands/dag-resume.js +2 -0
- package/dist/commands/dag-workflow-compile.js +2 -0
- package/dist/commands/dag-workflow-plan.js +2 -0
- package/dist/commands/dag-workflow-validate.js +2 -0
- package/dist/commands/delegate.js +2 -0
- package/dist/commands/examples.js +2 -0
- package/dist/commands/import-prd.js +2 -0
- package/dist/commands/init-model-catalog.js +2 -0
- package/dist/commands/init.js +19 -13
- package/dist/commands/instructions.js +2 -0
- package/dist/commands/knowledge.js +2 -0
- package/dist/commands/loop-benchmark.js +2 -0
- package/dist/commands/pi-prompt.js +2 -0
- package/dist/commands/pi-reuse-benchmark.js +2 -0
- package/dist/commands/promote-run.js +2 -0
- package/dist/commands/stats.js +1 -1
- package/dist/commands/study-init.js +2 -0
- package/dist/commands/task-advance.js +34 -0
- package/dist/commands/task-source-prepare.js +2 -0
- package/dist/commands/worktree-create.js +2 -0
- package/dist/commands/worktree-remove.js +2 -0
- package/dist/executors/dag-pi-executor.js +1650 -198
- package/dist/executors/pi-executor.js +85 -3
- package/dist/executors/pi-sdk-executor.js +18 -0
- package/dist/executors/shell-executor.js +93 -7
- package/dist/executors/shell-verification.js +3 -0
- package/dist/executors/shell-write-guard.js +27 -32
- package/dist/governance/exec-plans.js +6 -3
- package/dist/infrastructure/console/app-data.js +6 -0
- package/dist/shared/artifacts-core.js +2 -0
- package/dist/shared/backend-dogfood-preflight.js +47 -0
- package/dist/shared/dag-failure-category.js +3 -0
- package/dist/shared/git-progress.js +2 -0
- package/dist/shared/one-shot-prompt-args.js +2 -0
- package/dist/shared/operator/capabilities.js +180 -0
- package/dist/shared/package-metadata.js +6 -4
- package/dist/shared/pi-context-pressure/extension.js +26 -16
- package/dist/shared/pi-context-pressure/sift-bridge.js +1 -1
- package/dist/shared/pi-provider-recovery.js +182 -0
- package/dist/shared/pi-retry-settings.js +40 -0
- package/dist/shared/reference-context.js +2 -0
- package/dist/task/config-types.js +29 -0
- package/dist/task/contract/project.js +9 -0
- package/dist/task/contract/recover.js +6 -0
- package/dist/task/contract/schema.js +17 -0
- package/dist/task/source-prepare/artifact-meta.js +9 -2
- package/dist/task/source-prepare/build-draft.js +60 -0
- package/dist/task/source-prepare/fragment-inventory.js +4 -1
- package/dist/task/source-prepare/parse-intent.js +36 -11
- package/dist/task/task-demand-routing.js +5 -2
- package/dist/worker/console/chat/browser-automation.js +523 -0
- package/dist/worker/console/chat/browser-policy.js +6 -36
- package/dist/worker/console/chat/browser-routes.js +188 -56
- package/dist/worker/console/chat/explore-tools.js +5 -2
- package/dist/worker/console/chat/pi-mode-loop-isolation.js +155 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +44 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +184 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +202 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +79 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +94 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/scheduled-goal-tools.js +22 -0
- package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +38 -0
- package/dist/worker/console/chat/pi-runtime/inspection-types.js +28 -0
- package/dist/worker/console/chat/pi-runtime/inspection.js +439 -0
- package/dist/worker/console/chat/pi-runtime/progressive-tools.js +195 -0
- package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +153 -0
- package/dist/worker/console/chat/pi-runtime/sdk-session.js +5 -0
- package/dist/worker/console/chat/pi-runtime.js +208 -1138
- package/dist/worker/console/chat/routes.js +27 -7
- package/dist/worker/console/chat/scheduled-goal-booking.js +59 -0
- package/dist/worker/console/chat/scheduled-goal-delivery.js +27 -0
- package/dist/worker/console/chat/scheduled-goal-request.js +190 -0
- package/dist/worker/console/chat/sdd-data-alignment.js +1 -1
- package/dist/worker/console/chat/session-mode-view.js +5 -4
- package/dist/worker/console/chat/session-mode.js +18 -12
- package/dist/worker/console/chat/session-store.js +42 -9
- package/dist/worker/console/chat/tool-preview.js +115 -0
- package/dist/worker/console/chat/tools.js +10 -0
- package/dist/worker/console/chat/turn-order.js +13 -0
- package/dist/worker/console/chat/turn-process.js +32 -30
- package/dist/worker/console/console-update-and-init.js +1 -19
- package/dist/worker/console/console-update-runtime.js +5 -20
- package/dist/worker/console/operator-actions.js +63 -1
- package/dist/worker/console/prd-intake-bridge.js +54 -1
- package/dist/worker/console/routes.js +8 -0
- package/dist/worker/console/scheduled-goal-host.js +98 -0
- package/dist/worker/console/scheduled-goal-operation-adapter.js +127 -0
- package/dist/worker/console/server.js +24 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D_fNbWc_.js → abnfDiagram-N423BO3Z-8-j6y-sd.js} +1 -1
- package/dist/worker/console/static/assets/{arc-_HuqLW6m.js → arc-eoQiMvuk.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-Djy2qY1m.js → architectureDiagram-T3A2C74G-C4A3uMcI.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-bB-1TSyY.js → blockDiagram-VBNYF7ZC-D4zD2F-Q.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-C5Hmghrz.js → c4Diagram-5PPSVZJV-j1RkJziL.js} +1 -1
- package/dist/worker/console/static/assets/channel-ChE7y-cx.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-Duyl39oy.js → chunk-2GRJ4B5K-YBHmhik1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-x6mdnSyf.js → chunk-2Q5K7J3B-COfWyo9P.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-WlBuFj7W.js → chunk-5RXB4S5H-I99OUkHY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CTF429HX.js → chunk-5VM5RSS4-XKxoJNJ4.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Dwd6r-SF.js → chunk-6Q2QTUOP-DLT_cYx1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C-Br82D1.js → chunk-GF5L2VYU-CxcKZ9mV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CuGp0DeE.js → chunk-JWPE2WC7-V1EqXdjY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CJhFX6Lh.js → chunk-KBJHAD2P-DebTtdFp.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DpGOa_jT.js → chunk-RYQCIY6F-B-ivNRDf.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DXJaTynd.js → chunk-XXDRQBXY-DC_Ds11b.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CRBZWjE4.js → cose-bilkent-JH36ORCC-sWEqKwIb.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BdXcxtlb.js → cynefin-VYW2F7L2-BXa_dcu4.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-07UKsOts.js → cynefinDiagram-MW4NZA55-C-Mle84F.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-D38p9__S.js → dagre-VZM6K2ZE-CXPDBITe.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-nSiBNNjH.js → diagram-7IWD3JNH-CC-WJQfa.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BFOTot5D.js → diagram-B4RE2ZJO-CDAV5Vs4.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DypKaZ6k.js → diagram-LBJQPF4R-CmFiAcNz.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-B6yoOQeW.js → diagram-Q27KOJAE-DPBZHuyn.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BHYS6viX.js → diagram-UB23O5K3-jUlm_Ds3.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-D2VD5Snj.js → ebnfDiagram-BXEA7PRR-DWhQ3mfY.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-E98mWxN1.js → erDiagram-JOGREHBK-Tr2gMqet.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CT1zxhqP.js → flowDiagram-UKHOOZJN-DJjVQHPA.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-6GcngNcy.js → ganttDiagram-PKOTCBZU-D74dQ4u0.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DCL6NvKe.js → gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js} +1 -1
- package/dist/worker/console/static/assets/index-BWkIfcrK.css +1 -0
- package/dist/worker/console/static/assets/index-Cdkvw_H6.js +469 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-C0627e-9.js → infoDiagram-6WML65LV-ILCbxJyb.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C_u3P6Ik.js → ishikawaDiagram-WSZJBQD7-DeuWBQ89.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DPDPv9HL.js → journeyDiagram-NVQOT4AX-CF5ih8Fk.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-D3OHdWiO.js → kanban-definition-27J2QSJJ-C7yOSuRO.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DI88zD7n.js → linear-BDZ9riWi.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-p2l8IrWY.js → mermaid.core-7pKqYtpZ.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-B1bAX-oS.js → mindmap-definition-FAOFIHXS-LeJDybSU.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DwOnWxdD.js → pegDiagram-VL7TDLO6-BJvT3pMD.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-xRkTXnJC.js → pieDiagram-7S7Q4E2Y-_rGqpMan.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-_9UC5Zio.js → quadrantDiagram-CIZ2JOQS-DPcSv5aA.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CgEUirWJ.js → railroadDiagram-AXF67PYL-Drxx4hkJ.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-Czbpwiyz.js → requirementDiagram-LRYGKXZP-BCTUdU4z.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-_j7_KiqY.js → sankeyDiagram-W5VNT64P-B6wzbZmB.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BNJa6Hyi.js → sequenceDiagram-SI44F4Z6-BGt8d3QQ.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DedpKtOc.js → sizeCapture-X5ZJPWSS-7nlhJKo7.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BBvthr7c.js → stateDiagram-OKZ733FA-Cv2stqMA.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-Ds7umgEM.js → swimlanes-SLNWSIFB-qDAo4Yc1.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKa-p1nF.js → timeline-definition-Z64GVDOM-CKbDNKTr.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-LoUNR56o.js → vennDiagram-T6HMQDX7-DI-9EHic.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-Bqbl6ym7.js → wardleyDiagram-T6FBY63Y-BrzzRDpX.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-B8dUg4lf.js → xychartDiagram-ELKLHX3M-BclH5hGh.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +24 -0
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +41 -11
- package/dist/worker/console/static-src/operator-chat/compaction-message.js +3 -17
- package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +192 -0
- package/dist/worker/console/static-src/operator-chat/pending-user-message.js +9 -1
- package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +15 -5
- package/dist/worker/console/static-src/operator-chat/timeline-merge.js +29 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +92 -38
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +145 -70
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +38 -55
- package/dist/worker/console/static-src/operator-chat/useComposer.js +182 -69
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +2 -0
- package/dist/worker/console/static-src/prd-file-import.js +3 -1
- package/dist/worker/console/workspace-context.js +22 -0
- package/dist/worker/console/workspace-initialization.js +209 -0
- package/dist/worker/delivery/git-transaction.js +2 -0
- package/dist/worker/feature/fullstack-validate.js +2 -0
- package/dist/worker/loop-agent/loop-agent-client.js +8 -2
- package/dist/worker/materialize/harness-task-materializer.js +4 -1
- package/dist/worker/metrics/projector.js +1 -1
- package/dist/worker/observability/event-store.js +4 -1
- package/dist/worker/observability/read-model.js +4 -1
- package/dist/worker/observe/node-transparency.js +23 -1
- package/dist/worker/observe/routes.js +4 -0
- package/dist/worker/observe/static/operator-chrome.js +3 -1
- package/dist/worker/observe/static/styles.css +7 -4
- package/dist/worker/observe/static/views/dag-inspector.js +5 -19
- package/dist/worker/outcomes/declared-artifacts.js +2 -0
- package/dist/worker/preflight.js +3 -0
- package/dist/worker/scheduler/scheduled-goal-dispatch.js +117 -0
- package/dist/worker/scheduler/scheduled-goal-evidence.js +167 -0
- package/dist/worker/scheduler/scheduled-goal-recovery.js +62 -0
- package/dist/worker/scheduler/scheduled-goal-store.js +699 -0
- package/dist/worker/scheduler/scheduled-goal-supervisor.js +132 -0
- package/dist/worker/scheduler/scheduled-goal-time.js +102 -0
- package/dist/worker/scheduler/scheduled-goal-types.js +95 -0
- package/dist/worker/task-spec/validate.js +4 -1
- package/dist/workflows/dag/backend-test-markdown-workflow.js +6 -24
- package/dist/workflows/dag/backend-test-plan-protocol.js +82 -5
- package/dist/workflows/dag/dag-retry-schema.js +11 -0
- package/dist/workflows/dag/decision-envelope.js +2 -0
- package/dist/workflows/dag/dynamic-runtime/shared.js +2 -2
- package/dist/workflows/dag/frontend-closeout.js +3 -1
- package/dist/workflows/dag/frontend-committed-facts.js +461 -0
- package/dist/workflows/dag/frontend-durable-tools.js +15 -3
- package/dist/workflows/dag/frontend-implementation-contract.js +369 -12
- package/dist/workflows/dag/frontend-plan-canary.js +53 -0
- package/dist/workflows/dag/frontend-plan-decision-contract.js +803 -0
- package/dist/workflows/dag/frontend-plan-render.js +0 -2
- package/dist/workflows/dag/frontend-provider-capability-matrix.js +8 -61
- package/dist/workflows/dag/frontend-recovery-run.js +57 -0
- package/dist/workflows/dag/frontend-repair.js +55 -76
- package/dist/workflows/dag/frontend-review-context.js +42 -68
- package/dist/workflows/dag/frontend-review-scopes.js +2 -2
- package/dist/workflows/dag/frontend-risk.js +92 -10
- package/dist/workflows/dag/frontend-session-budget.js +117 -3
- package/dist/workflows/dag/frontend-shape.js +11 -55
- package/dist/workflows/dag/frontend-test-execution-evidence.js +35 -10
- package/dist/workflows/dag/frontend-typed-event-store.js +32 -25
- package/dist/workflows/dag/frontend-verification-trace.js +33 -54
- package/dist/workflows/dag/frontend-writer-admission.js +3 -47
- package/dist/workflows/dag/frontend-writer-status.js +0 -23
- package/dist/workflows/dag/init-hybrid.js +47 -19
- package/dist/workflows/dag/interrupt-request.js +2 -0
- package/dist/workflows/dag/lifecycle.js +11 -2
- package/dist/workflows/dag/node-execution.js +50 -13
- package/dist/workflows/dag/reconcile-run.js +2 -0
- package/dist/workflows/dag/repair-artifact.js +3 -1
- package/dist/workflows/dag/report.js +2 -0
- package/dist/workflows/dag/rerun-plan.js +10 -0
- package/dist/workflows/dag/rerun-task.js +79 -1
- package/dist/workflows/dag/retry-policy.js +18 -0
- package/dist/workflows/dag/scheduler.js +2 -4
- package/dist/workflows/dag/types.js +44 -6
- package/dist/workflows/dag/validate.js +4 -0
- package/docs/README.md +1 -0
- package/docs/architecture/runtime-boundaries.md +3 -3
- package/docs/governance/README.md +1 -0
- package/docs/init-surface.manifest.json +1 -0
- package/docs/operations/README.md +2 -0
- package/docs/templates/README.md +1 -1
- package/docs/templates/agent-dag.schema.json +2 -2
- package/docs/templates/backend-test-dag.json +14 -10
- package/docs/templates/frontend-implementation-contract.schema.json +0 -7
- package/package.json +9 -3
- package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
- package/skills/frontend-contract/references/contract-protocol.md +3 -1
- package/skills/frontend-plan/SKILL.md +8 -6
- package/skills/frontend-plan/references/decision-contract.md +3 -3
- package/skills/frontend-review/SKILL.md +18 -28
- package/skills/frontend-review/references/review-findings.md +8 -3
- package/dist/commands/new-task.js +0 -5
- package/dist/commands/status.js +0 -57
- package/dist/commands/task-contract.js +0 -269
- package/dist/shared/prompts.js +0 -26
- package/dist/task/config.js +0 -2
- package/dist/task/contract/validate-draft.js +0 -106
- package/dist/task/goal.js +0 -3
- package/dist/task/index.js +0 -12
- package/dist/task/lifecycle.js +0 -1
- package/dist/task/operator/capabilities.js +0 -6
- package/dist/task/operator/envelope.js +0 -2
- package/dist/task/operator/index.js +0 -5
- package/dist/task/operator/registry.js +0 -2
- package/dist/task/operator/types.js +0 -1
- package/dist/task/paths.js +0 -1
- package/dist/task/source-state.js +0 -1
- package/dist/task/subagent-guidance.js +0 -1
- package/dist/worker/console/chat/sift-bridge.js +0 -1
- package/dist/worker/console/index.js +0 -20
- package/dist/worker/console/static/assets/channel-C0A6UEIa.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DzguNppy.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DzguNppy.js +0 -1
- package/dist/worker/console/static/assets/index-24jp3aBh.js +0 -468
- package/dist/worker/console/static/assets/index-CY6y6I8M.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BABVQnfM.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D0qsLaxR.js +0 -8
- package/dist/worker/scheduler/index.js +0 -25
- package/dist/workflows/dag/facts.js +0 -4
- package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -975
- package/dist/workflows/dag/index.js +0 -6
- package/dist/workflows/dynamic/index.js +0 -7
|
@@ -15,7 +15,7 @@ import { buildDagNodePromptEnvelope, formatConvergenceFeedbackBlock, } from "./p
|
|
|
15
15
|
import { persistLongNodeOutputArtifacts } from "./upstream-artifacts.js";
|
|
16
16
|
import { materializeDeclaredArtifactFacts } from "./artifact-bindings.js";
|
|
17
17
|
import { buildOutputLimitRecoverySection, loadBackendTestWriterProgressForRetry, } from "./backend-test-writer-completeness.js";
|
|
18
|
-
import { computeBackoffDelayMs, isCanonicalFinalVerifyShellRetryCandidate, isRetryablePiFailureCategory, isSafeReadOnlyPiRetryCandidate, isTargetTemplateTransientRetryNode, isWriterEmptyDiffRetryCandidate, isWriterTransportRetryCandidate, OUTPUT_LIMIT_RETRY_CATEGORY, projectFrontendNodeProtocolFailureReason, resolveFrontendPlanBackupRoute, resolveFrontendPlanRetryStep, VERIFY_SHELL_RETRY_POLICY, } from "./retry-policy.js";
|
|
18
|
+
import { computeBackoffDelayMs, isCanonicalFinalVerifyShellRetryCandidate, isProviderAvailabilityFailureCategory, isRetryablePiFailureCategory, isSafeReadOnlyPiRetryCandidate, isTargetTemplateTransientRetryNode, isWriterEmptyDiffRetryCandidate, isWriterTransportRetryCandidate, OUTPUT_LIMIT_RETRY_CATEGORY, projectFrontendNodeProtocolFailureReason, resolveFrontendPlanBackupRoute, resolveFrontendPlanRetryStep, VERIFY_SHELL_RETRY_POLICY, } from "./retry-policy.js";
|
|
19
19
|
import { applyNodeActivity, evaluateNodeLiveness, resolveLivenessPolicy, } from "./liveness-policy.js";
|
|
20
20
|
import { buildProtocolRetryInstruction, normalizeReviewVerdictAfterRetries, parseJsonReviewVerdict, validateOutputProtocol, } from "./output-protocol.js";
|
|
21
21
|
import { getStructuredContractValidator } from "./contract-output-registry.js";
|
|
@@ -568,7 +568,7 @@ export function renderFrontendPlanInputContext(input) {
|
|
|
568
568
|
"Do not read upstream artifacts, task sources, or repository files. If this input cannot support a decision, record a genuine evidence gap.",
|
|
569
569
|
"</frontend_plan_input>",
|
|
570
570
|
"<plan_review_checklist>",
|
|
571
|
-
"
|
|
571
|
+
"Satisfy these checks in the committed facts before the runtime compiles and finalizes the Plan:",
|
|
572
572
|
...checklistLines,
|
|
573
573
|
"</plan_review_checklist>",
|
|
574
574
|
].join("\n");
|
|
@@ -614,6 +614,10 @@ export async function buildFrontendPlanInputContext(runDir, componentSourceCitat
|
|
|
614
614
|
export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFailureCategory, previousProtocolReason, recoveryTargetPaths, recoveryDiagnostics, frontendPlanRetryStep) {
|
|
615
615
|
if (attemptNumber <= 1)
|
|
616
616
|
return basePrompt;
|
|
617
|
+
// Match the executor segmented Plan identity; custom nodes retain their terminal.
|
|
618
|
+
const planCompletion = task.id === FRONTEND_PLAN_NODE_ID
|
|
619
|
+
? "Stop after committing the required facts. The runtime compiles and finalizes the committed ledger automatically; only repair facts reported by its validation."
|
|
620
|
+
: "Then call finalize_plan exactly once.";
|
|
617
621
|
// Context overflow is a transport/session failure, not a plan-protocol
|
|
618
622
|
// failure. It must take precedence over the plan retry ladder so every
|
|
619
623
|
// retry, including a repeated plan overflow, starts from the compact
|
|
@@ -656,8 +660,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
656
660
|
previousProtocolReason) {
|
|
657
661
|
// The frontend plan node's compile authority is the committed typed
|
|
658
662
|
// ledger, not a fenced JSON text artifact: its retry guidance must
|
|
659
|
-
// direct the model to re-commit corrected record_* facts and
|
|
660
|
-
//
|
|
663
|
+
// direct the model to re-commit corrected record_* facts and respect
|
|
664
|
+
// terminal ownership. The full-contract JSON guidance below applies
|
|
661
665
|
// only to nodes whose authority is still a text contract artifact.
|
|
662
666
|
if (task.structuredContractOutput.schemaId ===
|
|
663
667
|
"frontend-implementation-contract-plan-patch-v1") {
|
|
@@ -673,7 +677,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
673
677
|
"<retry_instruction>",
|
|
674
678
|
"Previous plan ledger facts failed canonical contract validation:",
|
|
675
679
|
previousProtocolReason,
|
|
676
|
-
"Fix the reported violations by re-committing corrected record_* facts
|
|
680
|
+
"Fix the reported violations by re-committing corrected record_* facts. The committed typed ledger is the only compile authority.",
|
|
681
|
+
planCompletion,
|
|
677
682
|
"Do not emit a fenced JSON contract, protected skeleton fields, or an openspec-citations block; narrative JSON is not validated and wastes the output budget.",
|
|
678
683
|
...frontendPlanValidationRetryGuidance(previousProtocolReason),
|
|
679
684
|
...splitGuidance,
|
|
@@ -711,7 +716,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
711
716
|
"",
|
|
712
717
|
"<retry_instruction>",
|
|
713
718
|
"Previous attempt was truncated by the provider (stopReason=length) before the plan facts were fully committed.",
|
|
714
|
-
"Re-commit the missing record_* facts
|
|
719
|
+
"Re-commit the missing record_* facts; the committed typed ledger is the only compile authority. Do NOT re-read contract/scout outputs or source files — use the facts already in context. Commit record_* facts one tool call per message.",
|
|
720
|
+
planCompletion,
|
|
715
721
|
"Do not emit a fenced JSON contract, protected skeleton fields, or an openspec-citations block; narrative JSON is not validated and wastes the output budget.",
|
|
716
722
|
"</retry_instruction>",
|
|
717
723
|
].join("\n");
|
|
@@ -732,7 +738,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
732
738
|
"",
|
|
733
739
|
"<retry_instruction>",
|
|
734
740
|
"Frontend plan retry ladder step: compact-terminal-first.",
|
|
735
|
-
"Do NOT rewrite the narrative. Only adopt already staged/quarantined fresh facts
|
|
741
|
+
"Do NOT rewrite the narrative. Only adopt already staged/quarantined fresh facts and fill the missing required facts.",
|
|
742
|
+
planCompletion,
|
|
736
743
|
"Keep the existing committed ledger intact; do not re-derive already committed facts.",
|
|
737
744
|
"</retry_instruction>",
|
|
738
745
|
].join("\n");
|
|
@@ -743,7 +750,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
743
750
|
"",
|
|
744
751
|
"<retry_instruction>",
|
|
745
752
|
"Frontend plan retry ladder step: bounded-tool-only.",
|
|
746
|
-
"Reduce reasoning and wall-clock time. Use only
|
|
753
|
+
"Reduce reasoning and wall-clock time. Use only the tools exposed for this session and only for the necessary missing facts.",
|
|
754
|
+
planCompletion,
|
|
747
755
|
"Do not expand scope or re-derive already committed facts.",
|
|
748
756
|
"</retry_instruction>",
|
|
749
757
|
].join("\n");
|
|
@@ -754,7 +762,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
754
762
|
"",
|
|
755
763
|
"<retry_instruction>",
|
|
756
764
|
"Frontend plan retry ladder step: backup-model.",
|
|
757
|
-
"A backup provider/model route was selected after repeated non-converging failures. Re-derive only the missing committed facts
|
|
765
|
+
"A backup provider/model route was selected after repeated non-converging failures. Re-derive only the missing committed facts; do not repeat the failed strategy.",
|
|
766
|
+
planCompletion,
|
|
758
767
|
"</retry_instruction>",
|
|
759
768
|
].join("\n");
|
|
760
769
|
}
|
|
@@ -793,7 +802,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
793
802
|
"",
|
|
794
803
|
"<retry_instruction>",
|
|
795
804
|
"Previous plan attempt issued too many read-only tool calls (read/grep/ls/find) and blew up the context window. Trust the upstream frontend-contract-pi typed requirement facts and frontend-scout-pi target surface already provided — do NOT re-read contract/scout stdout, PRD/source files, or component sources you already inspected.",
|
|
796
|
-
"Minimize discovery reads: only read what you genuinely need, once. Commit
|
|
805
|
+
"Minimize discovery reads: only read what you genuinely need, once. Commit the required record_* facts directly from the facts already in context (one tool call per message).",
|
|
806
|
+
planCompletion,
|
|
797
807
|
"</retry_instruction>",
|
|
798
808
|
].join("\n");
|
|
799
809
|
}
|
|
@@ -917,7 +927,8 @@ export function buildAttemptPrompt(task, basePrompt, attemptNumber, previousFail
|
|
|
917
927
|
"",
|
|
918
928
|
"<retry_instruction>",
|
|
919
929
|
"Previous attempt exceeded the structured output size limit.",
|
|
920
|
-
"Re-commit corrected record_* facts
|
|
930
|
+
"Re-commit corrected record_* facts; the committed typed ledger is the only compile authority.",
|
|
931
|
+
planCompletion,
|
|
921
932
|
"Do not emit a fenced JSON contract, protected skeleton fields, or an openspec-citations block; narrative JSON is not validated and wastes the output budget.",
|
|
922
933
|
"</retry_instruction>",
|
|
923
934
|
].join("\n");
|
|
@@ -1075,6 +1086,8 @@ function validateRepairArtifactGateBeforeShell(input) {
|
|
|
1075
1086
|
if (!gate)
|
|
1076
1087
|
return;
|
|
1077
1088
|
const upstream = input.state.nodes[gate.fromNodeId];
|
|
1089
|
+
if (!upstream)
|
|
1090
|
+
return;
|
|
1078
1091
|
const parsed = parseSupervisorRepairArtifact(upstream);
|
|
1079
1092
|
if (!parsed.ok) {
|
|
1080
1093
|
throw new Error(`repair artifact gate failed: ${parsed.reason}`);
|
|
@@ -1711,6 +1724,20 @@ export async function executeDagNode(input) {
|
|
|
1711
1724
|
? result.stderr.slice(markerIndex, markerIndex + 4_000).trim()
|
|
1712
1725
|
: `backend-test Markdown plan attempt failed with ${result.failureCategory}`;
|
|
1713
1726
|
}
|
|
1727
|
+
// Decision-path Plan bridge failures surface from the executor as
|
|
1728
|
+
// invalid-output (the derived relationship patch failed pre-validation),
|
|
1729
|
+
// NOT through the R1 structured self-check (which only runs when
|
|
1730
|
+
// result.ok). Capture the bridge diagnostics into previousProtocolReason
|
|
1731
|
+
// so the next attempt prompt tells the model exactly which decision facts
|
|
1732
|
+
// to repair instead of replaying the identical under-declared session.
|
|
1733
|
+
if (task.id === FRONTEND_PLAN_NODE_ID &&
|
|
1734
|
+
!result.ok &&
|
|
1735
|
+
result.failureCategory === "invalid-output" &&
|
|
1736
|
+
/frontend decision → relationship patch failed|frontend decision finalize failed/.test(result.stderr ?? "")) {
|
|
1737
|
+
previousProtocolReason = (result.stderr ?? "")
|
|
1738
|
+
.slice(-4_000)
|
|
1739
|
+
.trim();
|
|
1740
|
+
}
|
|
1714
1741
|
if (isFrontendStructuredRepairSchemaId(task.structuredContractOutput?.schemaId)) {
|
|
1715
1742
|
const rawText = canonicalNodeOutput(result);
|
|
1716
1743
|
if (rawText.trim().length > 0) {
|
|
@@ -1903,13 +1930,23 @@ export async function executeDagNode(input) {
|
|
|
1903
1930
|
frontendPriorFingerprints.push(fingerprint);
|
|
1904
1931
|
frontendPlanRetryStep = nextStep;
|
|
1905
1932
|
if (nextStep === "unsupported-provider-capability") {
|
|
1933
|
+
// Reachability first: when the failed attempts never reached model
|
|
1934
|
+
// reasoning (gateway 5xx / rate limit / quota / network), the
|
|
1935
|
+
// ladder's fail-closed category would read as a capability mismatch
|
|
1936
|
+
// and send the diagnosis the wrong way. Keep the outage visible in
|
|
1937
|
+
// the node's category and explain why.
|
|
1938
|
+
const providerOutage = isProviderAvailabilityFailureCategory(result.failureCategory);
|
|
1906
1939
|
result = {
|
|
1907
1940
|
...result,
|
|
1908
1941
|
ok: false,
|
|
1909
|
-
failureCategory:
|
|
1942
|
+
failureCategory: providerOutage
|
|
1943
|
+
? "upstream-unavailable"
|
|
1944
|
+
: "unsupported-provider-capability",
|
|
1910
1945
|
stderr: [
|
|
1911
1946
|
result.stderr,
|
|
1912
|
-
|
|
1947
|
+
providerOutage
|
|
1948
|
+
? "frontend plan retry ladder: attempts failed on provider reachability (5xx / rate limit / quota / network), so this is an upstream outage, not a provider capability mismatch"
|
|
1949
|
+
: "frontend plan retry ladder: no compatible provider capability route for the protocol failure reason",
|
|
1913
1950
|
]
|
|
1914
1951
|
.filter(Boolean)
|
|
1915
1952
|
.join("\n"),
|
|
@@ -7,6 +7,8 @@ export function parseDagReconcileRunArgs(args) {
|
|
|
7
7
|
let reason;
|
|
8
8
|
for (let index = 0; index < args.length; index += 1) {
|
|
9
9
|
const arg = args[index];
|
|
10
|
+
if (arg === undefined)
|
|
11
|
+
break;
|
|
10
12
|
if (arg === "--run-id")
|
|
11
13
|
runId = args[++index];
|
|
12
14
|
else if (arg.startsWith("--run-id="))
|
|
@@ -330,7 +330,9 @@ export function resolveRepairTaskForGate(input) {
|
|
|
330
330
|
}
|
|
331
331
|
const candidates = directDownstream.filter(isGovernedRepairWriter);
|
|
332
332
|
if (candidates.length === 1) {
|
|
333
|
-
|
|
333
|
+
const [onlyCandidate] = candidates;
|
|
334
|
+
if (onlyCandidate)
|
|
335
|
+
return { ok: true, repairTask: onlyCandidate };
|
|
334
336
|
}
|
|
335
337
|
const candidateIds = directDownstream.map((task) => task.id).join(", ") || "none";
|
|
336
338
|
if (candidates.length === 0) {
|
|
@@ -449,6 +449,8 @@ export async function buildDagRunReportEntry(input) {
|
|
|
449
449
|
const rankNodes = input.state.ranks[rank] ?? [];
|
|
450
450
|
for (let order = 0; order < rankNodes.length; order += 1) {
|
|
451
451
|
const nodeId = rankNodes[order];
|
|
452
|
+
if (nodeId === undefined)
|
|
453
|
+
continue;
|
|
452
454
|
const node = input.state.nodes[nodeId];
|
|
453
455
|
if (!node)
|
|
454
456
|
continue;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isCanonicalFrontendShapeDag } from "./frontend-shape-facts.js";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import { readFile } from "node:fs/promises";
|
|
3
4
|
import { z } from "zod";
|
|
@@ -1348,6 +1349,15 @@ export async function evaluateDagRerunPlan(input) {
|
|
|
1348
1349
|
}
|
|
1349
1350
|
}
|
|
1350
1351
|
const closureSafety = assessResetClosureSafety(input.parentSpec, resetNodeIds, {
|
|
1352
|
+
// The canonical frontend template tails into read-only artifact shells
|
|
1353
|
+
// (review-context, closeout) that carry no commands. Without artifact
|
|
1354
|
+
// continuation admission every from-node restart of that template was
|
|
1355
|
+
// blocked as `restart-subgraph-contains-unsafe-shell`, so a frontend run
|
|
1356
|
+
// could only ever be re-verified by repeating the whole chain (smoke
|
|
1357
|
+
// r27-r36: ~30 min per iteration instead of ~6).
|
|
1358
|
+
...(isCanonicalFrontendShapeDag(new Map(input.parentSpec.tasks.map((task) => [task.id, task])))
|
|
1359
|
+
? { artifactContinuation: true }
|
|
1360
|
+
: {}),
|
|
1351
1361
|
...(transportWriterRestart && effectiveFromNodeId
|
|
1352
1362
|
? { allowedTransportWriterNodeId: effectiveFromNodeId }
|
|
1353
1363
|
: {}),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { access, readFile } from "node:fs/promises";
|
|
1
|
+
import { access, mkdir, readFile } from "node:fs/promises";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { generateTaskDagUseCase } from "../../application/dag/generate-task-dag.js";
|
|
@@ -8,6 +8,7 @@ import { stageRecoveryChild } from "./frontend-recovery-run.js";
|
|
|
8
8
|
import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
|
|
9
9
|
import { DAG_RUNS_DIR, isTerminalDagRunStatus, locateDagRun, readDagRunSpec, readDagRunState, } from "./lifecycle.js";
|
|
10
10
|
import { deriveDagRerunFeedback } from "./rerun-feedback.js";
|
|
11
|
+
import { readTypedEventStoreFromJsonl } from "./frontend-typed-event-store.js";
|
|
11
12
|
import { acquireDagRecoveryLease, bindDagRecoveryLeaseExecution, } from "./recovery-lease.js";
|
|
12
13
|
import { parseDagSpec, } from "./types.js";
|
|
13
14
|
export const RERUN_TASK_LINEAGE_REL_PATH = ".runtime/rerun-task-lineage.json";
|
|
@@ -26,6 +27,8 @@ export function parseDagRerunTaskArgs(args) {
|
|
|
26
27
|
let recoveryOperationId;
|
|
27
28
|
for (let index = 0; index < args.length; index += 1) {
|
|
28
29
|
const arg = args[index];
|
|
30
|
+
if (arg === undefined)
|
|
31
|
+
break;
|
|
29
32
|
if (arg === "--run-id")
|
|
30
33
|
parentRunId = args[++index];
|
|
31
34
|
else if (arg.startsWith("--run-id="))
|
|
@@ -396,6 +399,81 @@ async function executeFrontendRecoveryContinuation(input) {
|
|
|
396
399
|
if (!locatedChild || locatedChild.runDir !== staged.childRunDir) {
|
|
397
400
|
throw new Error(`frontend recovery child lifecycle drift: ${staged.childRunId}`);
|
|
398
401
|
}
|
|
402
|
+
// D (local design repair): publish a read-only snapshot of the parent's
|
|
403
|
+
// committed decision facts into the child run. The child plan node replays
|
|
404
|
+
// these through its own durable tools (normal commit entry, child binding)
|
|
405
|
+
// and the model only corrects the rows the design review flagged; the
|
|
406
|
+
// parent ledger is never rewritten and the finalize terminal is not
|
|
407
|
+
// inherited. Best-effort: a parent without plan facts plans fresh.
|
|
408
|
+
try {
|
|
409
|
+
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")
|
|
444
|
+
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
|
+
});
|
|
451
|
+
}
|
|
452
|
+
}
|
|
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
|
+
}
|
|
399
477
|
const childSpec = await readDagRunSpec(locatedChild.runDir);
|
|
400
478
|
const childState = await readDagRunState(locatedChild.runDir);
|
|
401
479
|
let runSummary;
|
|
@@ -364,6 +364,24 @@ export function computeBackoffDelayMs(attemptNumber, policy) {
|
|
|
364
364
|
const raw = policy.initialDelayMs * 2 ** exponent;
|
|
365
365
|
return Math.min(raw, policy.maxDelayMs);
|
|
366
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Provider-reachability failure categories: the attempt never reached model
|
|
369
|
+
* reasoning, so no capability conclusion may be drawn from it. Used to keep the
|
|
370
|
+
* plan retry ladder from relabelling an upstream outage as
|
|
371
|
+
* `unsupported-provider-capability` (2026-09-11: the gateway returned 503 while
|
|
372
|
+
* r18/r19 reported the vague capability category).
|
|
373
|
+
*/
|
|
374
|
+
export const PROVIDER_AVAILABILITY_FAILURE_CATEGORIES = [
|
|
375
|
+
"unavailable",
|
|
376
|
+
"upstream-unavailable",
|
|
377
|
+
"network",
|
|
378
|
+
"rate-limit",
|
|
379
|
+
"quota",
|
|
380
|
+
];
|
|
381
|
+
export function isProviderAvailabilityFailureCategory(category) {
|
|
382
|
+
return (category !== undefined &&
|
|
383
|
+
PROVIDER_AVAILABILITY_FAILURE_CATEGORIES.includes(category));
|
|
384
|
+
}
|
|
367
385
|
/**
|
|
368
386
|
* A+B (AC-001/AC-005): project raw executor signals to the canonical 7-value
|
|
369
387
|
* protocol failure reason. Specific signals win first, then the existing
|
|
@@ -115,7 +115,7 @@ export const FRONTEND_WRITER_NODE_IDS = [
|
|
|
115
115
|
];
|
|
116
116
|
/**
|
|
117
117
|
* Run-relative artifact location read by the frontend writer admission gate.
|
|
118
|
-
* M8
|
|
118
|
+
* M8 points the admission source at the canonical
|
|
119
119
|
* frontend-writer-admission-result.json artifact (written by the
|
|
120
120
|
* frontend-writer-admission-shell); the exported name is retained because
|
|
121
121
|
* runner.ts / node-execution.ts reference it as the admission evidence source.
|
|
@@ -125,9 +125,7 @@ export { FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT };
|
|
|
125
125
|
/**
|
|
126
126
|
* Read and validate the writer admission result artifact.
|
|
127
127
|
* Fail-closed: a missing file or invalid payload returns ok:false and never
|
|
128
|
-
* throws. This is the M8 write authorization source
|
|
129
|
-
* frontend-prewrite-result-v1 for dispatch; the legacy artifact remains
|
|
130
|
-
* produced only by the shadow `runFrontendPrewriteGate` library export).
|
|
128
|
+
* throws. This is the M8 write authorization source for dispatch.
|
|
131
129
|
*/
|
|
132
130
|
export async function readFrontendPrewriteResult(runDir) {
|
|
133
131
|
const artifactPath = path.join(runDir, FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT);
|
|
@@ -192,6 +192,25 @@ export const dagJsonArtifactGateSchema = z.object({
|
|
|
192
192
|
const dagFrontendNodeIdSchema = z
|
|
193
193
|
.string()
|
|
194
194
|
.regex(/^[a-z][a-z0-9-]*$/, "frontend node id must be kebab-case");
|
|
195
|
+
/**
|
|
196
|
+
* Requirement id accepted in a generated DAG's `requiredRequirementIds`.
|
|
197
|
+
*
|
|
198
|
+
* These ids are lifted verbatim from the task requirement ledger, which mirrors
|
|
199
|
+
* whatever the PRD wrote. A PRD that writes `AC1` (no hyphen) therefore yields an
|
|
200
|
+
* id this schema rejects, and `dagSpecSchema.parse` surfaces zod's raw issue array
|
|
201
|
+
* - so the operator saw only `"message": "Invalid"` plus a JSON pointer and had no
|
|
202
|
+
* way to learn the constraint. The message below carries it into that error.
|
|
203
|
+
*
|
|
204
|
+
* This is deliberately a fail-closed check, not a normalizer: `AC1` is
|
|
205
|
+
* canonicalized to `AC-1` upstream by `normalizeAcceptanceId` in the semantic
|
|
206
|
+
* intake, so every workflow reads the same ids. What remains here is the guard
|
|
207
|
+
* for genuinely malformed input - and because `dagSpecSchema.parse` surfaces
|
|
208
|
+
* zod's raw issue array, the message below is what makes that guard
|
|
209
|
+
* self-explanatory instead of `"message": "Invalid"` plus a JSON pointer.
|
|
210
|
+
*/
|
|
211
|
+
const dagRequirementIdSchema = z
|
|
212
|
+
.string()
|
|
213
|
+
.regex(/^(?:REQ|BR|AC)-[A-Z0-9]+(?:-[A-Z0-9]+)*$/, 'requirement id must be "<REQ|BR|AC>-<SEGMENT>" with a hyphen after the prefix (e.g. AC-1, AC-FE-001, REQ-SRC-ABC123); ids come verbatim from the task requirement ledger, so a PRD writing "AC1" must write "AC-1"');
|
|
195
214
|
const openspecCandidatePathSchema = z
|
|
196
215
|
.string()
|
|
197
216
|
.refine((candidate) => !candidate.includes("\\") &&
|
|
@@ -210,9 +229,7 @@ export const dagFrontendPrewriteGateSchema = z.object({
|
|
|
210
229
|
planFallbackFromNodeIds: z.array(dagFrontendNodeIdSchema).default([]),
|
|
211
230
|
reviewFromNodeId: dagFrontendNodeIdSchema,
|
|
212
231
|
reviewFallbackFromNodeIds: z.array(dagFrontendNodeIdSchema).default([]),
|
|
213
|
-
requiredRequirementIds: z
|
|
214
|
-
.array(z.string().regex(/^(?:REQ|BR|AC)-[A-Z0-9]+(?:-[A-Z0-9]+)*$/))
|
|
215
|
-
.default([]),
|
|
232
|
+
requiredRequirementIds: z.array(dagRequirementIdSchema).default([]),
|
|
216
233
|
allowedMockStrategies: z
|
|
217
234
|
.array(z.enum(["native", "browser-intercept", "request-adapter", "not-needed"]))
|
|
218
235
|
.min(1),
|
|
@@ -422,9 +439,7 @@ export const dagFrontendDesignPolicySchema = z
|
|
|
422
439
|
.object({
|
|
423
440
|
schemaVersion: z.literal(1),
|
|
424
441
|
planFromNodeId: dagFrontendNodeIdSchema,
|
|
425
|
-
requiredRequirementIds: z
|
|
426
|
-
.array(z.string().regex(/^(?:REQ|BR|AC)-[A-Z0-9]+(?:-[A-Z0-9]+)*$/))
|
|
427
|
-
.default([]),
|
|
442
|
+
requiredRequirementIds: z.array(dagRequirementIdSchema).default([]),
|
|
428
443
|
allowedMockStrategies: z
|
|
429
444
|
.array(z.enum(["native", "browser-intercept", "request-adapter", "not-needed"]))
|
|
430
445
|
.min(1),
|
|
@@ -434,6 +449,29 @@ export const dagFrontendDesignPolicySchema = z
|
|
|
434
449
|
outputDir: z.string().regex(/^[a-z0-9][a-z0-9._-]*$/),
|
|
435
450
|
requireSourceFreshness: z.literal(true),
|
|
436
451
|
implementationWriteSet: z.array(z.string().min(1)).min(1).optional(),
|
|
452
|
+
/** Generation-frozen requirement→file ownership. Violations are
|
|
453
|
+
* machine-rejected at plan finalize (smoke r35: prose-only ownership
|
|
454
|
+
* rules were ignored by the planner and re-violated by recovery). */
|
|
455
|
+
requirementOwnership: z
|
|
456
|
+
.array(z
|
|
457
|
+
.object({
|
|
458
|
+
requirementIds: z.array(z.string().min(1)).min(1),
|
|
459
|
+
implementationFiles: z.array(z.string().min(1)).optional(),
|
|
460
|
+
verificationFiles: z.array(z.string().min(1)).optional(),
|
|
461
|
+
})
|
|
462
|
+
.strict())
|
|
463
|
+
.optional(),
|
|
464
|
+
/** Generation-frozen test capability boundary composed into the
|
|
465
|
+
* canonical dependencyPolicy by the runtime. */
|
|
466
|
+
capabilityBoundary: z
|
|
467
|
+
.object({
|
|
468
|
+
allowed: z.array(z.string().min(1)).optional(),
|
|
469
|
+
forbidden: z.array(z.string().min(1)).optional(),
|
|
470
|
+
})
|
|
471
|
+
.strict()
|
|
472
|
+
.optional(),
|
|
473
|
+
/** Generation-frozen interaction id vocabulary (plan finalize check). */
|
|
474
|
+
interactionIds: z.array(z.string().min(1)).optional(),
|
|
437
475
|
/** Generation-frozen roots that bound custom normative directories. */
|
|
438
476
|
openspecSpecRoots: z
|
|
439
477
|
.array(z.string().refine((root) => isValidFrontendSpecRoot(root), "openspec spec root must be a normalized repo-relative directory"))
|
|
@@ -222,6 +222,8 @@ function validateRepairArtifactGateConfig(task, spec, issues) {
|
|
|
222
222
|
return;
|
|
223
223
|
}
|
|
224
224
|
const hardVerify = hardVerifyCandidates[0];
|
|
225
|
+
if (!hardVerify)
|
|
226
|
+
return;
|
|
225
227
|
const descendantIds = new Set();
|
|
226
228
|
const queue = [hardVerify.id];
|
|
227
229
|
while (queue.length > 0) {
|
|
@@ -411,6 +413,8 @@ function validateSameRankWriteSetConflicts(spec, ranks, issues) {
|
|
|
411
413
|
for (let j = i + 1; j < exclusiveWriters.length; j += 1) {
|
|
412
414
|
const left = exclusiveWriters[i];
|
|
413
415
|
const right = exclusiveWriters[j];
|
|
416
|
+
if (!left || !right)
|
|
417
|
+
continue;
|
|
414
418
|
const leftSet = left.writeSet ?? [];
|
|
415
419
|
const rightSet = right.writeSet ?? [];
|
|
416
420
|
for (const leftEntry of leftSet) {
|
package/docs/README.md
CHANGED
|
@@ -80,5 +80,6 @@
|
|
|
80
80
|
| `reports/` | 验证、dogfood、merge、init evolution 与历史 handoff 证据 |
|
|
81
81
|
| `skills/` | repo-local skill registry |
|
|
82
82
|
| `templates/` | 可复用任务、报告、DAG 和 init 模板 |
|
|
83
|
+
| `fixtures/` | 文档与前端 DAG 验收使用的固定输入 |
|
|
83
84
|
|
|
84
85
|
站上使用者文档在 `../website/docs/`;源仓治理事实以本目录、`AGENTS.md`、`harness.json`、`CHANGELOG.md` 和检查脚本为准。
|
|
@@ -205,15 +205,15 @@ Runtime 变更另需 `npm run typecheck` 及对应 targeted Vitest(见 exec pl
|
|
|
205
205
|
|
|
206
206
|
| 面 | 路径 / 入口 | 边界 |
|
|
207
207
|
| --- | --- | --- |
|
|
208
|
-
| OpenCode transient-retry | `.opencode/plugins/loop-agent-transient-retry.js`(init surface `generated`) |
|
|
208
|
+
| OpenCode transient-retry | `.opencode/plugins/loop-agent-transient-retry.js`(init surface `generated`) | 瞬态 UnknownError / TypeValidation wrapper 及已知被裁剪的内部 provider 波动文案 resume;busy/retry 门控 + backoff;overflow/401/配额/取消/业务标 permanent(`plugin-ignore-permanent-error`),**不** compact |
|
|
209
209
|
| OpenCode overflow-compact | `.opencode/plugins/loop-agent-context-overflow-compact.js`(init surface `generated`) | 仅 context overflow → `session.compact`(无则 `summarize`)+ 有限 `promptAsync` 续接;`MAX_OVERFLOW_RECOVERIES ≤ 2`;session 锁;非 overflow 不动作 |
|
|
210
210
|
| Pi project extension | `.pi/extensions/loop-agent-context-overflow.js`(init surface `generated`) | `message_end` 上将 overflow `errorMessage` 幂等改写为 `context_length_exceeded:` 前缀,触发 Pi 原生 compact/retry;分类器与控制器共享 P1–P10 / N1–N5 语料(含嵌套 JSON);**不**写 `~/.pi` settings / compaction / 模型窗口,**不**投影 sift native |
|
|
211
|
-
| Console / DAG 运行时 | npm 内置 inline extension + 可选 `@agent-context/sift` |
|
|
211
|
+
| Console / DAG 运行时 | npm 内置 inline extension + 可选 `@agent-context/sift` | Console 无需 init 即启用内部 provider transient 规范化、字段级 retry process defaults 与 L0/L1/L2;项目显式 retry 字段优先于用户全局字段,再优先于推荐默认值。DAG 使用独立 in-memory retry/compaction,且不做 streaming 主动 compact。`HARNESS_CONTEXT_PRESSURE_MODE=off` 只关 L0/L2,不关闭 Console transient 恢复;`HARNESS_CONSOLE_SIFT` / `HARNESS_DAG_SIFT` 的 `0\|false\|off` 关 L1。不进入目标项目 init 文件 |
|
|
212
212
|
| Pi 用户配置 | `~/.pi/agent/settings.json` | **不**进入项目 `.harness/init-surface.json` hash;仅 `--client-recovery=user` 可字段级补缺并原子写;`auto`/`project`/`off` 与 `check-update` 默认零写 home;读取时只有 `ENOENT` 视为缺文件,其他 I/O 错误 fail closed |
|
|
213
213
|
| CLI mode | `--client-recovery=auto\|project\|user\|off`(默认 `auto`) | `auto`/`project` 安装上述三份项目产物;`user` = 三产物 + 显式 Pi retry 合并;`off` 全跳过 |
|
|
214
214
|
| Ownership | recorded sha256 + apply-safe | 三份 generated 缺失可补、与 recorded hash 一致可升级;用户改过 → model merge / human decision,禁止静默覆盖 |
|
|
215
215
|
|
|
216
|
-
实现落点:`src/
|
|
216
|
+
实现落点:`src/shared/pi-provider-recovery.ts`(内置规则、纯 `additionalRules` 扩展接口与 generated predicate)、`src/shared/pi-retry-settings.ts`(字段级 process defaults)、`src/shared/pi-context-pressure/` 与 `src/worker/console/chat/pi-runtime.ts`(Console inline normalization),以及 `src/commands/client-recovery.ts` / `src/commands/init.ts`(项目投影与 surface 编排)。
|
|
217
217
|
|
|
218
218
|
## 演进里程碑
|
|
219
219
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
- [`harness-methodology-tdd.md`](harness-methodology-tdd.md):测试先行的方法与边界。
|
|
11
11
|
- [`harness-methodology-verification.md`](harness-methodology-verification.md):如何用新鲜命令结果支持完成声明。
|
|
12
12
|
- [`harness-methodology-debugging.md`](harness-methodology-debugging.md):系统化定位故障,不用猜测代替证据。
|
|
13
|
+
- [`defect-ledger.md`](defect-ledger.md):真实缺陷台账与优先级规则——治理目标先从真故障选,再看代理指标排名。
|
|
13
14
|
- [`document-review-policy.md`](document-review-policy.md):文档 freshness、`reviewTier` 与 `lastReviewed` 更新边界。
|
|
14
15
|
- [`lightweight-github-collaboration.md`](lightweight-github-collaboration.md):短分支、简短 PR、CI 与 Squash Merge 的轻量协作规则。
|
|
15
16
|
- [`研发模式.md`](研发模式.md):Feature 团队推进、交付和知识回写方法论。
|
|
@@ -364,6 +364,7 @@
|
|
|
364
364
|
"description": "Documentation and user-facing guidance changes that should be considered but should not slow normal iteration.",
|
|
365
365
|
"patterns": [
|
|
366
366
|
"CHANGELOG.md",
|
|
367
|
+
"CHANGELOG/**",
|
|
367
368
|
"website/docs/**",
|
|
368
369
|
"docs/*.md",
|
|
369
370
|
"docs/architecture/**"
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
## 入口
|
|
6
6
|
|
|
7
|
+
- [`scheduled-goal-host.md`](scheduled-goal-host.md):Console Chat 预约宿主、服务环境、状态判读与清理。
|
|
8
|
+
|
|
7
9
|
- [`local-development-environment.md`](local-development-environment.md):本地环境、Windows 差异和常见排障。
|
|
8
10
|
- [`branch-merge-guideline.md`](branch-merge-guideline.md):按风险选择合并模式并留下 source-SHA 证据。
|
|
9
11
|
- [`github-collaboration.md`](github-collaboration.md):仓库内 GitHub 协作约定及发布通道。
|
package/docs/templates/README.md
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
## Backend-test
|
|
32
32
|
|
|
33
|
-
- `backend-test-dag.json` — backend-test DAG
|
|
33
|
+
- `backend-test-dag.json` — backend-test DAG 模板;由 runtime builder 生成,Module Index 的 8 列、separator、单一 resolved Markdown Path 和 Split Reason 集合以 `backend-test-plan-protocol.ts` 为真源并由 drift test 校验;其中 `generate-backend-md-cases-pi` 是唯一允许 `writer-empty-diff` 重试的 writer(总共两次,仅限 post-write-guard attribution 确认的空 diff);N2/N5 合同限定 Scenario Partition 必须有源有限域。
|
|
34
34
|
- `backend-test-dag.classify.prompt.md`、`backend-test-dag.generate-pytest.prompt.md`、`backend-test-dag.review-cases.prompt.md`、`backend-test-dag.retrospect.prompt.md` — 分类、生成、审查和复盘提示。
|
|
35
35
|
- `backend-test-analysis.schema.json`、`backend-test-execution.schema.json`、`backend-test-result.schema.json`、`backend-test-case-manifest.schema.json` — 分析、执行、结果与用例清单 schema。
|
|
36
36
|
|
|
@@ -466,9 +466,9 @@
|
|
|
466
466
|
"retryCategories": {
|
|
467
467
|
"type": "array",
|
|
468
468
|
"items": {
|
|
469
|
-
"enum": ["timeout", "network", "rate-limit", "unavailable", "empty-output", "output-limit", "output-too-large", "protocol-invalid", "invalid-output", "writer-empty-diff", "incomplete-write-set", "writer-clean-timeout", "read-burst", "context-overflow"]
|
|
469
|
+
"enum": ["timeout", "network", "rate-limit", "unavailable", "upstream-unavailable", "empty-output", "output-limit", "output-too-large", "protocol-invalid", "invalid-output", "writer-empty-diff", "incomplete-write-set", "writer-clean-timeout", "read-burst", "context-overflow"]
|
|
470
470
|
},
|
|
471
|
-
"default": ["timeout", "network", "rate-limit", "unavailable", "empty-output", "output-limit"],
|
|
471
|
+
"default": ["timeout", "network", "rate-limit", "unavailable", "upstream-unavailable", "empty-output", "output-limit"],
|
|
472
472
|
"description": "Failure categories eligible for retry. quota/auth/write-guard are never eligible. invalid-output is allowed only on explicit structured/protocol policies; writer-empty-diff and incomplete-write-set are reserved for requireChangedFiles generation/completeness writers; writer-clean-timeout is reserved for standard bounded writers after explicit zero-write-tool-call and empty-diff evidence."
|
|
473
473
|
}
|
|
474
474
|
}
|