@tea-agent/loop-agent 0.39.0-next.2 → 0.39.0-next.21
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 +130 -0
- package/dist/application/dag/generate-task-dag.js +9 -0
- package/dist/build-stamp.json +2 -2
- package/dist/commands/init-upgrade.js +97 -19
- package/dist/executors/dag-pi-executor.js +42 -4
- package/dist/executors/shell-executor.js +269 -15
- package/dist/shared/operator/capabilities.js +149 -27
- package/dist/task/config-types.js +22 -0
- package/dist/worker/console/chat/deferred-turn.js +91 -0
- package/dist/worker/console/chat/mcp-inventory.js +221 -0
- package/dist/worker/console/chat/pi-runtime.js +165 -83
- package/dist/worker/console/chat/repo-walk.js +10 -1
- package/dist/worker/console/chat/routes.js +477 -55
- package/dist/worker/console/chat/semantic-activity.js +20 -8
- package/dist/worker/console/chat/session-store.js +146 -2
- package/dist/worker/console/chat/turn-process.js +17 -30
- package/dist/worker/console/harness-pi-model-matrix.js +137 -0
- package/dist/worker/console/operator-actions.js +128 -4
- package/dist/worker/console/operator-user-error.js +19 -0
- package/dist/worker/console/pi-readiness.js +8 -1
- package/dist/worker/console/recovery-cta.js +4 -4
- package/dist/worker/console/recovery-error-copy.js +4 -4
- package/dist/worker/console/security.js +20 -1
- package/dist/worker/console/server.js +6 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DSvF6RXQ.js → abnfDiagram-N423BO3Z-C4bmo3iY.js} +1 -1
- package/dist/worker/console/static/assets/{arc-DuI4ogtJ.js → arc-SAD7McOS.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-DdBbgD4y.js → architectureDiagram-T3A2C74G-DAVLUdK1.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-xQC2HELm.js → blockDiagram-VBNYF7ZC-CPPdv4vj.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DPMSgwIZ.js → c4Diagram-5PPSVZJV-D1GRGZax.js} +1 -1
- package/dist/worker/console/static/assets/channel-R6oQIDkw.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-WTEKTxin.js → chunk-2GRJ4B5K-D_Bq2ZqK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-B6vZ0Pv_.js → chunk-2Q5K7J3B-CPLVtamK.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BrerNAix.js → chunk-5RXB4S5H-DnaZWcL3.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D_ch2aaI.js → chunk-5VM5RSS4-BRTmFgnq.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-VvfacNrq.js → chunk-6Q2QTUOP-BRlfYZoH.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-B-uGFIg2.js → chunk-GF5L2VYU-CjNybD4u.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BlysCtod.js → chunk-JWPE2WC7-D3e-74fG.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BjAUAfcT.js → chunk-KBJHAD2P-Br3ir6f2.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-BeZnBmb-.js → chunk-RYQCIY6F-1NgVuRbh.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-Bbfe3UJG.js → chunk-XXDRQBXY-BTYuvuWN.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BPXlmPWI.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BPXlmPWI.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BKJQnYVM.js → cose-bilkent-JH36ORCC-BC6Bgosf.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-B1wtI3hU.js → cynefin-VYW2F7L2-DV-HypfL.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-DCF6DBSu.js → cynefinDiagram-MW4NZA55-DhTaddO-.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BJyNGRlP.js → dagre-VZM6K2ZE-BnEcOmiI.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-B7j1-VsZ.js → diagram-7IWD3JNH-xphGRVKp.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BREJ140a.js → diagram-B4RE2ZJO-CrdD1mRG.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-CDPHmHGH.js → diagram-LBJQPF4R-D4YdLsaF.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BtZLrez1.js → diagram-Q27KOJAE-LCKyGZ5U.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-mzybu8oU.js → diagram-UB23O5K3-BeiTe7t0.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Dk3I2uO6.js → ebnfDiagram-BXEA7PRR-BO2cq8GS.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-BT97u_tQ.js → erDiagram-JOGREHBK-CmWww3Nt.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CMOtYzui.js → flowDiagram-UKHOOZJN-C2kkUYg5.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DiNydkuY.js → ganttDiagram-PKOTCBZU-DY_JZ2iQ.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Cwt6fLkl.js → gitGraphDiagram-DS77QQ5N-BizhCSw9.js} +1 -1
- package/dist/worker/console/static/assets/index-BXN89VPX.js +325 -0
- package/dist/worker/console/static/assets/index-CuH5CNFu.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-AsGIGKKB.js → infoDiagram-6WML65LV-Dlo2eK_d.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BL8ITZh3.js → ishikawaDiagram-WSZJBQD7-3EIlIIuZ.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-VPKAUX8M.js → journeyDiagram-NVQOT4AX-DiMDe5Yh.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BL56hfGp.js → kanban-definition-27J2QSJJ-sN553oIN.js} +1 -1
- package/dist/worker/console/static/assets/{linear-BmSG3nIZ.js → linear-D9Py31Ld.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-DWGK9kwP.js → mermaid.core-D7Occzk_.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS--vvKLjo0.js → mindmap-definition-FAOFIHXS-DjDRboiR.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-B41mxb2-.js → pegDiagram-VL7TDLO6-Cgc4qlzp.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DTlu77sw.js → pieDiagram-7S7Q4E2Y-DxZj8pKd.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Bk5A7alv.js → quadrantDiagram-CIZ2JOQS-CJ50MngR.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Csf9jzQy.js → railroadDiagram-AXF67PYL-BY-OD8Tr.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-CeptoSNx.js → requirementDiagram-LRYGKXZP-CQFButfK.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-A-DLCLer.js → sankeyDiagram-W5VNT64P-BB_QUK_b.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-22VbPdOI.js → sequenceDiagram-SI44F4Z6-CqhXZjyx.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DWvAyBC9.js → sizeCapture-X5ZJPWSS-2l1U4rgJ.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-qICZ75yT.js → stateDiagram-OKZ733FA-BX1FbrhJ.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DJKi0Qel.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-xi7lcMyp.js → swimlanes-SLNWSIFB-DOSnT7hb.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-YYe7EEm5.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Bu6Nl6O2.js → timeline-definition-Z64GVDOM-DVJQA7AN.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BzMz4Bn9.js → vennDiagram-T6HMQDX7-74uxl9gx.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CxaJnzc5.js → wardleyDiagram-T6FBY63Y-DsBxlcg_.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-5JK-omQK.js → xychartDiagram-ELKLHX3M-snuW9Mjw.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static-src/app/console-types.js +39 -0
- package/dist/worker/console/static-src/app/useOperatorActions.js +1 -1
- package/dist/worker/console/static-src/app/useRecoveryActions.js +2 -2
- package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +82 -22
- package/dist/worker/console/static-src/operator-chat/mutation-gate.js +45 -0
- package/dist/worker/console/static-src/operator-chat/resource-diagnostics.js +204 -0
- package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +8 -1
- package/dist/worker/console/static-src/operator-chat/turn-submission.js +42 -0
- package/dist/worker/console/static-src/operator-chat/useChatSessions.js +18 -0
- package/dist/worker/console/static-src/operator-chat/useChatStream.js +216 -10
- package/dist/worker/console/static-src/operator-chat/useChatThread.js +50 -22
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +26 -1
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +755 -51
- package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
- package/dist/workflows/dag/backend-test-execution-contract.js +18 -9
- package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
- package/dist/workflows/dag/backend-test-intake-context.js +32 -0
- package/dist/workflows/dag/backend-test-layout.js +133 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +167 -32
- package/dist/workflows/dag/backend-test-module-stem.js +5 -0
- package/dist/workflows/dag/backend-test-pytest-collection.js +368 -33
- package/dist/workflows/dag/backend-test-result-contract.js +1 -1
- package/dist/workflows/dag/backend-test-scenario-param.js +884 -140
- package/dist/workflows/dag/backend-test-scenario-partitions.js +249 -0
- package/dist/workflows/dag/backend-test-writer-completeness.js +100 -56
- package/dist/workflows/dag/contract-validator-registrations.js +3 -1
- package/dist/workflows/dag/convergence/controller.js +141 -0
- package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
- package/dist/workflows/dag/dynamic-runtime/shared.js +1 -1
- package/dist/workflows/dag/frontend-implementation-contract.js +386 -0
- package/dist/workflows/dag/frontend-plan-render.js +90 -0
- package/dist/workflows/dag/frontend-prewrite-gate.js +243 -8
- package/dist/workflows/dag/init-hybrid.js +793 -104
- package/dist/workflows/dag/node-execution.js +61 -2
- package/dist/workflows/dag/prompt.js +45 -0
- package/dist/workflows/dag/rerun-feedback.js +212 -0
- package/dist/workflows/dag/rerun-plan.js +93 -27
- package/dist/workflows/dag/rerun-run.js +3 -0
- package/dist/workflows/dag/rerun-task.js +61 -2
- package/dist/workflows/dag/retry-policy.js +22 -0
- package/dist/workflows/dag/types.js +125 -0
- package/docs/templates/backend-test-dag.json +60 -35
- package/docs/templates/frontend-implementation-contract.schema.json +9 -2
- package/harness.json +3 -1
- package/package.json +1 -1
- package/skills/frontend-design-review/references/review-checklist.md +2 -0
- package/skills/frontend-implementation/references/design-spec.md +16 -19
- package/skills/frontend-implementation/references/node-contracts.md +9 -6
- package/dist/worker/console/static/assets/channel-DLVz9TYW.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BeAuGcO9.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BeAuGcO9.js +0 -1
- package/dist/worker/console/static/assets/index-DQxiso1w.js +0 -325
- package/dist/worker/console/static/assets/index-_j0Hzo69.css +0 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DzKvfHTX.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Cxqr_qM1.js +0 -8
|
@@ -3,7 +3,8 @@ import path from "node:path";
|
|
|
3
3
|
import { generateTaskDagUseCase } from "../../application/dag/generate-task-dag.js";
|
|
4
4
|
import { writeJsonAtomic } from "../../infrastructure/harness/atomic-write.js";
|
|
5
5
|
import { DAG_RUNS_DIR, isTerminalDagRunStatus, locateDagRun, readDagRunSpec, readDagRunState, } from "./lifecycle.js";
|
|
6
|
-
import {
|
|
6
|
+
import { deriveDagRerunFeedback } from "./rerun-feedback.js";
|
|
7
|
+
import { parseDagSpec, } from "./types.js";
|
|
7
8
|
export const RERUN_TASK_LINEAGE_REL_PATH = ".runtime/rerun-task-lineage.json";
|
|
8
9
|
export function parseDagRerunTaskArgs(args) {
|
|
9
10
|
if (args.length === 0) {
|
|
@@ -218,6 +219,7 @@ async function writeRerunTaskLineage(cwd, newRunId, input) {
|
|
|
218
219
|
parentRunId: input.parentRunId,
|
|
219
220
|
reason: input.reason,
|
|
220
221
|
requestId: input.requestId,
|
|
222
|
+
feedback: input.feedback,
|
|
221
223
|
createdAt: new Date().toISOString(),
|
|
222
224
|
}, { repoRoot: cwd, allowCompletedFactsWrite: true });
|
|
223
225
|
}
|
|
@@ -228,12 +230,30 @@ function blockedResult(input) {
|
|
|
228
230
|
reason: input.reason,
|
|
229
231
|
requestId: input.requestId,
|
|
230
232
|
mode: "blocked",
|
|
233
|
+
feedback: input.feedback ?? {
|
|
234
|
+
inherited: false,
|
|
235
|
+
reason: "no-unresolved-verify-review-feedback",
|
|
236
|
+
},
|
|
231
237
|
blockedReason: input.blockedReason,
|
|
232
238
|
...(input.note ? { note: input.note } : {}),
|
|
233
239
|
...(input.taskId ? { taskId: input.taskId } : {}),
|
|
234
240
|
...(input.conflictPaths ? { conflictPaths: input.conflictPaths } : {}),
|
|
235
241
|
};
|
|
236
242
|
}
|
|
243
|
+
async function readGeneratedRerunFeedback(outputPath) {
|
|
244
|
+
const raw = JSON.parse(await readFile(outputPath, "utf8"));
|
|
245
|
+
return parseDagSpec(raw).rerunFeedback;
|
|
246
|
+
}
|
|
247
|
+
function summarizeFeedback(feedback, fallbackReason) {
|
|
248
|
+
return feedback
|
|
249
|
+
? {
|
|
250
|
+
inherited: true,
|
|
251
|
+
sourceNodeId: feedback.sourceNodeId,
|
|
252
|
+
digest: feedback.digest,
|
|
253
|
+
bindingStatus: feedback.binding.status,
|
|
254
|
+
}
|
|
255
|
+
: { inherited: false, reason: fallbackReason };
|
|
256
|
+
}
|
|
237
257
|
function extractRunSummary(generateResult) {
|
|
238
258
|
if (generateResult.mode === "generate+basic-validate")
|
|
239
259
|
return undefined;
|
|
@@ -277,7 +297,26 @@ export async function rerunStandaloneTask(input) {
|
|
|
277
297
|
note: eligibility.note,
|
|
278
298
|
});
|
|
279
299
|
}
|
|
300
|
+
let parentFeedback;
|
|
301
|
+
let missingFeedbackReason = "no-unresolved-verify-review-feedback";
|
|
302
|
+
try {
|
|
303
|
+
parentFeedback = await deriveDagRerunFeedback({
|
|
304
|
+
parentRunId: input.parentRunId,
|
|
305
|
+
taskId: taskResolution.taskId,
|
|
306
|
+
runDir: located.runDir,
|
|
307
|
+
spec,
|
|
308
|
+
state,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Feedback is additive recovery context. A corrupt/missing historical
|
|
313
|
+
// artifact must be reported honestly but must not block an otherwise
|
|
314
|
+
// eligible full rerun.
|
|
315
|
+
missingFeedbackReason = "feedback-unavailable";
|
|
316
|
+
}
|
|
280
317
|
const execute = input.execute ?? true;
|
|
318
|
+
let effectiveFeedback;
|
|
319
|
+
let expectedRerunFeedbackDigest;
|
|
281
320
|
// AC-001 generated-output-conflict preflight: when a real execution is
|
|
282
321
|
// requested, first generate the DAG draft (execute:false) so we can inspect
|
|
283
322
|
// the regenerated spec's requireChangedFiles writer write sets against
|
|
@@ -296,15 +335,23 @@ export async function rerunStandaloneTask(input) {
|
|
|
296
335
|
dryRun: false,
|
|
297
336
|
profile: input.profile ?? "auto",
|
|
298
337
|
profileExplicit: input.profileExplicit ?? false,
|
|
338
|
+
rerunFeedback: parentFeedback,
|
|
299
339
|
});
|
|
300
340
|
if (preflight.mode === "generate+basic-validate") {
|
|
301
341
|
let conflictPaths = [];
|
|
302
342
|
try {
|
|
303
343
|
const raw = await readFile(preflight.outputPath, "utf8");
|
|
304
344
|
const preflightSpec = parseDagSpec(JSON.parse(raw));
|
|
345
|
+
effectiveFeedback = preflightSpec.rerunFeedback;
|
|
346
|
+
expectedRerunFeedbackDigest = effectiveFeedback?.digest;
|
|
347
|
+
if (parentFeedback && !effectiveFeedback) {
|
|
348
|
+
throw new Error("rerun feedback missing from generated preflight DAG");
|
|
349
|
+
}
|
|
305
350
|
conflictPaths = await assessGeneratedOutputConflict(preflightSpec, input.cwd);
|
|
306
351
|
}
|
|
307
|
-
catch {
|
|
352
|
+
catch (error) {
|
|
353
|
+
if (parentFeedback)
|
|
354
|
+
throw error;
|
|
308
355
|
// If the draft cannot be parsed, fall through to the real execution
|
|
309
356
|
// path: execution's own validation will surface the structural defect.
|
|
310
357
|
conflictPaths = [];
|
|
@@ -332,7 +379,17 @@ export async function rerunStandaloneTask(input) {
|
|
|
332
379
|
dryRun: false,
|
|
333
380
|
profile: input.profile ?? "auto",
|
|
334
381
|
profileExplicit: input.profileExplicit ?? false,
|
|
382
|
+
rerunFeedback: parentFeedback,
|
|
383
|
+
expectedRerunFeedbackDigest,
|
|
335
384
|
});
|
|
385
|
+
if (parentFeedback && !effectiveFeedback) {
|
|
386
|
+
effectiveFeedback = await readGeneratedRerunFeedback(generateResult.outputPath);
|
|
387
|
+
}
|
|
388
|
+
if (expectedRerunFeedbackDigest &&
|
|
389
|
+
effectiveFeedback?.digest !== expectedRerunFeedbackDigest) {
|
|
390
|
+
throw new Error(`rerun feedback drift after generation: expected ${expectedRerunFeedbackDigest}, got ${effectiveFeedback?.digest ?? "missing"}`);
|
|
391
|
+
}
|
|
392
|
+
const feedbackSummary = summarizeFeedback(effectiveFeedback, missingFeedbackReason);
|
|
336
393
|
const newRunId = extractNewRunId(generateResult);
|
|
337
394
|
const runSummary = extractRunSummary(generateResult);
|
|
338
395
|
const completedSuccessfully = !execute ||
|
|
@@ -342,6 +399,7 @@ export async function rerunStandaloneTask(input) {
|
|
|
342
399
|
parentRunId: input.parentRunId,
|
|
343
400
|
reason: input.reason,
|
|
344
401
|
requestId: input.requestId,
|
|
402
|
+
feedback: feedbackSummary,
|
|
345
403
|
});
|
|
346
404
|
}
|
|
347
405
|
const result = {
|
|
@@ -350,6 +408,7 @@ export async function rerunStandaloneTask(input) {
|
|
|
350
408
|
reason: input.reason,
|
|
351
409
|
requestId: input.requestId,
|
|
352
410
|
mode: "generate+validate+execute",
|
|
411
|
+
feedback: feedbackSummary,
|
|
353
412
|
taskId: taskResolution.taskId,
|
|
354
413
|
...(newRunId ? { newRunId } : {}),
|
|
355
414
|
...(runSummary && !completedSuccessfully && "status" in runSummary
|
|
@@ -21,6 +21,8 @@ export const STRUCTURED_OUTPUT_RETRY_CATEGORY = "output-too-large";
|
|
|
21
21
|
export const PROTOCOL_INVALID_RETRY_CATEGORY = "protocol-invalid";
|
|
22
22
|
/** Recoverable model artifact/schema formatting failure on read-only structured nodes. */
|
|
23
23
|
export const STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY = "invalid-output";
|
|
24
|
+
/** Provider stopReason=length truncated the response before the JSON contract completed. */
|
|
25
|
+
export const STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY = "structured-output-truncated";
|
|
24
26
|
/** Retry only a proven no-op from an explicitly opt-in bounded Pi writer. */
|
|
25
27
|
export const WRITER_EMPTY_DIFF_RETRY_CATEGORY = "writer-empty-diff";
|
|
26
28
|
/** Retry when a backend-test writer finished but Completeness Gate found missing/broken targets. */
|
|
@@ -36,6 +38,7 @@ export const STRUCTURED_REQUIRED_DAG_RETRY_CATEGORIES = [
|
|
|
36
38
|
...DEFAULT_DAG_RETRY_CATEGORIES,
|
|
37
39
|
STRUCTURED_OUTPUT_RETRY_CATEGORY,
|
|
38
40
|
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
41
|
+
STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY,
|
|
39
42
|
];
|
|
40
43
|
/** Categories allowed on nodes that declare a machine-readable outputProtocol. */
|
|
41
44
|
export const PROTOCOL_AWARE_DAG_RETRY_CATEGORIES = [
|
|
@@ -48,6 +51,7 @@ export const ALL_DAG_RETRY_CATEGORIES = [
|
|
|
48
51
|
STRUCTURED_OUTPUT_RETRY_CATEGORY,
|
|
49
52
|
PROTOCOL_INVALID_RETRY_CATEGORY,
|
|
50
53
|
STRUCTURED_ARTIFACT_INVALID_RETRY_CATEGORY,
|
|
54
|
+
STRUCTURED_OUTPUT_TRUNCATED_RETRY_CATEGORY,
|
|
51
55
|
WRITER_EMPTY_DIFF_RETRY_CATEGORY,
|
|
52
56
|
INCOMPLETE_WRITE_SET_RETRY_CATEGORY,
|
|
53
57
|
WRITER_CLEAN_TIMEOUT_RETRY_CATEGORY,
|
|
@@ -197,6 +201,24 @@ function isExclusivePiImplementer(task) {
|
|
|
197
201
|
!task.dynamicCondition &&
|
|
198
202
|
!task.dynamicLoopUntil);
|
|
199
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Provider/transport failure categories that can crash a writer executor
|
|
206
|
+
* after some workspace writes already landed on disk. A continuation may
|
|
207
|
+
* restart that writer itself; it must never import or normalize the ERROR fact.
|
|
208
|
+
*/
|
|
209
|
+
export const WRITER_TRANSPORT_FAILURE_CATEGORIES = new Set([
|
|
210
|
+
"unavailable",
|
|
211
|
+
"network",
|
|
212
|
+
"rate-limit",
|
|
213
|
+
"timeout",
|
|
214
|
+
]);
|
|
215
|
+
export function isTransportCrashedExclusiveWriter(task, failureCategory) {
|
|
216
|
+
if (!task)
|
|
217
|
+
return false;
|
|
218
|
+
return (isExclusivePiImplementer(task) &&
|
|
219
|
+
failureCategory !== undefined &&
|
|
220
|
+
WRITER_TRANSPORT_FAILURE_CATEGORIES.has(failureCategory));
|
|
221
|
+
}
|
|
200
222
|
/**
|
|
201
223
|
* Static eligibility for the requireChangedFiles writer-empty-diff class.
|
|
202
224
|
* The Pi executor assigns writer-empty-diff only after post-write-guard
|
|
@@ -193,12 +193,38 @@ export const dagFrontendPrewriteGateSchema = z.object({
|
|
|
193
193
|
requireSourceFreshness: z.literal(true),
|
|
194
194
|
implementationWriteSet: z.array(z.string().min(1)).min(1).optional(),
|
|
195
195
|
openspecCandidatePaths: z.array(openspecCandidatePathSchema).default([]),
|
|
196
|
+
/**
|
|
197
|
+
* Generation-frozen component/theme specification bucket. Derived from
|
|
198
|
+
* `designEvidence.classified.component ∪ theme ∪ rule.components` at DAG
|
|
199
|
+
* generation. When non-empty and the canonical contract has UI-visible
|
|
200
|
+
* work, the prewrite gate requires a non-empty `uiComponentChoices` and
|
|
201
|
+
* cross-checks each `specReference.path` against this set + the effective
|
|
202
|
+
* plan openspec-citations block. Legacy DAGs without this field keep the
|
|
203
|
+
* field-absent semantics (component-choices-missing is not enforced).
|
|
204
|
+
*/
|
|
205
|
+
componentSpecCandidatePaths: z.array(openspecCandidatePathSchema).optional(),
|
|
196
206
|
/**
|
|
197
207
|
* OpenSpec gate policy. Omitted on legacy DAGs: the runtime treats
|
|
198
208
|
* undefined as scan-strict so pre-existing full-read semantics are
|
|
199
209
|
* preserved. Generation always writes it explicitly for new DAGs.
|
|
200
210
|
*/
|
|
201
211
|
openspecPolicy: z.enum(["cited", "scan-strict"]).optional(),
|
|
212
|
+
/**
|
|
213
|
+
* When true, the effective plan node (planFromNodeId when it is selected
|
|
214
|
+
* over the fallback) emits an RFC 7386 merge-patch delta instead of a full
|
|
215
|
+
* contract. The gate applies it on the original contract node
|
|
216
|
+
* (planFallbackFromNodeIds[0]) before analysis/materialization. Legacy DAGs
|
|
217
|
+
* without this field keep full-contract semantics.
|
|
218
|
+
*/
|
|
219
|
+
revisionPatch: z.boolean().optional(),
|
|
220
|
+
/**
|
|
221
|
+
* Deterministically rendered plan.md artifact name (same outputDir as the
|
|
222
|
+
* contract). Defaults to frontend-plan.md at runtime.
|
|
223
|
+
*/
|
|
224
|
+
planMdArtifactName: z
|
|
225
|
+
.string()
|
|
226
|
+
.regex(/^[a-z0-9][a-z0-9._-]*\.md$/)
|
|
227
|
+
.optional(),
|
|
202
228
|
/**
|
|
203
229
|
* Generation-frozen candidate source metadata (diagnostic). cited mode
|
|
204
230
|
* candidates are declared ∪ taskSourceCited; scan-strict candidates are
|
|
@@ -397,6 +423,8 @@ export const dagBackendTestPipelineSchema = z.enum([
|
|
|
397
423
|
"markdown-scenario-param",
|
|
398
424
|
"markdown-execute-html",
|
|
399
425
|
"markdown-manifest",
|
|
426
|
+
"markdown-report",
|
|
427
|
+
"ingest-backend-test-gap",
|
|
400
428
|
]);
|
|
401
429
|
export const dagFrontendBrowserToolPreflightSchema = z.object({}).strict();
|
|
402
430
|
export const dagFrontendTestEvidenceValidationSchema = z.object({}).strict();
|
|
@@ -574,6 +602,13 @@ export const dagDynamicExpansionSchema = z.object({
|
|
|
574
602
|
maxTotalTokens: z.number().int().positive().optional(),
|
|
575
603
|
})
|
|
576
604
|
.optional(),
|
|
605
|
+
/**
|
|
606
|
+
* When true, any child blocked by the aggregate token budget fails the map
|
|
607
|
+
* barrier instead of being retained as a case-level blocked outcome.
|
|
608
|
+
* Backend-test enables this because partial Markdown/pytest module sets are
|
|
609
|
+
* invalid generation assets; frontend-test keeps the default false.
|
|
610
|
+
*/
|
|
611
|
+
failOnTokenBudgetExhaustion: z.boolean().optional(),
|
|
577
612
|
/**
|
|
578
613
|
* When true, map child ERROR/auth/timeout is recorded as case-level
|
|
579
614
|
* failed/blocked evidence and the map barrier still succeeds (frontend-test).
|
|
@@ -678,6 +713,8 @@ export const dagConvergenceSpecSchema = z
|
|
|
678
713
|
*/
|
|
679
714
|
export const structuredContractOutputSchemaIds = [
|
|
680
715
|
"frontend-implementation-contract-v1",
|
|
716
|
+
"frontend-implementation-contract-plan-patch-v1",
|
|
717
|
+
"frontend-implementation-contract-revision-patch-v1",
|
|
681
718
|
];
|
|
682
719
|
export const dagTaskSchema = z.object({ id: z.string().regex(/^[a-z][a-z0-9-]*$/, "task id must be kebab-case"),
|
|
683
720
|
depends_on: z.array(z.string()).default([]),
|
|
@@ -739,8 +776,25 @@ export const dagTaskSchema = z.object({ id: z.string().regex(/^[a-z][a-z0-9-]*$/
|
|
|
739
776
|
.object({
|
|
740
777
|
schemaId: z.enum(structuredContractOutputSchemaIds),
|
|
741
778
|
retryOnInvalid: z.boolean().default(true),
|
|
779
|
+
/**
|
|
780
|
+
* Optional deterministic base object for patch-producing structured
|
|
781
|
+
* nodes. The frontend plan patch validator applies the model delta to
|
|
782
|
+
* this run-owned skeleton before strict contract validation.
|
|
783
|
+
*/
|
|
784
|
+
skeleton: z.record(z.string(), z.unknown()).optional(),
|
|
742
785
|
})
|
|
743
786
|
.strict()
|
|
787
|
+
.superRefine((value, ctx) => {
|
|
788
|
+
if (value.schemaId ===
|
|
789
|
+
"frontend-implementation-contract-plan-patch-v1" &&
|
|
790
|
+
!value.skeleton) {
|
|
791
|
+
ctx.addIssue({
|
|
792
|
+
code: "custom",
|
|
793
|
+
message: "frontend plan patch output requires a runtime skeleton",
|
|
794
|
+
path: ["skeleton"],
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
})
|
|
744
798
|
.optional(),
|
|
745
799
|
/**
|
|
746
800
|
* Fail-closed outcome/diff consistency contract for bounded Pi writers.
|
|
@@ -819,6 +873,55 @@ export const dagSourceBindingSchema = z.object({
|
|
|
819
873
|
.min(1),
|
|
820
874
|
requirementIds: z.array(z.string().regex(/^(?:REQ|BR|AC)-[A-Z0-9]+(?:-[A-Z0-9]+)*$/)),
|
|
821
875
|
});
|
|
876
|
+
const dagRerunFeedbackEvidencePathSchema = z
|
|
877
|
+
.string()
|
|
878
|
+
.min(1)
|
|
879
|
+
.refine((value) => !/^(?:[A-Za-z]:[\\/]|[\\/]{2}|\/)/.test(value), "rerun feedback evidence paths must be repository-relative");
|
|
880
|
+
/**
|
|
881
|
+
* Bounded unresolved verify/review feedback carried by a full task rerun.
|
|
882
|
+
* This is recovery context, not a mutation of the original task contract.
|
|
883
|
+
*/
|
|
884
|
+
export const dagRerunFeedbackSchema = z
|
|
885
|
+
.object({
|
|
886
|
+
schemaVersion: z.literal(1),
|
|
887
|
+
kind: z.literal("unresolved-terminal-feedback"),
|
|
888
|
+
parentRunId: z.string().min(1),
|
|
889
|
+
taskId: z.string().min(1),
|
|
890
|
+
sourceNodeId: z.string().min(1),
|
|
891
|
+
verdict: z.enum(["request-revision", "fail"]).optional(),
|
|
892
|
+
failureCategory: z.string().min(1).optional(),
|
|
893
|
+
feedbackText: z.string().min(1).max(12_000),
|
|
894
|
+
evidenceRefs: z
|
|
895
|
+
.array(z
|
|
896
|
+
.object({
|
|
897
|
+
nodeId: z.string().min(1),
|
|
898
|
+
preservedNodeRecordPath: dagRerunFeedbackEvidencePathSchema,
|
|
899
|
+
})
|
|
900
|
+
.strict())
|
|
901
|
+
.max(8),
|
|
902
|
+
attemptSummary: z
|
|
903
|
+
.object({
|
|
904
|
+
completedPasses: z.number().int().positive(),
|
|
905
|
+
maxPasses: z.number().int().positive(),
|
|
906
|
+
terminalReason: z.string().min(1).optional(),
|
|
907
|
+
})
|
|
908
|
+
.strict(),
|
|
909
|
+
binding: z
|
|
910
|
+
.object({
|
|
911
|
+
sourceCanonicalHash: z
|
|
912
|
+
.string()
|
|
913
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
914
|
+
.optional(),
|
|
915
|
+
taskContractCanonicalHash: z
|
|
916
|
+
.string()
|
|
917
|
+
.regex(/^[a-f0-9]{64}$/)
|
|
918
|
+
.optional(),
|
|
919
|
+
status: z.enum(["exact", "changed", "unknown"]),
|
|
920
|
+
})
|
|
921
|
+
.strict(),
|
|
922
|
+
digest: z.string().regex(/^[a-f0-9]{64}$/),
|
|
923
|
+
})
|
|
924
|
+
.strict();
|
|
822
925
|
export const dagSpecSchema = z
|
|
823
926
|
.object({
|
|
824
927
|
version: dagVersionSchema,
|
|
@@ -830,6 +933,28 @@ export const dagSpecSchema = z
|
|
|
830
933
|
sourceBinding: dagSourceBindingSchema.optional(),
|
|
831
934
|
/** v4 managed Task Contract binding; only valid on version 4. */
|
|
832
935
|
taskContractBinding: dagTaskContractBindingSchema.optional(),
|
|
936
|
+
/** Optional unresolved parent-run feedback for a full task rerun. */
|
|
937
|
+
rerunFeedback: dagRerunFeedbackSchema.optional(),
|
|
938
|
+
/** Frozen backend-test artifact layout (plan A); absent = historical default testcase/ layout. */
|
|
939
|
+
backendTestLayout: z
|
|
940
|
+
.object({
|
|
941
|
+
testRoot: z.string(),
|
|
942
|
+
markdownRel: z.string(),
|
|
943
|
+
scriptRel: z.string(),
|
|
944
|
+
markdownDir: z.string(),
|
|
945
|
+
scriptDir: z.string(),
|
|
946
|
+
readmePath: z.string(),
|
|
947
|
+
isDefault: z.boolean(),
|
|
948
|
+
})
|
|
949
|
+
.optional(),
|
|
950
|
+
/** Bound user shared-setup document (plan B); absent = no shared setup references expected. */
|
|
951
|
+
backendTestSharedSetup: z
|
|
952
|
+
.object({
|
|
953
|
+
path: z.string(),
|
|
954
|
+
readPath: z.string(),
|
|
955
|
+
sha256: z.string(),
|
|
956
|
+
})
|
|
957
|
+
.optional(),
|
|
833
958
|
outputLanguage: dagOutputLanguageSchema.optional(),
|
|
834
959
|
objective: z.string().optional(),
|
|
835
960
|
successCriteria: z.array(z.string()).optional(),
|