@deksden-com/dd-flow-cli 0.9.0-beta.156 → 0.9.0-beta.158
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 +15 -0
- package/dist/build-info.json +8 -8
- package/dist/cli/error-output.js +11 -1
- package/dist/cli/input-preparation.js +32 -4
- package/dist/cli/run-cli.js +24 -7
- package/dist/harness-runtime/lib/daemon-operations.mjs +46 -11
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +19 -6
- package/dist/harness-runtime/lib/dd-agy.mjs +19 -0
- package/dist/harness-runtime/lib/dd-codex-daemon.mjs +1 -1
- package/dist/harness-runtime/lib/dd-droid-daemon.mjs +1 -1
- package/dist/harness-runtime/lib/dd-grok-daemon.mjs +2 -2
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +1 -1
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +1 -1
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +1 -0
- package/dist/harness-runtime/lib/delegation-instructions.mjs +3 -0
- package/dist/schemas/code-work-batch.schema.json +1 -1
- package/dist/schemas/vnext-protocol-plan.schema.json +1 -1
- package/dist/services/codex-capacity.js +367 -0
- package/dist/services/controller-child-repair.js +46 -24
- package/dist/services/controller-fanout.js +23 -15
- package/dist/services/controller-result-authority.js +13 -8
- package/dist/services/controller-work-failure.js +198 -0
- package/dist/services/lifecycle-invocations.js +81 -16
- package/dist/services/managed-daemon-binding.js +40 -0
- package/dist/services/run-control.js +18 -36
- package/dist/services/run-controller.js +107 -22
- package/dist/services/vnext-code.js +3 -1
- package/dist/services/vnext-plan-review.js +2 -2
- package/dist/services/vnext-plan.js +3 -3
- package/dist/services/work-registry.js +59 -12
- package/dist/services/work-retry-context.js +55 -0
- package/dist/verification-components.json +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import crypto from "node:crypto";
|
|
4
|
+
import { AppError } from "../shared/errors.js";
|
|
5
|
+
import { managedDaemonExecutionAbsent } from "./managed-daemon-binding.js";
|
|
6
|
+
export const retryCorrectionFile = "retry-correction.json";
|
|
7
|
+
export const retryReceiptFile = "retry-receipt.json";
|
|
8
|
+
const hash = (bytes) => crypto.createHash("sha256").update(bytes).digest("hex");
|
|
9
|
+
export function prepareRetryCorrection(input, work, runHome) {
|
|
10
|
+
if (!input || typeof input.episode_id !== "string" || !input.episode_id.trim() || typeof input.correction !== "string" || !input.correction.trim()
|
|
11
|
+
|| typeof input.decision_ref !== "string" || !path.isAbsolute(input.decision_ref) || input.failed_result_sha256 !== hash(work.result ?? ""))
|
|
12
|
+
throw new AppError("work_retry_correction_invalid", "Retry correction does not identify the retained failed Work", 1);
|
|
13
|
+
const home = fs.realpathSync(runHome), decision = fs.realpathSync(input.decision_ref);
|
|
14
|
+
if (!decision.startsWith(`${home}${path.sep}`) || !fs.statSync(decision).isFile())
|
|
15
|
+
throw new AppError("work_retry_correction_invalid", "Retry decision must be a retained file inside this RUN", 1);
|
|
16
|
+
const bytes = fs.readFileSync(decision), accepted = JSON.parse(bytes.toString("utf8"));
|
|
17
|
+
if (accepted.schema_id !== "work-failure-decision@1" || accepted.action !== "retry" || accepted.episode_id !== input.episode_id || accepted.correction !== input.correction)
|
|
18
|
+
throw new AppError("work_retry_correction_invalid", "Retry correction differs from the retained coordinator decision", 1);
|
|
19
|
+
return { ...input, decision_ref: decision, decision_sha256: hash(bytes), work_id: work.work_id, project_id: work.project_id, run_id: work.run_id };
|
|
20
|
+
}
|
|
21
|
+
/** Snapshot the old launch before its current-row slot is reused; no process I/O in SQL. */
|
|
22
|
+
export function prepareExternalRetry(context, work) {
|
|
23
|
+
if (!context.db.get("SELECT 1 FROM sqlite_master WHERE type='table' AND name='work_launches'"))
|
|
24
|
+
return null;
|
|
25
|
+
const launch = context.db.get("SELECT * FROM work_launches WHERE work_id=?", [work.work_id]);
|
|
26
|
+
if (!launch)
|
|
27
|
+
return null;
|
|
28
|
+
if (!["start_requested", "completed", "failed", "cancelled"].includes(launch.status)
|
|
29
|
+
|| !managedDaemonExecutionAbsent(context, { stateDir: launch.state_dir, projectId: work.project_id, runId: work.run_id }))
|
|
30
|
+
throw new AppError("work_retry_external_unsettled", "Previous external Work launch still has unknown or live execution; reconcile it before retry", 1, { work_id: work.work_id, operation_id: launch.operation_id, state_dir: launch.state_dir });
|
|
31
|
+
return launch;
|
|
32
|
+
}
|
|
33
|
+
export function renderRetryCorrection(context, work, runHome) {
|
|
34
|
+
const directory = path.join(runHome, "works", work.work_id), file = path.join(directory, retryCorrectionFile);
|
|
35
|
+
if (!fs.existsSync(file))
|
|
36
|
+
return "";
|
|
37
|
+
const value = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
38
|
+
const receipt = JSON.parse(fs.readFileSync(path.join(directory, retryReceiptFile), "utf8"));
|
|
39
|
+
const current = context.db.get("SELECT current_start_invocation_id FROM works WHERE work_id=?", [work.work_id]);
|
|
40
|
+
const realHome = fs.realpathSync(runHome), realDecision = fs.realpathSync(value.decision_ref);
|
|
41
|
+
if (value.work_id !== work.work_id || value.project_id !== work.project_id || value.run_id !== work.run_id
|
|
42
|
+
|| receipt.work_id !== work.work_id || receipt.episode_id !== value.episode_id || receipt.current_start_invocation_id !== current?.current_start_invocation_id
|
|
43
|
+
|| !realDecision.startsWith(`${realHome}${path.sep}`))
|
|
44
|
+
throw new AppError("work_retry_correction_invalid", "Retained retry correction no longer matches this Work attempt", 1);
|
|
45
|
+
const decisionBytes = fs.readFileSync(realDecision);
|
|
46
|
+
if (value.decision_sha256 !== hash(decisionBytes))
|
|
47
|
+
throw new AppError("work_retry_correction_invalid", "Retained retry decision changed", 1);
|
|
48
|
+
const accepted = JSON.parse(decisionBytes.toString("utf8"));
|
|
49
|
+
if (accepted.schema_id !== "work-failure-decision@1" || accepted.action !== "retry"
|
|
50
|
+
|| accepted.episode_id !== value.episode_id || accepted.correction !== value.correction)
|
|
51
|
+
throw new AppError("work_retry_correction_invalid", "Retained retry correction no longer matches this Work attempt", 1);
|
|
52
|
+
return ["<accepted_work_retry_correction>", `- failed-result sha256: ${value.failed_result_sha256}`, `- retained decision: ${value.decision_ref}`,
|
|
53
|
+
`- episode: ${value.episode_id}`, value.correction,
|
|
54
|
+
"This is the coordinator's correction for this fresh attempt, not a new user requirement or permission to widen accepted scope. Read the retained decision. Apply its interpretation to the historical stop conditions; preserve accepted requirements, non-goals and previous receipts. Do not repeat an accepted predecessor Work.", "</accepted_work_retry_correction>", ""].join("\n");
|
|
55
|
+
}
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"services/command-context.js",
|
|
66
66
|
"services/config.js",
|
|
67
67
|
"services/controller-result-authority.js",
|
|
68
|
+
"services/controller-work-failure.js",
|
|
68
69
|
"services/delivery-access.js",
|
|
69
70
|
"services/delivery-approval.js",
|
|
70
71
|
"services/delivery-artifact.js",
|
|
@@ -329,6 +330,7 @@
|
|
|
329
330
|
"services/session-identity.js",
|
|
330
331
|
"services/sessions.js",
|
|
331
332
|
"services/setup.js",
|
|
333
|
+
"services/stage-blocker.js",
|
|
332
334
|
"services/stage-context.js",
|
|
333
335
|
"services/stage-handlers.js",
|
|
334
336
|
"services/stage-lifecycle.js",
|
|
@@ -352,6 +354,7 @@
|
|
|
352
354
|
"services/vnext-specify.js",
|
|
353
355
|
"services/vnext-workspace-policy.js",
|
|
354
356
|
"services/work-registry.js",
|
|
357
|
+
"services/work-retry-context.js",
|
|
355
358
|
"services/workspace-bootstrap.js",
|
|
356
359
|
"services/workspace-files.js",
|
|
357
360
|
"services/worktrees.js",
|