@tea-agent/loop-agent 0.42.0-next.1 → 0.42.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.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +321 -1
- package/dist/application/dag/generate-task-dag.js +75 -19
- package/dist/application/dag/run-dag.js +41 -0
- package/dist/application/task-lifecycle/advance.js +24 -5
- package/dist/application/task-lifecycle/observe.js +171 -17
- package/dist/application/task-lifecycle/plan-transitions.js +42 -7
- package/dist/application/task-lifecycle/recommendations.js +13 -2
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +7 -0
- package/dist/cli/program.js +6 -1
- package/dist/commands/client-recovery.js +3 -0
- package/dist/commands/dag-follow-up.js +138 -0
- package/dist/commands/dag-rerun-task.js +2 -0
- package/dist/commands/init.js +27 -1
- package/dist/commands/task-advance.js +19 -0
- package/dist/executors/dag-pi-executor.js +4010 -78
- package/dist/executors/pi-executor.js +15 -4
- package/dist/executors/pi-extension-resolver.js +14 -2
- package/dist/executors/pi-read-budget-policy.js +239 -0
- package/dist/executors/shell-executor.js +978 -188
- package/dist/executors/shell-write-guard.js +7 -0
- package/dist/infrastructure/console/operation-store.js +226 -6
- package/dist/shared/dag-failure-category.js +12 -0
- package/dist/shared/openspec-spec.js +70 -4
- package/dist/shared/operator/capabilities.js +7 -0
- package/dist/task/config-types.js +105 -5
- package/dist/task/contract/adopt.js +4 -0
- package/dist/task/contract/import-revision.js +4 -0
- package/dist/task/contract/project.js +3 -0
- package/dist/task/contract/schema.js +2 -1
- package/dist/task/frontend-project-capability.js +203 -20
- package/dist/task/runtime.js +5 -2
- package/dist/task/source-prepare/build-draft.js +3 -3
- package/dist/task/source-prepare/fragment-inventory.js +64 -25
- package/dist/task/source-prepare/prepare.js +126 -21
- package/dist/task/source-prepare/semantic-intake.js +6 -2
- package/dist/task/source-references.js +22 -1
- package/dist/worker/console/chat/chat-ui-policy.js +4 -2
- package/dist/worker/console/chat/model-resolver.js +7 -4
- package/dist/worker/console/chat/pi-runtime.js +258 -11
- package/dist/worker/console/chat/repo-browser.js +10 -3
- package/dist/worker/console/chat/routes.js +165 -71
- package/dist/worker/console/chat/sdd-data-alignment.js +222 -0
- package/dist/worker/console/chat/session-catalog.js +2 -0
- package/dist/worker/console/chat/session-store.js +159 -70
- package/dist/worker/console/chat/shortcuts.js +19 -3
- package/dist/worker/console/chat/turn-process.js +111 -56
- package/dist/worker/console/frontend-human-decision-adapter.js +19 -0
- package/dist/worker/console/frontend-split-operation-adapter.js +20 -0
- package/dist/worker/console/index.js +3 -0
- package/dist/worker/console/operator-actions.js +169 -7
- package/dist/worker/console/pi-readiness.js +3 -2
- package/dist/worker/console/server.js +23 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DZZ8m3PO.js → abnfDiagram-N423BO3Z-CcS17TBr.js} +1 -1
- package/dist/worker/console/static/assets/{arc-D6PvaVd-.js → arc-COptKq2S.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-B_OTOiI8.js → architectureDiagram-T3A2C74G-h4LKMHjP.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-Bv6rqHBg.js → blockDiagram-VBNYF7ZC-COA1MOH0.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-B8eHr0oz.js → c4Diagram-5PPSVZJV-DJUf0QPm.js} +1 -1
- package/dist/worker/console/static/assets/channel-DdBCaOJ6.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-DYwR0im2.js → chunk-2GRJ4B5K-mtWfKrUX.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-D2WPGqXt.js → chunk-2Q5K7J3B-B8pXsxDQ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-CQISJ_I7.js → chunk-5RXB4S5H-ipKzByl1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-C0o2Du1e.js → chunk-5VM5RSS4-DYi3Ald_.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-4f8kr-U7.js → chunk-6Q2QTUOP-DQtGYoty.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-D_OWvXzX.js → chunk-GF5L2VYU-BU0qS2YV.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CasdPz5X.js → chunk-JWPE2WC7-DVH9dIGE.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-Cj8lRrla.js → chunk-KBJHAD2P-Dt60SmgM.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-CUvD1FSd.js → chunk-RYQCIY6F-BoaUGuEY.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CqLw_eqB.js → chunk-XXDRQBXY-_WHFDTp2.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DZFra1GO.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DZFra1GO.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-ku-WqJPx.js → cose-bilkent-JH36ORCC-BxkbTIRd.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-Bq_PYDhl.js → cynefin-VYW2F7L2-Bf2UVnoG.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BiGZV641.js → cynefinDiagram-MW4NZA55-Bo23q1J_.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-C4JRlglF.js → dagre-VZM6K2ZE-Dd_UU49i.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-B0dNeWYG.js → diagram-7IWD3JNH-ebUa1a9y.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-Cj35YvYM.js → diagram-B4RE2ZJO-BucthU8r.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-uzQoJ2-8.js → diagram-LBJQPF4R-BgqNpAkm.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-D1a-Buoz.js → diagram-Q27KOJAE-DC4q5NGa.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-XjRrLRSs.js → diagram-UB23O5K3-CBqCaMeb.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Da_O24cW.js → ebnfDiagram-BXEA7PRR-CGtnbQ3-.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-BLJ8jrYU.js → erDiagram-JOGREHBK-CG3LUao5.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-B9GrLjM0.js → flowDiagram-UKHOOZJN-D2ZVgoFS.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-CeJ0TqiK.js → ganttDiagram-PKOTCBZU-DoYFZiKt.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bm2eNNFX.js → gitGraphDiagram-DS77QQ5N-CKoP1s6j.js} +1 -1
- package/dist/worker/console/static/assets/index-CAZ2fC_X.css +1 -0
- package/dist/worker/console/static/assets/index-vbTcFnFs.js +449 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DB26i3d8.js → infoDiagram-6WML65LV-Duofv8p2.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BOGRyeZT.js → ishikawaDiagram-WSZJBQD7-D2nlCkA1.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CZRoBO_6.js → journeyDiagram-NVQOT4AX-Dd4IHdus.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-qlWhJyoB.js → kanban-definition-27J2QSJJ-Bi20AOdt.js} +1 -1
- package/dist/worker/console/static/assets/{linear-CfUiDDB3.js → linear-D59YJ9kB.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-BQe6fpqj.js → mermaid.core-Bl13LpNa.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-zFzWHw64.js → mindmap-definition-FAOFIHXS-C6DLP5eY.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DFGUqjZO.js → pegDiagram-VL7TDLO6-BjO4cy64.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-BB5i0l8Z.js → pieDiagram-7S7Q4E2Y-D7i2qZTG.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-obbVZ_X5.js → quadrantDiagram-CIZ2JOQS-Dx8o_h0y.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BwdaNzc1.js → railroadDiagram-AXF67PYL-B55orI_t.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-CkTJaugh.js → requirementDiagram-LRYGKXZP-zWaehp6f.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-BwJ-hIgq.js → sankeyDiagram-W5VNT64P-CcA-pjvD.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BzSgmm7w.js → sequenceDiagram-SI44F4Z6-BOFbzNHI.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-Bn3oj5Q1.js → sizeCapture-X5ZJPWSS-BjAejah1.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-dxhGtL8K.js → stateDiagram-OKZ733FA-DXYwxJwZ.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Clg3V9t1.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-BLpEInya.js → swimlanes-SLNWSIFB-OYiOch8n.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DX1dxAAW.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-ChJGYcXy.js → timeline-definition-Z64GVDOM-cZfH3nmU.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DK-qjRer.js → vennDiagram-T6HMQDX7-BDE7b3E1.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-3qeaWAg-.js → wardleyDiagram-T6FBY63Y-kyyGy9WJ.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-CootlyP9.js → xychartDiagram-ELKLHX3M-CJj6VTog.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/active-run-badge.js +17 -0
- package/dist/worker/console/static-src/app/useRecoveryConsole.js +5 -5
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +19 -8
- package/dist/worker/console/static-src/operator-chat/input-history.js +8 -6
- package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +15 -7
- package/dist/worker/console/static-src/operator-chat/runtime-snapshot-store.js +10 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +258 -23
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +112 -4
- package/dist/worker/console/static-src/operator-chat/useComposer.js +13 -4
- package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +29 -6
- package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +8 -2
- package/dist/worker/console/static-src/shell/console-update-reload.js +36 -9
- package/dist/worker/console/static-src/shell/workspace-route.js +11 -0
- package/dist/worker/console/workspace-context.js +115 -1
- package/dist/worker/materialize/frontend-split-task-materializer.js +72 -0
- package/dist/worker/observe/routes.js +4 -0
- package/dist/worker/observe/static/constants.js +22 -22
- package/dist/worker/observe/static/dag-context-reason-labels.js +19 -0
- package/dist/worker/observe/static/dag-helpers.js +4 -2
- package/dist/worker/observe/static/dag-history-labels.js +1 -0
- package/dist/worker/observe/static/dag-inspector-humanize.d.ts +16 -0
- package/dist/worker/observe/static/dag-inspector-humanize.js +339 -0
- package/dist/worker/observe/static/dag-node-purpose.js +13 -8
- package/dist/worker/observe/static/index.html +4 -4
- package/dist/worker/observe/static/inspect-workspace.js +23 -0
- package/dist/worker/observe/static/kpi.js +2 -2
- package/dist/worker/observe/static/operator-chrome.d.ts +10 -2
- package/dist/worker/observe/static/operator-chrome.js +37 -23
- package/dist/worker/observe/static/prompt-restart-candidates.js +4 -2
- package/dist/worker/observe/static/relations.js +7 -7
- package/dist/worker/observe/static/router.d.ts +12 -1
- package/dist/worker/observe/static/router.js +48 -6
- package/dist/worker/observe/static/run-processing.js +4 -2
- package/dist/worker/observe/static/shell-chrome.js +2 -2
- package/dist/worker/observe/static/state.js +5 -0
- package/dist/worker/observe/static/styles.css +231 -0
- package/dist/worker/observe/static/views/dag-graph.js +1 -1
- package/dist/worker/observe/static/views/dag-inspector.js +336 -181
- package/dist/worker/observe/static/views/dag.js +26 -14
- package/dist/worker/observe/static/views/dags.js +3 -1
- package/dist/worker/observe/static/views/dashboard.js +14 -6
- package/dist/worker/observe/static/views/pool.js +7 -2
- package/dist/worker/observe/static/views/run.js +12 -3
- package/dist/worker/observe/static/views/session-timeline.js +74 -13
- package/dist/worker/observe/static/views/task.js +7 -2
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +215 -28
- package/dist/workflows/dag/backend-test-markdown-workflow.js +13 -1
- package/dist/workflows/dag/backend-test-plan-protocol.js +210 -0
- package/dist/workflows/dag/backend-test-scenario-param.js +172 -25
- package/dist/workflows/dag/backend-test-scenario-partitions.js +62 -1
- package/dist/workflows/dag/backend-test-writer-completeness.js +104 -12
- package/dist/workflows/dag/contract-validator-registrations.js +1 -2
- package/dist/workflows/dag/dag-retry-schema.js +138 -0
- package/dist/workflows/dag/frontend-closeout.js +221 -0
- package/dist/workflows/dag/frontend-design-policy.js +400 -0
- package/dist/workflows/dag/frontend-human-decision.js +182 -0
- package/dist/workflows/dag/frontend-implementation-contract.js +1237 -192
- package/dist/workflows/dag/frontend-plan-render.js +2 -1
- package/dist/workflows/dag/frontend-prewrite-gate.js +256 -350
- package/dist/workflows/dag/frontend-provider-capability-matrix.js +159 -0
- package/dist/workflows/dag/frontend-recovery-capsule.js +455 -0
- package/dist/workflows/dag/frontend-recovery-controller.js +226 -0
- package/dist/workflows/dag/frontend-recovery-lineage.js +178 -0
- package/dist/workflows/dag/frontend-recovery-plan.js +21 -10
- package/dist/workflows/dag/frontend-recovery-run.js +166 -34
- package/dist/workflows/dag/frontend-repair.js +1 -432
- package/dist/workflows/dag/frontend-review-context.js +261 -15
- package/dist/workflows/dag/frontend-review-findings.js +270 -0
- package/dist/workflows/dag/frontend-shadow-dual-write.js +941 -0
- package/dist/workflows/dag/frontend-shape-capsule-store.js +191 -0
- package/dist/workflows/dag/frontend-shape-facts.js +419 -0
- package/dist/workflows/dag/frontend-shape.js +435 -0
- package/dist/workflows/dag/frontend-source-fidelity-ledger.js +108 -0
- package/dist/workflows/dag/frontend-split-application-service.js +203 -0
- package/dist/workflows/dag/frontend-split-orchestrator.js +899 -0
- package/dist/workflows/dag/frontend-typed-event-store.js +452 -0
- package/dist/workflows/dag/frontend-typed-event-transaction.js +180 -0
- package/dist/workflows/dag/frontend-verification-trace.js +252 -25
- package/dist/workflows/dag/frontend-worktree-diff.js +250 -17
- package/dist/workflows/dag/frontend-writer-admission.js +319 -0
- package/dist/workflows/dag/frontend-writer-status.js +256 -0
- package/dist/workflows/dag/init-hybrid.js +1031 -564
- package/dist/workflows/dag/interrupt-request.js +7 -0
- package/dist/workflows/dag/node-execution.js +854 -4
- package/dist/workflows/dag/prompt.js +70 -3
- package/dist/workflows/dag/recovery-lease.js +170 -0
- package/dist/workflows/dag/report.js +37 -1
- package/dist/workflows/dag/rerun-feedback.js +315 -1
- package/dist/workflows/dag/rerun-plan.js +17 -6
- package/dist/workflows/dag/rerun-run.js +44 -6
- package/dist/workflows/dag/rerun-task.js +251 -13
- package/dist/workflows/dag/retry-policy.js +230 -104
- package/dist/workflows/dag/runner.js +580 -124
- package/dist/workflows/dag/scheduler.js +133 -20
- package/dist/workflows/dag/types.js +244 -16
- package/dist/workflows/dag/validate.js +28 -12
- package/docs/examples/README.md +5 -0
- package/docs/init-surface.manifest.json +30 -12
- package/docs/skills/vetted-skill-registry.md +4 -2
- package/docs/templates/README.md +2 -0
- package/docs/templates/agent-dag-report.schema.json +8 -2
- package/docs/templates/agent-dag.schema.json +1 -1
- package/docs/templates/backend-test-dag.json +25 -20
- package/docs/templates/frontend-implementation-contract.schema.json +4 -1
- package/docs/templates/frontend-implementation-dag.json +89 -0
- package/docs/templates/spec-registry.schema.json +45 -0
- package/harness.json +1 -1
- package/package.json +4 -3
- package/skills/frontend-bounded-implement/SKILL.md +15 -14
- package/skills/frontend-bounded-implement/references/code-standards.md +19 -0
- package/skills/frontend-contract/SKILL.md +23 -0
- package/skills/frontend-contract/references/contract-protocol.md +34 -0
- package/skills/frontend-design-review/SKILL.md +22 -41
- package/skills/frontend-plan/SKILL.md +26 -0
- package/skills/frontend-plan/references/decision-contract.md +37 -0
- package/skills/frontend-plan/references/design-decisions.md +17 -0
- package/skills/frontend-review/SKILL.md +20 -15
- package/skills/frontend-review/references/review-findings.md +6 -7
- package/skills/frontend-scout/SKILL.md +25 -0
- package/skills/frontend-scout/references/design-evidence.md +16 -0
- package/skills/frontend-scout/references/scout-evidence.md +23 -0
- package/skills/frontend-verification/SKILL.md +1 -1
- package/skills/loop-agent/references/command-reference.md +1 -0
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/dist/worker/console/static/assets/channel-BU5gOilw.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DIzKJGHr.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DIzKJGHr.js +0 -1
- package/dist/worker/console/static/assets/index-H9rFJiGL.css +0 -1
- package/dist/worker/console/static/assets/index-xwu9GxEc.js +0 -451
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-Cld2qK9v.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-TIHpiT7w.js +0 -8
- package/skills/frontend-implementation/SKILL.md +0 -52
- package/skills/frontend-implementation/references/code-standards.md +0 -33
- package/skills/frontend-implementation/references/design-spec.md +0 -56
- package/skills/frontend-implementation/references/node-contracts.md +0 -31
|
@@ -3,10 +3,10 @@ import path from "node:path";
|
|
|
3
3
|
import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
|
|
4
4
|
import { sha256Hex } from "./frontend-implementation-contract.js";
|
|
5
5
|
import { FRONTEND_RECOVERY_IMPORT_MANIFEST_REL_PATH, FRONTEND_RECOVERY_INTENT_REL_DIR, FRONTEND_RECOVERY_STAGING_PREFIX, computeFrontendRecoveryPlan, computeFrontendRecoveryPlanForSource, } from "./frontend-recovery-plan.js";
|
|
6
|
-
import { dagRunDirExists, getDagRunDir, readDagRunSpec, readDagRunState, transferDagRunDir, writeDagRunState, } from "./lifecycle.js";
|
|
6
|
+
import { dagRunDirExists, getDagRunDir, locateDagRun, readDagRunSpec, readDagRunState, transferDagRunDir, writeDagRunState, } from "./lifecycle.js";
|
|
7
7
|
import { buildDagRunId } from "./runner.js";
|
|
8
8
|
import { prepareRunDir, writeNodeRecord } from "./run-store.js";
|
|
9
|
-
import {
|
|
9
|
+
import { FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT, readFrontendWriterAdmissionResult, } from "./scheduler.js";
|
|
10
10
|
import { topoSortToRanks } from "./topo.js";
|
|
11
11
|
/**
|
|
12
12
|
* Candidate-continuation child creation kernel (phase 3b).
|
|
@@ -19,8 +19,8 @@ import { topoSortToRanks } from "./topo.js";
|
|
|
19
19
|
* phase=child-running. Scheduling/execution of the child is phase 3c and out
|
|
20
20
|
* of scope here.
|
|
21
21
|
*/
|
|
22
|
-
/** Canonical contract artifact default location; overridden by the
|
|
23
|
-
*
|
|
22
|
+
/** Canonical contract artifact default location; overridden by the design
|
|
23
|
+
* policy shell's configured outputDir/artifactName when present. */
|
|
24
24
|
const FRONTEND_CANONICAL_CONTRACT_DEFAULT_REL_PATH = "contracts/frontend-implementation-contract.json";
|
|
25
25
|
function resolveDeps(deps) {
|
|
26
26
|
return {
|
|
@@ -62,6 +62,9 @@ function isValidFrontendRecoveryMarker(raw) {
|
|
|
62
62
|
* Read + validate the activation marker. Missing or invalid markers return
|
|
63
63
|
* `undefined` so the phase-3c gate and tests can treat an unmarked active
|
|
64
64
|
* child as not executable (AC-2 / AC-5d).
|
|
65
|
+
*
|
|
66
|
+
* @deprecated Read-only/scheduler compatibility only; the runner no longer
|
|
67
|
+
* uses activation markers as the authoritative recovery entry point.
|
|
65
68
|
*/
|
|
66
69
|
export async function readFrontendRecoveryMarker(parentRunDir, requestId) {
|
|
67
70
|
let raw;
|
|
@@ -79,8 +82,8 @@ export async function readFrontendRecoveryMarker(parentRunDir, requestId) {
|
|
|
79
82
|
return raw;
|
|
80
83
|
}
|
|
81
84
|
function classifyFrontendFactKind(nodeId) {
|
|
82
|
-
if (/
|
|
83
|
-
return "
|
|
85
|
+
if (/admission|design-policy|verify|policy/i.test(nodeId))
|
|
86
|
+
return "gate";
|
|
84
87
|
if (/scout/i.test(nodeId))
|
|
85
88
|
return "scout";
|
|
86
89
|
if (/contract/i.test(nodeId))
|
|
@@ -91,9 +94,9 @@ function classifyFrontendFactKind(nodeId) {
|
|
|
91
94
|
}
|
|
92
95
|
function resolveCanonicalContractRelPath(spec) {
|
|
93
96
|
for (const task of spec.tasks) {
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
96
|
-
return path.posix.join(
|
|
97
|
+
const policy = task.shell?.frontendDesignPolicy;
|
|
98
|
+
if (policy) {
|
|
99
|
+
return path.posix.join(policy.outputDir, policy.artifactName);
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
return FRONTEND_CANONICAL_CONTRACT_DEFAULT_REL_PATH;
|
|
@@ -270,14 +273,63 @@ async function casUpdateFrontendRecoveryState(parentRunDir, expectedRevision, de
|
|
|
270
273
|
await deps.writeParentState(parentRunDir, state);
|
|
271
274
|
}
|
|
272
275
|
async function materializeChildStaging(input) {
|
|
273
|
-
const { cwd, parentRunDir, parentRunId, parentSpec, parentState, recovery, requestId, childRunId, stagingDir, createdAt, } = input;
|
|
276
|
+
const { cwd, parentRunDir, parentRunId, parentSpec, parentState, recovery, recoveryPlan, requestId, childRunId, stagingDir, createdAt, } = input;
|
|
274
277
|
await prepareRunDir(stagingDir);
|
|
275
|
-
|
|
278
|
+
// Design-review rejection must be visible to the reset planner. Recovery
|
|
279
|
+
// children otherwise copy the old spec and only rerun design review, which
|
|
280
|
+
// deterministically re-rejects the unchanged plan. Bind the parent's typed
|
|
281
|
+
// findings into the child spec as ordinary rerun feedback.
|
|
282
|
+
let childSpec = parentSpec;
|
|
283
|
+
if (recovery.failureSource === "frontend-plan-pi" ||
|
|
284
|
+
recovery.failureSource === "frontend-review-pi") {
|
|
285
|
+
const designRecovery = parentState.terminalReason === "design-request-changes";
|
|
286
|
+
const reviewRecovery = recovery.failureSource === "frontend-review-pi" ||
|
|
287
|
+
parentState.terminalReason === "review-request-changes";
|
|
288
|
+
let feedback;
|
|
289
|
+
try {
|
|
290
|
+
const { deriveDagRerunFeedback } = await import("./rerun-feedback.js");
|
|
291
|
+
const taskId = parentSpec.taskContractBinding?.taskId ??
|
|
292
|
+
parentSpec.sourceBinding?.taskId ??
|
|
293
|
+
parentRunId;
|
|
294
|
+
feedback = await deriveDagRerunFeedback({
|
|
295
|
+
parentRunId,
|
|
296
|
+
taskId,
|
|
297
|
+
runDir: parentRunDir,
|
|
298
|
+
spec: parentSpec,
|
|
299
|
+
state: parentState,
|
|
300
|
+
});
|
|
301
|
+
if (reviewRecovery &&
|
|
302
|
+
feedback &&
|
|
303
|
+
feedback.sourceNodeId !== "frontend-review-pi") {
|
|
304
|
+
// Do not accidentally carry an older design/verify finding when a
|
|
305
|
+
// review-triggered continuation has lost its typed review fact.
|
|
306
|
+
feedback = undefined;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
if (designRecovery || reviewRecovery) {
|
|
311
|
+
throw new Error(`frontend recovery feedback unavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (feedback) {
|
|
315
|
+
childSpec = { ...parentSpec, rerunFeedback: feedback };
|
|
316
|
+
}
|
|
317
|
+
else if (designRecovery || reviewRecovery) {
|
|
318
|
+
// A design/review rejection cannot be safely retried without its typed
|
|
319
|
+
// findings. Fail closed instead of deterministically re-running the
|
|
320
|
+
// unchanged plan and producing another rejection.
|
|
321
|
+
throw new Error(`frontend recovery feedback unavailable: no typed ${reviewRecovery ? "review" : "design"} findings were found for recovery`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
await writeJsonVerified(stagingDir, "run.json", childSpec);
|
|
276
325
|
// Phase 5: writer transient partial-write recovery resets the writer subtree
|
|
277
326
|
// (frontend-implement-pi) instead of the candidate producer; everything
|
|
278
327
|
// upstream is imported as verified parent facts.
|
|
279
328
|
let plan;
|
|
280
|
-
if (
|
|
329
|
+
if (recoveryPlan) {
|
|
330
|
+
plan = recoveryPlan;
|
|
331
|
+
}
|
|
332
|
+
else if (recovery.failureSource) {
|
|
281
333
|
plan = computeFrontendRecoveryPlanForSource({
|
|
282
334
|
spec: parentSpec,
|
|
283
335
|
parentRunId,
|
|
@@ -286,21 +338,21 @@ async function materializeChildStaging(input) {
|
|
|
286
338
|
});
|
|
287
339
|
}
|
|
288
340
|
else {
|
|
289
|
-
const
|
|
290
|
-
if (!
|
|
291
|
-
throw new Error(
|
|
341
|
+
const admissionRead = await readFrontendWriterAdmissionResult(parentRunDir);
|
|
342
|
+
if (!admissionRead.ok) {
|
|
343
|
+
throw new Error(admissionRead.reason);
|
|
292
344
|
}
|
|
293
345
|
plan = computeFrontendRecoveryPlan({
|
|
294
346
|
spec: parentSpec,
|
|
295
347
|
parentRunId,
|
|
296
348
|
requestId,
|
|
297
|
-
result:
|
|
349
|
+
result: admissionRead.result,
|
|
298
350
|
});
|
|
299
351
|
}
|
|
300
|
-
const { ranks } = topoSortToRanks(
|
|
352
|
+
const { ranks } = topoSortToRanks(childSpec);
|
|
301
353
|
const resetSet = new Set(plan.resetNodeIds);
|
|
302
354
|
const importedSet = new Set(plan.importedNodeIds);
|
|
303
|
-
const tasksById = new Map(
|
|
355
|
+
const tasksById = new Map(childSpec.tasks.map((task) => [task.id, task]));
|
|
304
356
|
const nodes = {};
|
|
305
357
|
const importedFacts = [];
|
|
306
358
|
for (const nodeId of plan.importedNodeIds) {
|
|
@@ -325,22 +377,22 @@ async function materializeChildStaging(input) {
|
|
|
325
377
|
}
|
|
326
378
|
nodes[nodeId] = buildPendingNodeRecord(task);
|
|
327
379
|
}
|
|
328
|
-
for (const task of
|
|
380
|
+
for (const task of childSpec.tasks) {
|
|
329
381
|
if (!resetSet.has(task.id) && !importedSet.has(task.id)) {
|
|
330
382
|
throw new Error(`node ${task.id} missing from frontend recovery plan partition`);
|
|
331
383
|
}
|
|
332
384
|
}
|
|
333
|
-
// Canonical contract +
|
|
385
|
+
// Canonical contract + writer-admission identity facts are copied alongside
|
|
334
386
|
// the per-node facts so reset nodes can re-read them (AC-4).
|
|
335
387
|
const canonicalContract = await copyArtifactVerified({
|
|
336
388
|
parentRunDir,
|
|
337
389
|
newRunDir: stagingDir,
|
|
338
|
-
relativePath: resolveCanonicalContractRelPath(
|
|
390
|
+
relativePath: resolveCanonicalContractRelPath(childSpec),
|
|
339
391
|
});
|
|
340
|
-
const
|
|
392
|
+
const writerAdmissionResult = await copyArtifactVerified({
|
|
341
393
|
parentRunDir,
|
|
342
394
|
newRunDir: stagingDir,
|
|
343
|
-
relativePath:
|
|
395
|
+
relativePath: FRONTEND_WRITER_ADMISSION_RESULT_ARTIFACT,
|
|
344
396
|
});
|
|
345
397
|
const childState = {
|
|
346
398
|
version: 1,
|
|
@@ -359,8 +411,11 @@ async function materializeChildStaging(input) {
|
|
|
359
411
|
parentRunId,
|
|
360
412
|
childRunId,
|
|
361
413
|
attemptId: recovery.attemptId,
|
|
362
|
-
attemptIndex: 1,
|
|
363
|
-
continuationCount: 1,
|
|
414
|
+
attemptIndex: recovery.attemptIndex + 1,
|
|
415
|
+
continuationCount: recovery.continuationCount + 1,
|
|
416
|
+
...(recovery.failureSource
|
|
417
|
+
? { failureSource: recovery.failureSource }
|
|
418
|
+
: {}),
|
|
364
419
|
revision: 0,
|
|
365
420
|
},
|
|
366
421
|
...(parentState.evaluation
|
|
@@ -377,9 +432,9 @@ async function materializeChildStaging(input) {
|
|
|
377
432
|
relativePath: canonicalContract.destinationRelativePath,
|
|
378
433
|
sha256: canonicalContract.sha256,
|
|
379
434
|
},
|
|
380
|
-
|
|
381
|
-
relativePath:
|
|
382
|
-
sha256:
|
|
435
|
+
writerAdmissionResult: {
|
|
436
|
+
relativePath: writerAdmissionResult.destinationRelativePath,
|
|
437
|
+
sha256: writerAdmissionResult.sha256,
|
|
383
438
|
},
|
|
384
439
|
importedFacts,
|
|
385
440
|
};
|
|
@@ -417,6 +472,9 @@ async function verifyThreeWayConsistency(input) {
|
|
|
417
472
|
* intent. Single-writer: the recovery coordinator is the only caller.
|
|
418
473
|
* Fail-closed on revision drift, missing intent, unreadable prewrite result,
|
|
419
474
|
* hash mismatch, marker-write failure, or consistency failure.
|
|
475
|
+
*
|
|
476
|
+
* @deprecated The M6 operation controller is the authoritative recovery loop;
|
|
477
|
+
* this kernel is retained only for read-only/scheduler compatibility.
|
|
420
478
|
*/
|
|
421
479
|
export async function stageRecoveryChild(options) {
|
|
422
480
|
const { cwd, parentRunId } = options;
|
|
@@ -426,7 +484,41 @@ export async function stageRecoveryChild(options) {
|
|
|
426
484
|
const parentRunDir = getDagRunDir(cwd, "active", parentRunId);
|
|
427
485
|
const parentState = await deps.readParentState(parentRunDir);
|
|
428
486
|
const parentSpec = await readDagRunSpec(parentRunDir);
|
|
429
|
-
|
|
487
|
+
let recovery = parentState.frontendRecoveryState;
|
|
488
|
+
if (options.recoveryIntent) {
|
|
489
|
+
const intent = options.recoveryIntent;
|
|
490
|
+
if (intent.parentRunId !== parentRunId ||
|
|
491
|
+
intent.requestId.length === 0 ||
|
|
492
|
+
intent.phase !== "child-staging" ||
|
|
493
|
+
intent.childRunId !== undefined ||
|
|
494
|
+
intent.revision !== 0) {
|
|
495
|
+
throw new Error("frontend recovery intent binding mismatch");
|
|
496
|
+
}
|
|
497
|
+
if (recovery?.requestId === intent.requestId) {
|
|
498
|
+
if (recovery.parentRunId !== intent.parentRunId ||
|
|
499
|
+
recovery.recoveryRootRunId !== intent.recoveryRootRunId ||
|
|
500
|
+
recovery.attemptIndex !== intent.attemptIndex ||
|
|
501
|
+
recovery.continuationCount !== intent.continuationCount ||
|
|
502
|
+
recovery.failureSource !== intent.failureSource) {
|
|
503
|
+
throw new Error("frontend recovery intent replay binding mismatch");
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
const previousAttemptIndex = recovery?.attemptIndex ?? 0;
|
|
508
|
+
const previousContinuationCount = recovery?.continuationCount ?? 0;
|
|
509
|
+
const expectedRoot = recovery?.recoveryRootRunId ?? parentRunId;
|
|
510
|
+
if (intent.recoveryRootRunId !== expectedRoot ||
|
|
511
|
+
intent.attemptIndex !== previousAttemptIndex ||
|
|
512
|
+
intent.continuationCount !== previousContinuationCount) {
|
|
513
|
+
throw new Error("frontend recovery intent lineage mismatch");
|
|
514
|
+
}
|
|
515
|
+
recovery = structuredClone(intent);
|
|
516
|
+
await deps.writeParentState(parentRunDir, {
|
|
517
|
+
...parentState,
|
|
518
|
+
frontendRecoveryState: recovery,
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
}
|
|
430
522
|
if (!recovery) {
|
|
431
523
|
throw new Error(`parent run ${parentRunId} has no frontend recovery intent`);
|
|
432
524
|
}
|
|
@@ -434,17 +526,49 @@ export async function stageRecoveryChild(options) {
|
|
|
434
526
|
if (!requestId) {
|
|
435
527
|
throw new Error(`parent run ${parentRunId} recovery intent has no requestId`);
|
|
436
528
|
}
|
|
529
|
+
if (options.recoveryPlan) {
|
|
530
|
+
if (options.recoveryPlan.parentRunId !== parentRunId ||
|
|
531
|
+
options.recoveryPlan.requestId !== requestId ||
|
|
532
|
+
options.recoveryPlan.failureSource !== recovery.failureSource) {
|
|
533
|
+
throw new Error("frontend recovery plan binding mismatch");
|
|
534
|
+
}
|
|
535
|
+
const expectedPlan = computeFrontendRecoveryPlanForSource({
|
|
536
|
+
spec: parentSpec,
|
|
537
|
+
parentRunId,
|
|
538
|
+
requestId,
|
|
539
|
+
failureSource: recovery.failureSource,
|
|
540
|
+
});
|
|
541
|
+
if (JSON.stringify(expectedPlan.resetNodeIds) !==
|
|
542
|
+
JSON.stringify(options.recoveryPlan.resetNodeIds) ||
|
|
543
|
+
JSON.stringify(expectedPlan.importedNodeIds) !==
|
|
544
|
+
JSON.stringify(options.recoveryPlan.importedNodeIds)) {
|
|
545
|
+
throw new Error("frontend recovery plan drifted from parent DAG");
|
|
546
|
+
}
|
|
547
|
+
}
|
|
437
548
|
// Idempotent short-circuit (D4.2): reserved childRunId + activated marker +
|
|
438
549
|
// existing child dir means the request was already fully committed.
|
|
439
550
|
if (recovery.childRunId) {
|
|
440
551
|
const existingMarker = await readFrontendRecoveryMarker(parentRunDir, requestId);
|
|
441
552
|
if (existingMarker) {
|
|
442
|
-
const
|
|
443
|
-
if (
|
|
553
|
+
const existingChild = await locateDagRun(cwd, existingMarker.childRunId);
|
|
554
|
+
if (existingChild &&
|
|
555
|
+
(existingChild.lifecycle === "active" ||
|
|
556
|
+
existingChild.lifecycle === "paused" ||
|
|
557
|
+
existingChild.lifecycle === "completed")) {
|
|
558
|
+
await verifyThreeWayConsistency({
|
|
559
|
+
parentRunDir,
|
|
560
|
+
activeChildDir: existingChild.runDir,
|
|
561
|
+
marker: existingMarker,
|
|
562
|
+
parentRunId,
|
|
563
|
+
requestId,
|
|
564
|
+
recoveryRootRunId: recovery.recoveryRootRunId,
|
|
565
|
+
childRunId: existingMarker.childRunId,
|
|
566
|
+
deps,
|
|
567
|
+
});
|
|
444
568
|
return {
|
|
445
569
|
ok: true,
|
|
446
570
|
childRunId: existingMarker.childRunId,
|
|
447
|
-
childRunDir:
|
|
571
|
+
childRunDir: existingChild.runDir,
|
|
448
572
|
marker: existingMarker,
|
|
449
573
|
idempotentReplay: true,
|
|
450
574
|
};
|
|
@@ -452,8 +576,15 @@ export async function stageRecoveryChild(options) {
|
|
|
452
576
|
}
|
|
453
577
|
}
|
|
454
578
|
// Derive the childRunId exactly once; replay always reuses a reserved id.
|
|
455
|
-
|
|
456
|
-
|
|
579
|
+
// buildDagRunId is deterministic for the same task title on the same day. A
|
|
580
|
+
// recovery child must never reuse its still-active parent directory, or the
|
|
581
|
+
// staging path aliases the parent and the required import manifest is absent.
|
|
582
|
+
const childRunId = recovery.childRunId ?? await (async () => {
|
|
583
|
+
const generatedChildRunId = await (options.buildChildRunId ?? buildDagRunId)(parentSpec, cwd);
|
|
584
|
+
return generatedChildRunId === parentRunId
|
|
585
|
+
? `${generatedChildRunId}-recovery-${requestId.slice(0, 8)}`
|
|
586
|
+
: generatedChildRunId;
|
|
587
|
+
})();
|
|
457
588
|
// Orphan staging cleanup (D4.3): remove any in-flight staging dir for this id.
|
|
458
589
|
const activeRootDir = getDagRunDir(cwd, "active", "");
|
|
459
590
|
const stagingDir = path.join(activeRootDir, `${FRONTEND_RECOVERY_STAGING_PREFIX}${childRunId}`);
|
|
@@ -487,6 +618,7 @@ export async function stageRecoveryChild(options) {
|
|
|
487
618
|
parentSpec,
|
|
488
619
|
parentState,
|
|
489
620
|
recovery,
|
|
621
|
+
recoveryPlan: options.recoveryPlan,
|
|
490
622
|
requestId,
|
|
491
623
|
childRunId,
|
|
492
624
|
stagingDir,
|