@tea-agent/loop-agent 0.41.1-beta.0 → 0.41.2
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/CHANGELOG.md +61 -267
- package/dist/application/dag/generate-task-dag.js +19 -75
- package/dist/application/task-lifecycle/advance.js +5 -24
- package/dist/application/task-lifecycle/observe.js +17 -171
- package/dist/application/task-lifecycle/plan-transitions.js +7 -42
- package/dist/application/task-lifecycle/recommendations.js +2 -13
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +0 -7
- package/dist/cli/program.js +0 -5
- package/dist/commands/client-recovery.js +0 -3
- package/dist/commands/init.js +1 -27
- package/dist/commands/task-advance.js +0 -19
- package/dist/executors/dag-pi-executor.js +231 -3784
- package/dist/executors/pi-executor.js +4 -15
- package/dist/executors/pi-extension-resolver.js +14 -2
- package/dist/executors/shell-executor.js +217 -945
- package/dist/executors/shell-write-guard.js +0 -7
- package/dist/shared/dag-failure-category.js +0 -12
- package/dist/shared/openspec-spec.js +4 -70
- package/dist/shared/operator/capabilities.js +0 -7
- package/dist/task/config-types.js +7 -34
- package/dist/task/contract/adopt.js +0 -4
- package/dist/task/contract/import-revision.js +0 -4
- package/dist/task/contract/project.js +0 -3
- package/dist/task/contract/schema.js +1 -2
- package/dist/task/frontend-project-capability.js +20 -203
- package/dist/task/runtime.js +2 -5
- package/dist/task/source-prepare/build-draft.js +3 -3
- package/dist/task/source-prepare/fragment-inventory.js +9 -15
- package/dist/task/source-prepare/prepare.js +1 -89
- package/dist/task/source-prepare/semantic-intake.js +2 -6
- package/dist/task/source-references.js +1 -22
- package/dist/worker/console/chat/chat-ui-policy.js +4 -2
- package/dist/worker/console/chat/pi-runtime.js +235 -13
- package/dist/worker/console/chat/repo-browser.js +10 -3
- package/dist/worker/console/chat/routes.js +86 -44
- package/dist/worker/console/chat/semantic-activity.js +12 -11
- package/dist/worker/console/chat/session-stats.js +96 -0
- package/dist/worker/console/chat/session-store.js +133 -70
- package/dist/worker/console/chat/shortcuts.js +1 -1
- package/dist/worker/console/chat/turn-process.js +139 -60
- package/dist/worker/console/index.js +0 -3
- package/dist/worker/console/operation-store.js +6 -226
- package/dist/worker/console/operator-actions.js +7 -169
- package/dist/worker/console/pi-plugins.js +3 -1
- package/dist/worker/console/server.js +19 -4
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-Bho4we4c.js → abnfDiagram-N423BO3Z-DQ5jlYVU.js} +1 -1
- package/dist/worker/console/static/assets/{arc-TBDkTeK0.js → arc-BeTVCzH9.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-BF_fZrn2.js → architectureDiagram-T3A2C74G-DassREBi.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-CCnPgUe2.js → blockDiagram-VBNYF7ZC-DyeNX8Ek.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-BCYZJLAT.js → c4Diagram-5PPSVZJV-BXb_zxGx.js} +1 -1
- package/dist/worker/console/static/assets/channel-B_lofstT.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-D8K6adhU.js → chunk-2GRJ4B5K-B9F9gxGC.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-DkT1Q78b.js → chunk-2Q5K7J3B-Byd5zHEQ.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-DuhvpIr7.js → chunk-5RXB4S5H-BqoxMJk9.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BnK6dC49.js → chunk-5VM5RSS4-CT7d6YZw.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DPz__z7r.js → chunk-6Q2QTUOP-CdiNyN0N.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-0kkppM2j.js → chunk-GF5L2VYU-BGw9bpVc.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BB41iK5t.js → chunk-JWPE2WC7-DiDVlVB1.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CiVrxKHU.js → chunk-KBJHAD2P-BhHf-4yK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-C2h9Xje1.js → chunk-RYQCIY6F-B79pEgwv.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-3iOSHdbM.js → chunk-XXDRQBXY-Cb70EcUV.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-ieUI0-eY.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-ieUI0-eY.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BN3A7tkk.js → cose-bilkent-JH36ORCC-DBHLnAf1.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-CTuBy0Or.js → cynefin-VYW2F7L2-BT_JRsOH.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-wb6tUlMN.js → cynefinDiagram-MW4NZA55-Bss-msa3.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-GP1Ivx8B.js → dagre-VZM6K2ZE-B8Gr24pt.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-ejrcK6L0.js → diagram-7IWD3JNH-BrjU70Jw.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-YFkCCvUU.js → diagram-B4RE2ZJO-Cp_JpPGd.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-B4rrvIaL.js → diagram-LBJQPF4R-BWKICEP-.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-C-YIZcUf.js → diagram-Q27KOJAE-D3z_UNR_.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-BPF5wcL1.js → diagram-UB23O5K3-_Ywm390x.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-CU5SzXjO.js → ebnfDiagram-BXEA7PRR-D9QYQQMB.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-CpL414DE.js → erDiagram-JOGREHBK-BNgXNKAr.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-MrhLzNau.js → flowDiagram-UKHOOZJN-QRLnkPCg.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-Bg4qFuUo.js → ganttDiagram-PKOTCBZU-B9fOduNi.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-ColxSXLR.js → gitGraphDiagram-DS77QQ5N-FSEdtPN2.js} +1 -1
- package/dist/worker/console/static/assets/index-Cs9JUSPs.css +1 -0
- package/dist/worker/console/static/assets/index-DtPrwu7M.js +451 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-Czvtm6gc.js → infoDiagram-6WML65LV-D5Bjg9dm.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-B7Xp8HyJ.js → ishikawaDiagram-WSZJBQD7-BlNRkWvf.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DWYZcvph.js → journeyDiagram-NVQOT4AX-BdJiw3SL.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-KTLZRUjx.js → kanban-definition-27J2QSJJ-CsDNlYht.js} +1 -1
- package/dist/worker/console/static/assets/{linear-_Exn7bfl.js → linear-8g9dbEmX.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-Cxg8kX8V.js → mermaid.core-ChyQH_ut.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-oKrlo2Bt.js → mindmap-definition-FAOFIHXS-DwYoCTYt.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-XAeteiNd.js → pegDiagram-VL7TDLO6-T_b2rS17.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-BTf1K-lp.js → pieDiagram-7S7Q4E2Y-1Cr7WMhH.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-C0IlY0Jf.js → quadrantDiagram-CIZ2JOQS-Bq4qM59o.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-BVbKtZhW.js → railroadDiagram-AXF67PYL-ytFgR1RL.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-C5e4JFcr.js → requirementDiagram-LRYGKXZP-CnUdUVYX.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cz30hc29.js → sankeyDiagram-W5VNT64P-_5rJqG6R.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-DS33n6d0.js → sequenceDiagram-SI44F4Z6-D5imyGbt.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-46w7v-9T.js → sizeCapture-X5ZJPWSS-DvgDn3wL.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-pbcD5SsZ.js → stateDiagram-OKZ733FA-BViu7duc.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-kNxnG4_w.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-DuivYBSj.js → swimlanes-SLNWSIFB-BcULKg2P.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-DyTzlcWH.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Cb9VZVIl.js → timeline-definition-Z64GVDOM-DmPveIjt.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-D2-mfOgR.js → vennDiagram-T6HMQDX7-9r-iFy0R.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-DeS2aC76.js → wardleyDiagram-T6FBY63Y-D3fIXdvM.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-WGsrFjxH.js → xychartDiagram-ELKLHX3M-BCSS9SBg.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/useRunProgress.js +9 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +19 -8
- package/dist/worker/console/static-src/operator-chat/dag-progress-link.js +22 -0
- package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +15 -7
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +2 -0
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +6 -0
- package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +28 -3
- package/dist/worker/console/static-src/pages/tasks/run-panel-progress.js +106 -0
- package/dist/worker/console/static-src/shell/workspace-route.js +4 -0
- package/dist/worker/console/workspace-context.js +1 -111
- package/dist/worker/observability/read-model.js +4 -0
- package/dist/worker/observe/routes.js +4 -0
- package/dist/worker/observe/static/dag-node-purpose.js +0 -5
- package/dist/worker/observe/static/views/dag-inspector.js +2 -7
- package/dist/worker/observe/static/views/session-timeline.js +46 -15
- package/dist/workflows/dag/backend-test-result-contract.js +1 -1
- package/dist/workflows/dag/contract-validator-registrations.js +2 -1
- package/dist/workflows/dag/frontend-implementation-contract.js +162 -932
- package/dist/workflows/dag/frontend-plan-render.js +1 -2
- package/dist/workflows/dag/frontend-prewrite-gate.js +349 -255
- package/dist/workflows/dag/frontend-recovery-plan.js +10 -17
- package/dist/workflows/dag/frontend-recovery-run.js +20 -33
- package/dist/workflows/dag/frontend-repair.js +432 -1
- package/dist/workflows/dag/frontend-review-context.js +15 -261
- package/dist/workflows/dag/frontend-verification-trace.js +24 -249
- package/dist/workflows/dag/frontend-worktree-diff.js +17 -250
- package/dist/workflows/dag/init-hybrid.js +494 -685
- package/dist/workflows/dag/interrupt-request.js +0 -7
- package/dist/workflows/dag/node-execution.js +4 -732
- package/dist/workflows/dag/prompt.js +1 -34
- package/dist/workflows/dag/report.js +1 -37
- package/dist/workflows/dag/rerun-feedback.js +1 -256
- package/dist/workflows/dag/rerun-plan.js +2 -10
- package/dist/workflows/dag/rerun-run.js +0 -23
- package/dist/workflows/dag/rerun-task.js +0 -29
- package/dist/workflows/dag/retry-policy.js +104 -214
- package/dist/workflows/dag/runner.js +122 -429
- package/dist/workflows/dag/scheduler.js +16 -114
- package/dist/workflows/dag/types.js +12 -239
- package/dist/workflows/dag/validate.js +12 -28
- package/docs/init-surface.manifest.json +12 -30
- package/docs/skills/vetted-skill-registry.md +2 -4
- package/docs/templates/README.md +0 -2
- package/docs/templates/agent-dag-report.schema.json +2 -8
- package/docs/templates/agent-dag.schema.json +1 -1
- package/docs/templates/frontend-implementation-contract.schema.json +1 -4
- package/harness.json +3 -3
- package/package.json +1 -1
- package/skills/frontend-bounded-implement/SKILL.md +14 -15
- package/skills/frontend-design-review/SKILL.md +41 -22
- package/skills/frontend-implementation/SKILL.md +52 -0
- package/skills/frontend-implementation/references/code-standards.md +33 -0
- package/skills/frontend-implementation/references/design-spec.md +56 -0
- package/skills/frontend-implementation/references/node-contracts.md +31 -0
- package/skills/frontend-review/SKILL.md +15 -20
- package/skills/frontend-review/references/review-findings.md +7 -6
- package/skills/frontend-verification/SKILL.md +1 -1
- package/skills/loop-agent/references/command-reference.md +0 -1
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/dist/commands/dag-follow-up.js +0 -138
- package/dist/executors/pi-read-budget-policy.js +0 -239
- package/dist/worker/console/frontend-human-decision-adapter.js +0 -19
- package/dist/worker/console/frontend-split-operation-adapter.js +0 -20
- package/dist/worker/console/static/assets/channel-bnXW0U3C.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-rZpq_twR.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-rZpq_twR.js +0 -1
- package/dist/worker/console/static/assets/index-D3CC4eUz.css +0 -1
- package/dist/worker/console/static/assets/index-DLt4ZFvD.js +0 -437
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-zBMYiUyi.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-d_rms-5i.js +0 -8
- package/dist/worker/console/static-src/active-run-badge.js +0 -17
- package/dist/worker/materialize/frontend-split-task-materializer.js +0 -72
- package/dist/workflows/dag/dag-retry-schema.js +0 -138
- package/dist/workflows/dag/frontend-closeout.js +0 -221
- package/dist/workflows/dag/frontend-design-policy.js +0 -400
- package/dist/workflows/dag/frontend-human-decision.js +0 -182
- package/dist/workflows/dag/frontend-provider-capability-matrix.js +0 -159
- package/dist/workflows/dag/frontend-read-budgets.js +0 -12
- package/dist/workflows/dag/frontend-recovery-capsule.js +0 -455
- package/dist/workflows/dag/frontend-recovery-controller.js +0 -202
- package/dist/workflows/dag/frontend-recovery-lineage.js +0 -178
- package/dist/workflows/dag/frontend-review-findings.js +0 -270
- package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -914
- package/dist/workflows/dag/frontend-shape-capsule-store.js +0 -191
- package/dist/workflows/dag/frontend-shape-facts.js +0 -409
- package/dist/workflows/dag/frontend-shape.js +0 -427
- package/dist/workflows/dag/frontend-source-fidelity-ledger.js +0 -108
- package/dist/workflows/dag/frontend-split-application-service.js +0 -203
- package/dist/workflows/dag/frontend-split-orchestrator.js +0 -899
- package/dist/workflows/dag/frontend-typed-event-store.js +0 -452
- package/dist/workflows/dag/frontend-typed-event-transaction.js +0 -180
- package/dist/workflows/dag/frontend-writer-admission.js +0 -285
- package/dist/workflows/dag/frontend-writer-status.js +0 -256
- package/dist/workflows/dag/recovery-lease.js +0 -80
- package/docs/templates/frontend-implementation-dag.json +0 -89
- package/docs/templates/spec-registry.schema.json +0 -45
- package/skills/frontend-bounded-implement/references/code-standards.md +0 -19
- package/skills/frontend-contract/SKILL.md +0 -23
- package/skills/frontend-contract/references/contract-protocol.md +0 -34
- package/skills/frontend-plan/SKILL.md +0 -26
- package/skills/frontend-plan/references/decision-contract.md +0 -37
- package/skills/frontend-plan/references/design-decisions.md +0 -17
- package/skills/frontend-scout/SKILL.md +0 -25
- package/skills/frontend-scout/references/design-evidence.md +0 -16
- package/skills/frontend-scout/references/scout-evidence.md +0 -23
|
@@ -45,42 +45,9 @@ function formatResolvedSkillInstructions(instructions) {
|
|
|
45
45
|
if (!instructions || instructions.length === 0)
|
|
46
46
|
return "(none)";
|
|
47
47
|
return instructions
|
|
48
|
-
.map((instruction) =>
|
|
48
|
+
.map((instruction) => instruction.promptText)
|
|
49
49
|
.join("\n\n---\n\n");
|
|
50
50
|
}
|
|
51
|
-
/** Keep skill provenance, but turn bounded inline manuals into a small action list. */
|
|
52
|
-
function formatSkillChecklist(instruction) {
|
|
53
|
-
const metadata = [
|
|
54
|
-
`Skill: ${instruction.name}`,
|
|
55
|
-
`Resolution: ${instruction.resolution}`,
|
|
56
|
-
...(instruction.path ? [`Path: ${instruction.path}`] : []),
|
|
57
|
-
...(instruction.sha256 ? [`Sha256: ${instruction.sha256}`] : []),
|
|
58
|
-
"Injection mode: checklist",
|
|
59
|
-
];
|
|
60
|
-
if (instruction.resolution !== "resolved")
|
|
61
|
-
return [...metadata, instruction.promptText].join("\n");
|
|
62
|
-
const source = instruction.promptText.split("Instructions:\n")[1] ?? "";
|
|
63
|
-
const candidates = source
|
|
64
|
-
.split(/\r?\n/)
|
|
65
|
-
.map((line) => line.trim())
|
|
66
|
-
.filter((line) => /^(?:#{1,3}\s+|[-*]\s+|\d+[.)]\s+)/.test(line) || line.length > 0)
|
|
67
|
-
.map((line) => line.replace(/^#{1,3}\s+/, "").replace(/^[-*]\s+/, "").replace(/^\d+[.)]\s+/, ""))
|
|
68
|
-
.filter((line) => line.length > 0);
|
|
69
|
-
const checklist = [];
|
|
70
|
-
let chars = 0;
|
|
71
|
-
for (const item of candidates) {
|
|
72
|
-
const bounded = item.slice(0, 240);
|
|
73
|
-
if (checklist.length >= 10 || chars + bounded.length > 1_600)
|
|
74
|
-
break;
|
|
75
|
-
checklist.push(`- ${bounded}`);
|
|
76
|
-
chars += bounded.length;
|
|
77
|
-
}
|
|
78
|
-
return [
|
|
79
|
-
...metadata,
|
|
80
|
-
"Checklist (apply these actions; consult the immutable resolved file only when a listed action requires detail):",
|
|
81
|
-
...(checklist.length > 0 ? checklist : ["- Follow the resolved skill's declared workflow."]),
|
|
82
|
-
].join("\n");
|
|
83
|
-
}
|
|
84
51
|
export function formatOutputLanguageBlock(language = DEFAULT_DAG_OUTPUT_LANGUAGE) {
|
|
85
52
|
if (language === "en") {
|
|
86
53
|
return [
|
|
@@ -125,8 +125,6 @@ const dagNodeArtifactsReportSchema = z
|
|
|
125
125
|
humanEscalationMd: dagArtifactRefSchema,
|
|
126
126
|
humanApproval: dagArtifactRefSchema,
|
|
127
127
|
humanRejection: dagArtifactRefSchema,
|
|
128
|
-
changeManifest: dagArtifactRefSchema,
|
|
129
|
-
changeManifestChangedFiles: z.array(z.string()).optional(),
|
|
130
128
|
})
|
|
131
129
|
.strict();
|
|
132
130
|
const dagNodeReportRowSchema = z
|
|
@@ -261,20 +259,6 @@ export async function probeArtifact(filePath) {
|
|
|
261
259
|
export async function buildNodeArtifactsReport(runDir, nodeId) {
|
|
262
260
|
const nodeDir = path.join(runDir, nodeId);
|
|
263
261
|
const artifact = (name) => probeArtifact(path.join(nodeDir, name));
|
|
264
|
-
const changeManifestRef = await artifact("change-manifest.json");
|
|
265
|
-
let changeManifestChangedFiles;
|
|
266
|
-
if (changeManifestRef.exists) {
|
|
267
|
-
try {
|
|
268
|
-
const manifest = JSON.parse(await readFile(path.join(nodeDir, "change-manifest.json"), "utf-8"));
|
|
269
|
-
changeManifestChangedFiles = Array.isArray(manifest.changedFiles)
|
|
270
|
-
? manifest.changedFiles
|
|
271
|
-
.filter((item) => typeof item === "string")
|
|
272
|
-
: undefined;
|
|
273
|
-
}
|
|
274
|
-
catch {
|
|
275
|
-
// unreadable manifest → leave undefined
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
262
|
return {
|
|
279
263
|
resultSummary: await artifact("result.summary.md"),
|
|
280
264
|
promptRedacted: await artifact("prompt.redacted.md"),
|
|
@@ -286,8 +270,6 @@ export async function buildNodeArtifactsReport(runDir, nodeId) {
|
|
|
286
270
|
humanEscalationMd: await artifact("human-escalation.md"),
|
|
287
271
|
humanApproval: await artifact("human-approval.json"),
|
|
288
272
|
humanRejection: await artifact("human-rejection.json"),
|
|
289
|
-
changeManifest: changeManifestRef,
|
|
290
|
-
changeManifestChangedFiles,
|
|
291
273
|
};
|
|
292
274
|
}
|
|
293
275
|
function taskById(spec) {
|
|
@@ -744,12 +726,6 @@ function formatArtifactFlags(artifacts) {
|
|
|
744
726
|
flags.push("approval");
|
|
745
727
|
if (artifacts.humanRejection.exists)
|
|
746
728
|
flags.push("rejection");
|
|
747
|
-
if (artifacts.changeManifest.exists) {
|
|
748
|
-
const count = artifacts.changeManifestChangedFiles?.length;
|
|
749
|
-
flags.push(count !== undefined
|
|
750
|
-
? `changed:${count}`
|
|
751
|
-
: "change-manifest");
|
|
752
|
-
}
|
|
753
729
|
return flags.length > 0 ? flags.join(",") : "-";
|
|
754
730
|
}
|
|
755
731
|
function formatTimestamp(value) {
|
|
@@ -773,19 +749,7 @@ function summarizeNodeStatuses(nodes) {
|
|
|
773
749
|
return `${total} total / ${finished} finished / ${failed} failed / ${skipped} skipped / ${pending} pending`;
|
|
774
750
|
}
|
|
775
751
|
function hasArtifact(artifacts) {
|
|
776
|
-
return
|
|
777
|
-
artifacts.resultSummary,
|
|
778
|
-
artifacts.promptRedacted,
|
|
779
|
-
artifacts.skills,
|
|
780
|
-
artifacts.nodeRecord,
|
|
781
|
-
artifacts.decisionEnvelope,
|
|
782
|
-
artifacts.decisionEnvelopeValidation,
|
|
783
|
-
artifacts.humanEscalationJson,
|
|
784
|
-
artifacts.humanEscalationMd,
|
|
785
|
-
artifacts.humanApproval,
|
|
786
|
-
artifacts.humanRejection,
|
|
787
|
-
artifacts.changeManifest,
|
|
788
|
-
].some((artifact) => artifact.exists);
|
|
752
|
+
return Object.values(artifacts).some((artifact) => artifact.exists);
|
|
789
753
|
}
|
|
790
754
|
function failureRows(run) {
|
|
791
755
|
return run.nodes.filter((node) => node.status === "ERROR" ||
|
|
@@ -2,8 +2,6 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { parseJsonReviewVerdict } from "./output-protocol.js";
|
|
5
|
-
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
5
|
export const MAX_RERUN_FEEDBACK_CHARS = 12_000;
|
|
8
6
|
const RERUN_FEEDBACK_TRUNCATION_MARKER = "\n\n...[上一轮反馈已按长度上限截断]...\n\n";
|
|
9
7
|
const MAX_EVIDENCE_REFS = 8;
|
|
@@ -37,44 +35,6 @@ function requestRevision(text) {
|
|
|
37
35
|
return (emphasized?.[1] ?? trimmed).trim() === "VERDICT: request-revision";
|
|
38
36
|
});
|
|
39
37
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Deterministically render a typed `request_review_changes` fact into feedback
|
|
42
|
-
* text. Unlike the legacy text channel (VERDICT: request-revision), the
|
|
43
|
-
* frontend review terminal is a committed typed fact; the findings are the
|
|
44
|
-
* actionable body the next round must consume.
|
|
45
|
-
*/
|
|
46
|
-
export function formatTypedReviewRequestFeedback(fact) {
|
|
47
|
-
const lines = [];
|
|
48
|
-
lines.push(`frontend review committed request_review_changes (issueCategory=${typeof fact.issueCategory === "string" ? fact.issueCategory : "unknown"})`);
|
|
49
|
-
if (Array.isArray(fact.findings) && fact.findings.length > 0) {
|
|
50
|
-
lines.push("review findings:");
|
|
51
|
-
for (const finding of fact.findings) {
|
|
52
|
-
if (!finding || typeof finding !== "object")
|
|
53
|
-
continue;
|
|
54
|
-
const record = finding;
|
|
55
|
-
const severity = typeof record.severity === "string" ? record.severity : "";
|
|
56
|
-
const issue = typeof record.issue === "string" ? record.issue : "";
|
|
57
|
-
const location = [
|
|
58
|
-
typeof record.file === "string" ? record.file : "",
|
|
59
|
-
typeof record.line === "number" ? String(record.line) : "",
|
|
60
|
-
]
|
|
61
|
-
.filter(Boolean)
|
|
62
|
-
.join(":");
|
|
63
|
-
const prefix = location ? `[${location}] ` : "";
|
|
64
|
-
const requiredChange = typeof record.requiredChange === "string" &&
|
|
65
|
-
record.requiredChange.length > 0
|
|
66
|
-
? ` (requiredChange: ${record.requiredChange})`
|
|
67
|
-
: "";
|
|
68
|
-
lines.push(`- ${prefix}${severity}: ${issue}${requiredChange}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (Array.isArray(fact.evidenceRefs) && fact.evidenceRefs.length > 0) {
|
|
72
|
-
lines.push(`evidenceRefs: ${fact.evidenceRefs
|
|
73
|
-
.filter((ref) => typeof ref === "string")
|
|
74
|
-
.join(", ")}`);
|
|
75
|
-
}
|
|
76
|
-
return lines.join("\n");
|
|
77
|
-
}
|
|
78
38
|
function pathInside(root, candidate) {
|
|
79
39
|
const relative = path.relative(root, candidate);
|
|
80
40
|
return (relative === "" ||
|
|
@@ -167,162 +127,6 @@ function evidenceRefs(repoRoot, runDir, pass, sourceNodeId) {
|
|
|
167
127
|
}
|
|
168
128
|
return result;
|
|
169
129
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Read the committed frontend review request fact (typed terminal channel).
|
|
172
|
-
* Returns { nodeId, fact } when the review node committed `request_review_changes`.
|
|
173
|
-
*/
|
|
174
|
-
async function readTypedReviewRequestFact(runDir) {
|
|
175
|
-
const fact = await readCommittedReviewRequestFact({ runDir });
|
|
176
|
-
if (!fact)
|
|
177
|
-
return undefined;
|
|
178
|
-
return {
|
|
179
|
-
nodeId: FRONTEND_REVIEW_NODE_ID,
|
|
180
|
-
fact: {
|
|
181
|
-
issueCategory: fact.issueCategory,
|
|
182
|
-
evidenceRefs: fact.evidenceRefs,
|
|
183
|
-
findings: fact.findings,
|
|
184
|
-
},
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Read the committed frontend design request fact (typed terminal channel).
|
|
189
|
-
* Returns { nodeId, fact } when the design review node committed
|
|
190
|
-
* `request_design_changes` — the design analog of request_review_changes.
|
|
191
|
-
*/
|
|
192
|
-
async function readTypedDesignRequestFact(runDir) {
|
|
193
|
-
const fact = await readCommittedDesignRequestFact({ runDir });
|
|
194
|
-
if (!fact)
|
|
195
|
-
return undefined;
|
|
196
|
-
return {
|
|
197
|
-
nodeId: FRONTEND_DESIGN_REVIEW_NODE_ID,
|
|
198
|
-
fact: {
|
|
199
|
-
issueCategory: fact.issueCategory,
|
|
200
|
-
evidenceRefs: fact.evidenceRefs,
|
|
201
|
-
findings: fact.findings,
|
|
202
|
-
},
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
const RERUN_FEEDBACK_LINEAGE_MAX_DEPTH = 5;
|
|
206
|
-
const RERUN_FEEDBACK_LINEAGE_LIFECYCLES = [
|
|
207
|
-
"active",
|
|
208
|
-
"paused",
|
|
209
|
-
"completed",
|
|
210
|
-
];
|
|
211
|
-
function safeLineageRunId(value) {
|
|
212
|
-
if (typeof value !== "string" || !value || value !== value.trim())
|
|
213
|
-
return undefined;
|
|
214
|
-
if (value === "." ||
|
|
215
|
-
value === ".." ||
|
|
216
|
-
value.includes("/") ||
|
|
217
|
-
value.includes("\\") ||
|
|
218
|
-
value.includes("\0"))
|
|
219
|
-
return undefined;
|
|
220
|
-
return value;
|
|
221
|
-
}
|
|
222
|
-
async function readCommittedTerminalKind(input) {
|
|
223
|
-
try {
|
|
224
|
-
const records = await readTypedEventStoreFromJsonl(path.join(input.runDir, input.nodeId, input.factsFile));
|
|
225
|
-
for (const record of records) {
|
|
226
|
-
if (record.phase !== "committed")
|
|
227
|
-
continue;
|
|
228
|
-
const kind = record.fact.kind;
|
|
229
|
-
if (typeof kind === "string" && input.kinds.includes(kind))
|
|
230
|
-
return kind;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
catch {
|
|
234
|
-
// A missing/unreadable terminal store means this run did not establish a
|
|
235
|
-
// usable resolution barrier; lineage lookup may continue.
|
|
236
|
-
}
|
|
237
|
-
return undefined;
|
|
238
|
-
}
|
|
239
|
-
async function readReviewTerminalKind(runDir) {
|
|
240
|
-
return readCommittedTerminalKind({
|
|
241
|
-
runDir,
|
|
242
|
-
nodeId: FRONTEND_REVIEW_NODE_ID,
|
|
243
|
-
factsFile: "review-typed-facts.jsonl",
|
|
244
|
-
kinds: ["request_review_changes", "approve_review"],
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
async function readDesignTerminalKind(runDir) {
|
|
248
|
-
return readCommittedTerminalKind({
|
|
249
|
-
runDir,
|
|
250
|
-
nodeId: FRONTEND_DESIGN_REVIEW_NODE_ID,
|
|
251
|
-
factsFile: "design-typed-facts.jsonl",
|
|
252
|
-
kinds: ["request_design_changes", "approve_design"],
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Walk the rerun-task lineage chain (`<runDir>/.runtime/rerun-task-lineage.json`
|
|
257
|
-
* → parentRunId) looking for the nearest ancestor run with a committed review
|
|
258
|
-
* or design request fact. A nearer final-review approval resolves all older
|
|
259
|
-
* findings; a nearer design approval resolves older design findings while
|
|
260
|
-
* still allowing an older final-review request to survive. Bounded depth;
|
|
261
|
-
* unsafe ids, mismatched state identities, cycles, and unreadable lineage
|
|
262
|
-
* files terminate the walk with undefined.
|
|
263
|
-
*/
|
|
264
|
-
async function readAncestorTypedRequestFact(runDir) {
|
|
265
|
-
let currentRunDir = runDir;
|
|
266
|
-
let currentRunId;
|
|
267
|
-
let designResolved = false;
|
|
268
|
-
const dagRunsRoot = path.resolve(runDir, "..", "..");
|
|
269
|
-
const visitedRunDirs = new Set([path.resolve(runDir)]);
|
|
270
|
-
for (let depth = 0; depth <= RERUN_FEEDBACK_LINEAGE_MAX_DEPTH; depth += 1) {
|
|
271
|
-
const reviewTerminalKind = await readReviewTerminalKind(currentRunDir);
|
|
272
|
-
if (currentRunId && reviewTerminalKind === "request_review_changes") {
|
|
273
|
-
const fact = await readTypedReviewRequestFact(currentRunDir);
|
|
274
|
-
if (fact)
|
|
275
|
-
return { ...fact, parentRunId: currentRunId };
|
|
276
|
-
}
|
|
277
|
-
if (reviewTerminalKind === "approve_review")
|
|
278
|
-
return undefined;
|
|
279
|
-
const designTerminalKind = await readDesignTerminalKind(currentRunDir);
|
|
280
|
-
if (currentRunId &&
|
|
281
|
-
!designResolved &&
|
|
282
|
-
designTerminalKind === "request_design_changes") {
|
|
283
|
-
const fact = await readTypedDesignRequestFact(currentRunDir);
|
|
284
|
-
if (fact)
|
|
285
|
-
return { ...fact, parentRunId: currentRunId };
|
|
286
|
-
}
|
|
287
|
-
if (designTerminalKind === "approve_design")
|
|
288
|
-
designResolved = true;
|
|
289
|
-
if (depth === RERUN_FEEDBACK_LINEAGE_MAX_DEPTH)
|
|
290
|
-
return undefined;
|
|
291
|
-
let parentRunId;
|
|
292
|
-
try {
|
|
293
|
-
const lineage = JSON.parse(await readFile(path.join(currentRunDir, ".runtime", "rerun-task-lineage.json"), "utf8"));
|
|
294
|
-
parentRunId = safeLineageRunId(lineage.parentRunId);
|
|
295
|
-
}
|
|
296
|
-
catch {
|
|
297
|
-
return undefined;
|
|
298
|
-
}
|
|
299
|
-
if (!parentRunId)
|
|
300
|
-
return undefined;
|
|
301
|
-
let ancestorRunDir;
|
|
302
|
-
for (const lifecycle of RERUN_FEEDBACK_LINEAGE_LIFECYCLES) {
|
|
303
|
-
const candidate = path.join(dagRunsRoot, lifecycle, parentRunId);
|
|
304
|
-
try {
|
|
305
|
-
const ancestorState = JSON.parse(await readFile(path.join(candidate, "state.json"), "utf8"));
|
|
306
|
-
if (ancestorState.runId === parentRunId) {
|
|
307
|
-
ancestorRunDir = candidate;
|
|
308
|
-
break;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
catch {
|
|
312
|
-
// try next lifecycle
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
if (!ancestorRunDir)
|
|
316
|
-
return undefined;
|
|
317
|
-
const resolvedAncestorRunDir = path.resolve(ancestorRunDir);
|
|
318
|
-
if (visitedRunDirs.has(resolvedAncestorRunDir))
|
|
319
|
-
return undefined;
|
|
320
|
-
visitedRunDirs.add(resolvedAncestorRunDir);
|
|
321
|
-
currentRunDir = ancestorRunDir;
|
|
322
|
-
currentRunId = parentRunId;
|
|
323
|
-
}
|
|
324
|
-
return undefined;
|
|
325
|
-
}
|
|
326
130
|
/**
|
|
327
131
|
* Derive only the latest unresolved verify/review feedback from canonical
|
|
328
132
|
* parent-run facts. Provider-only failures intentionally return undefined.
|
|
@@ -340,67 +144,8 @@ export async function deriveDagRerunFeedback(input) {
|
|
|
340
144
|
break;
|
|
341
145
|
}
|
|
342
146
|
}
|
|
343
|
-
if (!sourceNodeId || !sourceNode)
|
|
344
|
-
// Typed terminal channel: the frontend review/design review commit their
|
|
345
|
-
// verdicts as typed facts (request_review_changes / request_design_changes)
|
|
346
|
-
// instead of VERDICT text, and the frontend DAG has no convergence
|
|
347
|
-
// passHistory. Fall back to reading the typed event stores so findings
|
|
348
|
-
// still flow into the next round as unresolved feedback. Prefer review;
|
|
349
|
-
// if absent, fall through to the design review (a design rejection also
|
|
350
|
-
// carries actionable findings the next plan round must consume). When
|
|
351
|
-
// the direct parent has neither because it failed before review, walk the
|
|
352
|
-
// rerun-task lineage chain — chained
|
|
353
|
-
// reruns otherwise lose the grandparent's code-review findings and the
|
|
354
|
-
// reviewer re-flags them as "unresolved previous-round feedback" (r18).
|
|
355
|
-
// A committed approval is a resolution barrier and prevents older
|
|
356
|
-
// findings from being resurrected.
|
|
357
|
-
const typedFact = (await readTypedReviewRequestFact(input.runDir)) ??
|
|
358
|
-
(await readTypedDesignRequestFact(input.runDir)) ??
|
|
359
|
-
(await readAncestorTypedRequestFact(input.runDir));
|
|
360
|
-
if (typedFact) {
|
|
361
|
-
const parentSourceBindingHash = sourceBindingHash(input.spec);
|
|
362
|
-
return withDigest({
|
|
363
|
-
schemaVersion: 1,
|
|
364
|
-
kind: "unresolved-terminal-feedback",
|
|
365
|
-
parentRunId: "parentRunId" in typedFact &&
|
|
366
|
-
typeof typedFact.parentRunId === "string"
|
|
367
|
-
? typedFact.parentRunId
|
|
368
|
-
: input.parentRunId,
|
|
369
|
-
taskId: input.taskId,
|
|
370
|
-
sourceNodeId: typedFact.nodeId,
|
|
371
|
-
verdict: "request-revision",
|
|
372
|
-
failureCategory: typedFact.nodeId === FRONTEND_REVIEW_NODE_ID
|
|
373
|
-
? "review-request-changes"
|
|
374
|
-
: "design-request-changes",
|
|
375
|
-
feedbackText: scrubAndBoundFeedbackText(formatTypedReviewRequestFeedback(typedFact.fact), input.runDir, input.state.cwd),
|
|
376
|
-
evidenceRefs: [
|
|
377
|
-
{
|
|
378
|
-
nodeId: typedFact.nodeId,
|
|
379
|
-
preservedNodeRecordPath: `${typedFact.nodeId}.json`,
|
|
380
|
-
},
|
|
381
|
-
],
|
|
382
|
-
attemptSummary: {
|
|
383
|
-
completedPasses: 1,
|
|
384
|
-
maxPasses: 1,
|
|
385
|
-
...(input.state.terminalReason
|
|
386
|
-
? { terminalReason: input.state.terminalReason }
|
|
387
|
-
: {}),
|
|
388
|
-
},
|
|
389
|
-
binding: {
|
|
390
|
-
...(parentSourceBindingHash
|
|
391
|
-
? { sourceCanonicalHash: parentSourceBindingHash }
|
|
392
|
-
: {}),
|
|
393
|
-
...(input.spec.taskContractBinding?.canonicalHash
|
|
394
|
-
? {
|
|
395
|
-
taskContractCanonicalHash: input.spec.taskContractBinding.canonicalHash,
|
|
396
|
-
}
|
|
397
|
-
: {}),
|
|
398
|
-
status: "unknown",
|
|
399
|
-
},
|
|
400
|
-
});
|
|
401
|
-
}
|
|
147
|
+
if (!sourceNodeId || !sourceNode)
|
|
402
148
|
return undefined;
|
|
403
|
-
}
|
|
404
149
|
const completedPasses = pass?.pass ?? Math.max(1, input.state.convergence?.currentPass ?? 1);
|
|
405
150
|
const maxPasses = Math.max(completedPasses, input.state.convergence?.maxPasses ?? 1);
|
|
406
151
|
const parentSourceBindingHash = sourceBindingHash(input.spec);
|
|
@@ -160,16 +160,12 @@ function isCanonicalGeneratedVerifyShell(task) {
|
|
|
160
160
|
return false;
|
|
161
161
|
if (shell.projectGovernanceGate)
|
|
162
162
|
return false;
|
|
163
|
-
if (shell.
|
|
164
|
-
return false;
|
|
165
|
-
if (shell.frontendWriterAdmission)
|
|
163
|
+
if (shell.frontendPrewriteGate)
|
|
166
164
|
return false;
|
|
167
165
|
if (shell.frontendVerificationBundle)
|
|
168
166
|
return false;
|
|
169
167
|
if (shell.frontendReviewContext)
|
|
170
168
|
return false;
|
|
171
|
-
if (shell.frontendCloseout)
|
|
172
|
-
return false;
|
|
173
169
|
if (shell.backendTestPipeline)
|
|
174
170
|
return false;
|
|
175
171
|
if (shell.nonZeroExitPolicy === "record")
|
|
@@ -195,16 +191,12 @@ function isSafeGateOnlyShell(task) {
|
|
|
195
191
|
return false;
|
|
196
192
|
if (shell.preset)
|
|
197
193
|
return false;
|
|
198
|
-
if (shell.
|
|
199
|
-
return false;
|
|
200
|
-
if (shell.frontendWriterAdmission)
|
|
194
|
+
if (shell.frontendPrewriteGate)
|
|
201
195
|
return false;
|
|
202
196
|
if (shell.frontendVerificationBundle)
|
|
203
197
|
return false;
|
|
204
198
|
if (shell.frontendReviewContext)
|
|
205
199
|
return false;
|
|
206
|
-
if (shell.frontendCloseout)
|
|
207
|
-
return false;
|
|
208
200
|
if (shell.backendTestPipeline)
|
|
209
201
|
return false;
|
|
210
202
|
if (shell.verifyEvidence)
|
|
@@ -12,7 +12,6 @@ import { prepareActiveRunDir, writeNodeRecord, writeRunSpec, writeRunState, } fr
|
|
|
12
12
|
import { cloneParentSkillSnapshotForContinuation, readSkillSnapshot, } from "./skill-snapshot.js";
|
|
13
13
|
import { topoSortToRanks } from "./topo.js";
|
|
14
14
|
import { captureWorkspaceCheckpoint, readWorkspaceCheckpoint, WORKSPACE_CHECKPOINT_START_REL, WORKSPACE_CHECKPOINT_TERMINAL_REL, writeWorkspaceCheckpoint, } from "./workspace-checkpoint.js";
|
|
15
|
-
import { acquireDagRecoveryLease, bindDagRecoveryLeaseExecution, } from "./recovery-lease.js";
|
|
16
15
|
export const RERUN_PLAN_REL_PATH = ".runtime/rerun-plan.json";
|
|
17
16
|
export const IMPORT_MANIFEST_REL_PATH = ".runtime/import-manifest.json";
|
|
18
17
|
export const WORKER_ASSOCIATION_REL_PATH = ".runtime/worker-association.json";
|
|
@@ -573,20 +572,6 @@ export async function executeDagRerun(input) {
|
|
|
573
572
|
}
|
|
574
573
|
const parentSpec = await readDagRunSpec(located.runDir);
|
|
575
574
|
const parentState = await readDagRunState(located.runDir);
|
|
576
|
-
const recoveryLease = await acquireDagRecoveryLease({
|
|
577
|
-
cwd: input.cwd,
|
|
578
|
-
parentRunId: input.parentRunId,
|
|
579
|
-
requestId: input.requestId,
|
|
580
|
-
kind: "rerun-from-node",
|
|
581
|
-
});
|
|
582
|
-
if (recoveryLease.kind === "held") {
|
|
583
|
-
return {
|
|
584
|
-
ok: false,
|
|
585
|
-
plan,
|
|
586
|
-
errorCode: "RECOVERY_LEASE_HELD",
|
|
587
|
-
message: `parent run recovery is already claimed by ${recoveryLease.lease.kind} request ${recoveryLease.lease.requestId}`,
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
575
|
const staged = await stageContinuationRun({
|
|
591
576
|
cwd: input.cwd,
|
|
592
577
|
parentRunDir: located.runDir,
|
|
@@ -598,14 +583,6 @@ export async function executeDagRerun(input) {
|
|
|
598
583
|
requestId: input.requestId,
|
|
599
584
|
promptOverrides: input.promptOverrides,
|
|
600
585
|
});
|
|
601
|
-
// Stage is non-executing; bind the child identity immediately before handing
|
|
602
|
-
// it to the runner so no recovery DAG can start without durable parent
|
|
603
|
-
// lineage ownership.
|
|
604
|
-
await bindDagRecoveryLeaseExecution({
|
|
605
|
-
leasePath: recoveryLease.leasePath,
|
|
606
|
-
lease: recoveryLease.lease,
|
|
607
|
-
executionRef: staged.state.runId,
|
|
608
|
-
});
|
|
609
586
|
const continuationOptions = {
|
|
610
587
|
cwd: input.cwd,
|
|
611
588
|
spec: staged.spec,
|
|
@@ -4,7 +4,6 @@ import { generateTaskDagUseCase } from "../../application/dag/generate-task-dag.
|
|
|
4
4
|
import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
|
|
5
5
|
import { DAG_RUNS_DIR, isTerminalDagRunStatus, locateDagRun, readDagRunSpec, readDagRunState, } from "./lifecycle.js";
|
|
6
6
|
import { deriveDagRerunFeedback } from "./rerun-feedback.js";
|
|
7
|
-
import { acquireDagRecoveryLease, bindDagRecoveryLeaseExecution, } from "./recovery-lease.js";
|
|
8
7
|
import { parseDagSpec, } from "./types.js";
|
|
9
8
|
export const RERUN_TASK_LINEAGE_REL_PATH = ".runtime/rerun-task-lineage.json";
|
|
10
9
|
export function parseDagRerunTaskArgs(args) {
|
|
@@ -370,34 +369,6 @@ export async function rerunStandaloneTask(input) {
|
|
|
370
369
|
}
|
|
371
370
|
}
|
|
372
371
|
}
|
|
373
|
-
const recoveryLease = execute
|
|
374
|
-
? await acquireDagRecoveryLease({
|
|
375
|
-
cwd: input.cwd,
|
|
376
|
-
parentRunId: input.parentRunId,
|
|
377
|
-
requestId: input.requestId,
|
|
378
|
-
kind: "standalone-task-rerun",
|
|
379
|
-
})
|
|
380
|
-
: undefined;
|
|
381
|
-
if (recoveryLease?.kind === "held") {
|
|
382
|
-
return blockedResult({
|
|
383
|
-
parentRunId: input.parentRunId,
|
|
384
|
-
reason: input.reason,
|
|
385
|
-
requestId: input.requestId,
|
|
386
|
-
blockedReason: "recovery-lease-held",
|
|
387
|
-
note: `parent run recovery is already claimed by ${recoveryLease.lease.kind} request ${recoveryLease.lease.requestId}`,
|
|
388
|
-
taskId: taskResolution.taskId,
|
|
389
|
-
});
|
|
390
|
-
}
|
|
391
|
-
if (recoveryLease?.kind === "acquired") {
|
|
392
|
-
// Persist a non-empty execution identity before generateTaskDagUseCase can
|
|
393
|
-
// execute its new DAG. The generated run id is not available yet, so the
|
|
394
|
-
// request id is the stable lineage handle for this entry point.
|
|
395
|
-
await bindDagRecoveryLeaseExecution({
|
|
396
|
-
leasePath: recoveryLease.leasePath,
|
|
397
|
-
lease: recoveryLease.lease,
|
|
398
|
-
executionRef: `standalone-task-rerun:${input.requestId}`,
|
|
399
|
-
});
|
|
400
|
-
}
|
|
401
372
|
const generateResult = await generateTaskDagUseCase({
|
|
402
373
|
repoRoot: input.cwd,
|
|
403
374
|
taskId: taskResolution.taskId,
|