@deksden-com/dd-flow-cli 0.9.0-beta.150 → 0.9.0-beta.151
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 +12 -0
- package/README.md +17 -22
- package/dist/build-info.json +6 -6
- package/dist/harness-runtime/lib/agy-error-boundary.mjs +26 -5
- package/dist/harness-runtime/lib/agy-terminal-envelope.mjs +67 -0
- package/dist/harness-runtime/lib/dd-agy-daemon.mjs +10 -14
- package/dist/harness-runtime/lib/dd-agy.mjs +3 -3
- package/dist/harness-runtime/lib/dd-droid.mjs +2 -2
- package/dist/harness-runtime/lib/dd-opencode-daemon.mjs +8 -3
- package/dist/harness-runtime/lib/dd-opencode.mjs +2 -2
- package/dist/harness-runtime/lib/dd-zcode-daemon.mjs +1 -1
- package/dist/harness-runtime/lib/dd-zcode.mjs +37 -12
- package/dist/harness-runtime/lib/delegation-instructions.d.mts +1 -1
- package/dist/harness-runtime/lib/delegation-instructions.mjs +13 -4
- package/dist/harness-runtime/lib/model-observations.mjs +19 -7
- package/dist/harness-runtime/lib/native-children.d.mts +12 -1
- package/dist/harness-runtime/lib/native-children.mjs +47 -1
- package/dist/harness-runtime/lib/provider-overload-policy.d.mts +9 -1
- package/dist/harness-runtime/lib/provider-overload-policy.mjs +97 -6
- package/dist/services/check-runner-evidence.js +17 -302
- package/dist/services/check-runner-proof.js +305 -0
- package/dist/services/code-checks.js +4 -1
- package/dist/services/controller-child-capacity.js +58 -0
- package/dist/services/controller-child-observer.js +9 -3
- package/dist/services/memory-init-native-capacity.js +1 -1
- package/dist/services/provider-capacity.js +15 -7
- package/dist/services/run-controller-adapter.js +1 -1
- package/dist/services/run-controller.js +87 -18
- package/dist/services/run-recovery-guard.js +1 -1
- package/dist/services/run-recovery-runtime.js +1 -1
- package/dist/services/stage-context.js +56 -8
- package/dist/services/vnext-fanout.js +1 -1
- package/dist/verification-components.json +299 -0
- package/package.json +7 -6
|
@@ -45,14 +45,14 @@ import { assertNoCorrelatedRejection } from "./continuation-outcome.js";
|
|
|
45
45
|
import { spawnController, recordControllerLauncher, claimControllerProcess, markControllerDispatchReady, assertControllerLeaseAllowed } from "./run-controller-process.js";
|
|
46
46
|
import { controllerAdapter, controllerEnvironment, sessionArguments } from "./run-controller-adapter.js";
|
|
47
47
|
import { retainedChildObserver } from "./controller-child-observer.js";
|
|
48
|
-
import { capacityDelay, continueProviderCapacity, eligibleProviderChildOverload, providerChildFailure, ownedProviderBoundary } from "./provider-capacity.js";
|
|
48
|
+
import { capacityDelay, continueProviderCapacity, eligibleProviderChildOverload, providerChildFailure, ownedProviderBoundary, unavailableProviderChildRecovery } from "./provider-capacity.js";
|
|
49
49
|
import { resumeControllerSession, failControllerRecovery } from "./run-controller-recovery.js";
|
|
50
50
|
import { captureControllerBoundary } from "./run-controller-capture.js";
|
|
51
51
|
import { requestRunControl } from "./run-control-worker.js";
|
|
52
52
|
import { storageSessionId } from "./session-identity.js";
|
|
53
|
-
import { CAPACITY_POLICY, nativeItemsSettled, overloadExhausted, refusalObservation, terminalProviderOverload } from "../harness-runtime/lib/provider-overload-policy.mjs";
|
|
53
|
+
import { RECOVERY_POLICY as CAPACITY_POLICY, nativeItemsSettled, recoveryExhausted as overloadExhausted, recoveryRefusal as refusalObservation, terminalProviderRecovery as terminalProviderOverload, normalizeRecoveryFailure } from "../harness-runtime/lib/provider-overload-policy.mjs";
|
|
54
54
|
import { renderNativeChildFollowupInstruction } from "../harness-runtime/lib/delegation-instructions.mjs";
|
|
55
|
-
import { closeSuccessfulChildCapacity } from "./controller-child-capacity.js";
|
|
55
|
+
import { childCapacityDispatchAllowed, childCapacityRecoveryDecision, closeSuccessfulChildCapacity, reconcileChildCapacity } from "./controller-child-capacity.js";
|
|
56
56
|
import { isObservationLoss } from "../harness-runtime/lib/operation-errors.mjs";
|
|
57
57
|
export { resumeRunController } from "./run-controller-recovery.js";
|
|
58
58
|
const preparedLaunchInputs = new WeakMap();
|
|
@@ -754,7 +754,8 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
754
754
|
throw new AppError("capacity_continuation_conflict", "Retained capacity root has no failure receipt", 1);
|
|
755
755
|
throw JSON.parse(root.error_json);
|
|
756
756
|
}
|
|
757
|
-
|
|
757
|
+
const failedChildren = childObserver(session)?.failed() ?? [];
|
|
758
|
+
if (failedChildren.length && !(kind === "child" && childCapacityDispatchAllowed(state, failedChildren, session.id, firstOperationId, digestBytes(text))))
|
|
758
759
|
throw new AppError("fanout_dispatch_fenced", "A retained child failure forbids another coordinator dispatch", 1);
|
|
759
760
|
promptPending = true;
|
|
760
761
|
observedPromptOperation = firstOperationId;
|
|
@@ -785,15 +786,15 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
785
786
|
assertCurrent: () => {
|
|
786
787
|
assertOwner();
|
|
787
788
|
},
|
|
788
|
-
decision: async (boundary) => {
|
|
789
|
+
decision: async (boundary, currentFailure) => {
|
|
789
790
|
if (kind === "child") {
|
|
790
|
-
const target = Object.entries(state.child_capacity ?? {}).find(([, retained]) => retained.operation_id === firstOperationId);
|
|
791
|
-
if (!target)
|
|
792
|
-
return "reconciliation_blocked";
|
|
793
791
|
const seen = await inspect(["session", "inspect", "--session-id", session.id, ...sessionArguments(context, manifest, session)], `${firstOperationId}:child-followup-observe`);
|
|
794
|
-
const
|
|
795
|
-
|
|
796
|
-
|
|
792
|
+
const parent = normalizeRecoveryFailure(currentFailure, session.id);
|
|
793
|
+
const decision = childCapacityRecoveryDecision(state, controllerNativeChildren(seen, session.id), session.id, firstOperationId, parent?.request_proof.kind === "native_turn" ? parent.turn_id : undefined);
|
|
794
|
+
if (decision !== "continue") {
|
|
795
|
+
saveState(context, row, state);
|
|
796
|
+
return decision;
|
|
797
|
+
}
|
|
797
798
|
}
|
|
798
799
|
const view = getFlowRunStatus(executionContext, { projectRoot: manifest.request.project_root, runId: row.run_id });
|
|
799
800
|
const next = view.continuation;
|
|
@@ -1081,7 +1082,32 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1081
1082
|
const session = state.sessions[state.current_session];
|
|
1082
1083
|
const childHarness = runtimeHarness(session.profile);
|
|
1083
1084
|
const baseline = new Set(state.native_baseline ?? []);
|
|
1085
|
+
for (const intent of Object.values(state.child_capacity ?? {})) {
|
|
1086
|
+
if (!intent.dispatched || !intent.operation_id || intent.parent_turn_id || !intent.prompt_sha256)
|
|
1087
|
+
continue;
|
|
1088
|
+
let saved = context.db.get("SELECT input_json,receipt_json,status FROM run_controller_operations WHERE operation_id = ? AND controller_id = ? AND generation = ?", [intent.operation_id, row.controller_id, row.generation]);
|
|
1089
|
+
if (!saved)
|
|
1090
|
+
continue;
|
|
1091
|
+
const dispatch = JSON.parse(saved.input_json);
|
|
1092
|
+
if (!saved.receipt_json && saved.status === "outcome_unknown" && dispatch.dispatch_phase !== "prepared" && dispatch.prompt_sha256 === intent.prompt_sha256 && Array.isArray(dispatch.args)) {
|
|
1093
|
+
// Existing adapter recovery reads its durable operation; it cannot
|
|
1094
|
+
// redispatch a productive operation past external_dispatch_possible.
|
|
1095
|
+
await controllerAdapter(executionContext, row, manifest, session, dispatch.args, assertOwner, intent.operation_id, cancellation.signal, renewLease);
|
|
1096
|
+
saved = context.db.get("SELECT input_json,receipt_json,status FROM run_controller_operations WHERE operation_id = ? AND controller_id = ? AND generation = ?", [intent.operation_id, row.controller_id, row.generation]);
|
|
1097
|
+
}
|
|
1098
|
+
if (!saved?.receipt_json)
|
|
1099
|
+
continue;
|
|
1100
|
+
const receipt = JSON.parse(saved.receipt_json);
|
|
1101
|
+
if ((saved.status === "completed" || dispatch.dispatch_phase === "receipt_observed") && dispatch.prompt_sha256 === intent.prompt_sha256
|
|
1102
|
+
&& receipt.provider_session_id === session.id && receipt.turn?._meta?.zcode?.ddFlowRecovery?.operation_id === intent.operation_id
|
|
1103
|
+
&& typeof receipt.turn._meta.zcodeNativeTurnId === "string" && receipt.turn._meta.zcodeNativeTurnId) {
|
|
1104
|
+
intent.parent_turn_id = receipt.turn._meta.zcodeNativeTurnId;
|
|
1105
|
+
saveState(context, row, state);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1084
1108
|
let children = controllerNativeChildren(state.last_receipt ?? {}, session.id).filter(child => !baseline.has(child.session_id));
|
|
1109
|
+
if (reconcileChildCapacity(state, children, session.id))
|
|
1110
|
+
saveState(context, row, state);
|
|
1085
1111
|
childObserver(session)?.observeSettledChildren(children);
|
|
1086
1112
|
const retainedFailures = childObserver(session)?.failed() ?? [];
|
|
1087
1113
|
children = controllerNativeChildren({ descendants: [...children, ...retainedFailures] }, session.id);
|
|
@@ -1091,7 +1117,35 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1091
1117
|
saveState(context, row, state);
|
|
1092
1118
|
appendEvent(context, row.controller_id, "capacity_child_episodes_completed", { child_session_ids: closedChildEpisodes });
|
|
1093
1119
|
});
|
|
1094
|
-
|
|
1120
|
+
const queuedChild = children.find(child => state.child_capacity?.[child.session_id]?.phase === "native_message_accepted"
|
|
1121
|
+
&& (child.status === "failed" && state.child_capacity[child.session_id].turn_id === child.terminal_turn_id
|
|
1122
|
+
|| child.status === "running" && child.continuation_admission?.proof_kind === "parent_tool_admission"));
|
|
1123
|
+
if (queuedChild) {
|
|
1124
|
+
const observedAt = Date.parse(state.child_capacity[queuedChild.session_id].last_signal_at ?? "");
|
|
1125
|
+
if (!Number.isFinite(observedAt) || Date.now() - observedAt >= 600_000)
|
|
1126
|
+
throw new AppError("operation_observation_lost", "Accepted native child continuation has no new observed signal", 1, { child_session_id: queuedChild.session_id });
|
|
1127
|
+
setStatus("waiting_for_children");
|
|
1128
|
+
await delay(1000, undefined, { signal: cancellation.signal });
|
|
1129
|
+
state.last_receipt = await call(session, ["session", "inspect", "--session-id", session.id, ...sessionArguments(context, manifest, session)], false);
|
|
1130
|
+
saveState(context, row, state);
|
|
1131
|
+
continue;
|
|
1132
|
+
}
|
|
1133
|
+
const recoveryUnavailable = children.map(child => {
|
|
1134
|
+
const links = context.db.all("SELECT w.status FROM work_sessions ws JOIN works w ON w.work_id = ws.work_id WHERE w.project_id = ? AND w.run_id = ? AND ws.session_id = ?", [row.project_id, row.run_id, storageSessionId({ harness_id: childHarness, session_id: child.session_id })]);
|
|
1135
|
+
return links.length > 1 || links.some(link => link.status !== "running") ? null : unavailableProviderChildRecovery(child, session.id);
|
|
1136
|
+
}).find(Boolean);
|
|
1137
|
+
if (recoveryUnavailable) {
|
|
1138
|
+
if (children.every(child => ["completed", "failed", "cancelled", "settled_by_root"].includes(child.status)))
|
|
1139
|
+
throw recoveryUnavailable;
|
|
1140
|
+
// A blocked child does not cancel healthy siblings. Observe their own
|
|
1141
|
+
// native completion before reporting the unavailable continuation.
|
|
1142
|
+
setStatus("waiting_for_children");
|
|
1143
|
+
await delay(1000, undefined, { signal: cancellation.signal });
|
|
1144
|
+
state.last_receipt = await call(session, ["session", "inspect", "--session-id", session.id, ...sessionArguments(context, manifest, session)], false);
|
|
1145
|
+
saveState(context, row, state);
|
|
1146
|
+
continue;
|
|
1147
|
+
}
|
|
1148
|
+
if (children.some(child => child.status === "failed" && renderNativeChildFollowupInstruction(childHarness, child))) {
|
|
1095
1149
|
const inspected = await call(session, ["session", "inspect", "--session-id", session.id, ...sessionArguments(context, manifest, session)], false);
|
|
1096
1150
|
state.last_receipt = inspected;
|
|
1097
1151
|
saveState(context, row, state);
|
|
@@ -1104,6 +1158,8 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1104
1158
|
if (linked.length > 1 || linked.some(link => link.status !== "running"))
|
|
1105
1159
|
continue;
|
|
1106
1160
|
const retained = state.child_capacity?.[failedChild.session_id];
|
|
1161
|
+
if (retained?.policy && retained.policy !== CAPACITY_POLICY)
|
|
1162
|
+
throw new AppError("capacity_policy_mismatch", "Retained child episode requires its original pinned recovery policy", 1);
|
|
1107
1163
|
const refusals = [...(retained?.refusals ?? [])];
|
|
1108
1164
|
if (refusals.some(item => item.turn_id === failedChild.terminal_turn_id))
|
|
1109
1165
|
continue;
|
|
@@ -1114,11 +1170,11 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1114
1170
|
await prepareMutation(() => { saveState(context, row, state); appendEvent(context, row.controller_id, "capacity_child_refusal", { child_session_id: failedChild.session_id, refusal: refusals.at(-1) }); });
|
|
1115
1171
|
const exhausted = overloadExhausted(refusals);
|
|
1116
1172
|
if (exhausted)
|
|
1117
|
-
throw new AppError("provider_unavailable", "Native child exhausted its
|
|
1173
|
+
throw new AppError("provider_unavailable", "Native child exhausted its provider continuation attempts", 1, { ...exhausted, child_session_id: failedChild.session_id, primary_error: nativeFailure });
|
|
1118
1174
|
}
|
|
1119
1175
|
// Continue one existing child at a time; another failed child does not
|
|
1120
1176
|
// create a second fanout wave or share this child's refusal counter.
|
|
1121
|
-
const child = children.every(item => item.status === "failed" || item.status === "completed") ? failed.find(item => renderNativeChildFollowupInstruction(childHarness, item
|
|
1177
|
+
const child = children.every(item => item.status === "failed" || item.status === "completed") ? failed.find(item => renderNativeChildFollowupInstruction(childHarness, item) && eligibleProviderChildOverload(item, session.id)) : undefined;
|
|
1122
1178
|
const turnId = child?.terminal_turn_id;
|
|
1123
1179
|
const native = child && turnId ? providerChildFailure(child) : null;
|
|
1124
1180
|
const prior = child && state.child_capacity?.[child.session_id];
|
|
@@ -1143,7 +1199,7 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1143
1199
|
}
|
|
1144
1200
|
const exhausted = overloadExhausted(refusals);
|
|
1145
1201
|
if (exhausted)
|
|
1146
|
-
throw new AppError("provider_unavailable", "Native child exhausted its
|
|
1202
|
+
throw new AppError("provider_unavailable", "Native child exhausted its provider continuation attempts", 1, { ...exhausted, child_session_id: child.session_id, primary_error: native });
|
|
1147
1203
|
let wait;
|
|
1148
1204
|
try {
|
|
1149
1205
|
wait = prepared ? Math.max(0, Date.parse(prepared.not_before) - Date.now()) : capacityDelay(native, attempt);
|
|
@@ -1157,7 +1213,8 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1157
1213
|
const rootOperationId = prior?.root_operation_id ?? `${row.controller_id}:child:${digest([child.session_id, turnId]).slice(0, 16)}`;
|
|
1158
1214
|
const operationId = prepared?.operation_id ?? `${rootOperationId}:followup:${attempt}`;
|
|
1159
1215
|
state.child_capacity ??= {};
|
|
1160
|
-
|
|
1216
|
+
const followupText = renderNativeChildFollowupInstruction(childHarness, child);
|
|
1217
|
+
state.child_capacity[child.session_id] = { turn_id: turnId, attempts: attempt, operation_id: operationId, root_operation_id: rootOperationId, policy: CAPACITY_POLICY, refusals, not_before: prepared?.not_before ?? new Date(Date.now() + wait).toISOString(), dispatched: false, phase: "prepare", prompt_sha256: digestBytes(followupText), ...(child.continuation_ref ? { continuation_ref: child.continuation_ref } : {}) };
|
|
1161
1218
|
await prepareMutation(() => { saveState(context, row, state); appendEvent(context, row.controller_id, "capacity_child_followup", { child_session_id: child.session_id, turn_id: turnId, attempt, operation_id: operationId }); });
|
|
1162
1219
|
const until = performance.now() + wait;
|
|
1163
1220
|
while (performance.now() < until) {
|
|
@@ -1186,15 +1243,27 @@ async function executeController(context, row, manifest, state, assertOwnership,
|
|
|
1186
1243
|
throw new AppError("capacity_child_followup_blocked", "Native child or Work changed during capacity wait", 1, { child_session_id: child.session_id, turn_id: turnId });
|
|
1187
1244
|
await renewLease();
|
|
1188
1245
|
assertOwner();
|
|
1189
|
-
const text = renderNativeChildFollowupInstruction(childHarness, child
|
|
1246
|
+
const text = renderNativeChildFollowupInstruction(childHarness, child);
|
|
1247
|
+
// Fence dispatch before awaiting the parent: a lost ack must never
|
|
1248
|
+
// resend SendMessage into a child which may already be running.
|
|
1249
|
+
state.child_capacity[child.session_id].dispatched = true;
|
|
1250
|
+
state.child_capacity[child.session_id].phase = "dispatched";
|
|
1251
|
+
saveState(context, row, state);
|
|
1190
1252
|
await prompt(session, text, operationId, "child");
|
|
1253
|
+
const parentTurnId = state.last_receipt?.turn?._meta?.zcodeNativeTurnId;
|
|
1254
|
+
if (typeof parentTurnId === "string" && parentTurnId)
|
|
1255
|
+
state.child_capacity[child.session_id].parent_turn_id = parentTurnId;
|
|
1191
1256
|
state.child_capacity[child.session_id].dispatched = true;
|
|
1192
1257
|
saveState(context, row, state);
|
|
1193
1258
|
const after = await call(session, ["session", "inspect", "--session-id", session.id, ...sessionArguments(context, manifest, session)], false);
|
|
1259
|
+
const afterChildren = controllerNativeChildren(after, session.id);
|
|
1260
|
+
reconcileChildCapacity(state, afterChildren, session.id);
|
|
1261
|
+
if (after.descendants)
|
|
1262
|
+
after.descendants = afterChildren;
|
|
1194
1263
|
state.last_receipt = after;
|
|
1195
1264
|
saveState(context, row, state);
|
|
1196
1265
|
const observed = controllerNativeChildren(after, session.id).find(item => item.session_id === child.session_id);
|
|
1197
|
-
if (!observed || observed.status === "failed" && observed.terminal_turn_id === turnId)
|
|
1266
|
+
if (!observed || observed.status === "failed" && observed.terminal_turn_id === turnId && state.child_capacity[child.session_id].phase !== "native_message_accepted")
|
|
1198
1267
|
throw new AppError("capacity_child_followup_unconfirmed", "Native child did not advance to a new Turn after parent followup", 1, { child_session_id: child.session_id, turn_id: turnId });
|
|
1199
1268
|
continue;
|
|
1200
1269
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { AppError } from "../shared/errors.js";
|
|
3
|
-
import { CAPACITY_POLICY, MAX_OVERLOAD_RETRIES, overloadExhausted } from "../harness-runtime/lib/provider-overload-policy.mjs";
|
|
3
|
+
import { RECOVERY_POLICY as CAPACITY_POLICY, MAX_OVERLOAD_RETRIES, recoveryExhausted as overloadExhausted } from "../harness-runtime/lib/provider-overload-policy.mjs";
|
|
4
4
|
import { assertRunStartupSettled } from "./run-start-custody.js";
|
|
5
5
|
export function recoveryPacketReceipt(binding) {
|
|
6
6
|
if (!binding.packet_json || !binding.packet_sha256 || crypto.createHash("sha256").update(binding.packet_json).digest("hex") !== binding.packet_sha256)
|
|
@@ -8,7 +8,7 @@ import { managedProcessBinding, processIsAlive, resourceHome } from "./managed-p
|
|
|
8
8
|
import { getResourceDatabase } from "../storage/database.js";
|
|
9
9
|
import { requireManagedDaemonBinding } from "./managed-daemon-binding.js";
|
|
10
10
|
import { lifecycleRetryInstruction } from "../harness-runtime/lib/delegation-instructions.mjs";
|
|
11
|
-
import { CAPACITY_POLICY, MAX_OVERLOAD_RETRIES, overloadExhausted } from "../harness-runtime/lib/provider-overload-policy.mjs";
|
|
11
|
+
import { RECOVERY_POLICY as CAPACITY_POLICY, MAX_OVERLOAD_RETRIES, recoveryExhausted as overloadExhausted } from "../harness-runtime/lib/provider-overload-policy.mjs";
|
|
12
12
|
/** Pin retained Session loading and its first acknowledgement Turn, never a general fence bypass. */
|
|
13
13
|
export function prepareRunRecoveryDispatch(context, input) {
|
|
14
14
|
if (!/^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/.test(input.operationId) || !path.isAbsolute(input.stateDir))
|
|
@@ -16,6 +16,16 @@ function assertContextRelocation(receipt) {
|
|
|
16
16
|
|| !Array.isArray(receipt.path_mapping) || receipt.path_mapping.some(item => !item || typeof item.from !== "string" || typeof item.to !== "string" || !path.isAbsolute(item.from) || !path.isAbsolute(item.to)))
|
|
17
17
|
throw new AppError("context_relocation_invalid", "Stage context relocation lacks a verified import binding", 2);
|
|
18
18
|
}
|
|
19
|
+
function relocateDeclaredPath(source, receipts) {
|
|
20
|
+
let mapped = source;
|
|
21
|
+
for (const receipt of receipts) {
|
|
22
|
+
assertContextRelocation(receipt);
|
|
23
|
+
const selected = [...receipt.path_mapping].sort((a, b) => b.from.length - a.from.length).find(item => mapped === item.from || mapped.startsWith(`${item.from}${path.sep}`));
|
|
24
|
+
if (selected)
|
|
25
|
+
mapped = path.join(selected.to, path.relative(selected.from, mapped));
|
|
26
|
+
}
|
|
27
|
+
return mapped;
|
|
28
|
+
}
|
|
19
29
|
/** Physical packet locators may move; accepted decision/provenance blocks may not. */
|
|
20
30
|
export function projectPacketLocators(text, receipts) {
|
|
21
31
|
receipts.forEach(assertContextRelocation);
|
|
@@ -89,13 +99,7 @@ export function renderRetainedStageContext(input) {
|
|
|
89
99
|
|| !/^[a-f0-9]{64}$/.test(input.workspaceView.source_sha256) || !/^[a-f0-9]{64}$/.test(input.workspaceView.copy_sha256)))
|
|
90
100
|
throw new AppError("context_workspace_view_invalid", "Stage context workspace view lacks its bound review-copy proof", 2);
|
|
91
101
|
const mapPath = (source, workspaceSource = true) => {
|
|
92
|
-
let mapped = source;
|
|
93
|
-
for (const receipt of input.receipts) {
|
|
94
|
-
assertContextRelocation(receipt);
|
|
95
|
-
const selected = [...receipt.path_mapping].sort((a, b) => b.from.length - a.from.length).find(item => mapped === item.from || mapped.startsWith(`${item.from}${path.sep}`));
|
|
96
|
-
if (selected)
|
|
97
|
-
mapped = path.join(selected.to, path.relative(selected.from, mapped));
|
|
98
|
-
}
|
|
102
|
+
let mapped = relocateDeclaredPath(source, input.receipts);
|
|
99
103
|
const view = input.workspaceView;
|
|
100
104
|
if (view && workspaceSource && (mapped === view.from || mapped.startsWith(`${view.from}${path.sep}`)))
|
|
101
105
|
mapped = path.join(view.to, path.relative(view.from, mapped));
|
|
@@ -149,6 +153,7 @@ export function loadExternalStageContextBytes(input) {
|
|
|
149
153
|
return { value, sourcePath, materializedSha256, bytes };
|
|
150
154
|
}
|
|
151
155
|
export function prepareExternalStageContext(input) {
|
|
156
|
+
verifyImmutableContextSources(input.loaded.value);
|
|
152
157
|
const destination = externalStageContextDestination(input);
|
|
153
158
|
if (!fs.existsSync(destination))
|
|
154
159
|
prepareOutputFile(destination);
|
|
@@ -206,6 +211,7 @@ export function applyExternalStageContext(input) {
|
|
|
206
211
|
return installed;
|
|
207
212
|
}
|
|
208
213
|
export function renderExternalStageContext(input) {
|
|
214
|
+
verifyImmutableContextSources(input.loaded.value);
|
|
209
215
|
const value = input.loaded.value;
|
|
210
216
|
const sources = value.sources ?? [];
|
|
211
217
|
const taskInput = value.task_input ?? [];
|
|
@@ -251,7 +257,7 @@ function validateContext(value, expectedStage) {
|
|
|
251
257
|
for (const item of value[key]) {
|
|
252
258
|
const valid = key === "accepted_decisions" ? text(item) || object(item) && (text(item.id) || text(item.statement)) && [item.id, item.statement].every(field => field === undefined || text(field))
|
|
253
259
|
: object(item) && text(item.role) && (key === "dynamic_roles" ? item.reason === undefined || text(item.reason)
|
|
254
|
-
: text(item.path) && (key === "sources" ? text(item.reason) && (item.required === undefined || typeof item.required === "boolean") && (item.root === undefined || typeof item.root === "string" && ["project", "workspace", "run"].includes(item.root)) : item.sha256 === undefined || text(item.sha256)));
|
|
260
|
+
: text(item.path) && (key === "sources" ? text(item.reason) && (item.sha256 === undefined || typeof item.sha256 === "string" && /^[a-f0-9]{64}$/.test(item.sha256)) && (item.required === undefined || typeof item.required === "boolean") && (item.root === undefined || typeof item.root === "string" && ["project", "workspace", "run"].includes(item.root)) : item.sha256 === undefined || text(item.sha256)));
|
|
255
261
|
if (!valid)
|
|
256
262
|
throw new AppError("validation", `Invalid stage context ${key} item`, 2, { parameter: key });
|
|
257
263
|
}
|
|
@@ -261,4 +267,46 @@ function validateContext(value, expectedStage) {
|
|
|
261
267
|
throw new AppError("validation", `Stage context ${key} must be a nonempty string`, 2);
|
|
262
268
|
}
|
|
263
269
|
}
|
|
270
|
+
function verifyImmutableContextSources(value) {
|
|
271
|
+
for (const source of value.sources ?? []) {
|
|
272
|
+
if (!source.sha256)
|
|
273
|
+
continue; // Ordinary mutable project documents are not frozen.
|
|
274
|
+
try {
|
|
275
|
+
const info = fs.lstatSync(source.path);
|
|
276
|
+
if (!info.isFile() || info.isSymbolicLink() || info.size > 2 * 1024 * 1024 || sha256(fs.readFileSync(source.path)) !== source.sha256)
|
|
277
|
+
throw new Error("changed");
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
throw new AppError("context_source_checksum_mismatch", "Immutable stage source is unavailable or changed", 2, { role: source.role });
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** Only an accepted CODE context may bind a diagnostic capability to checks. */
|
|
285
|
+
export function browserCheckCapabilityEnvironment(context, runId, runHome) {
|
|
286
|
+
const row = context.db.get("SELECT project_id, index_json FROM runs WHERE id = ?", [runId]);
|
|
287
|
+
const ref = row ? JSON.parse(row.index_json).execution_profile?.stage_context_inputs?.code : null;
|
|
288
|
+
if (!ref)
|
|
289
|
+
return {};
|
|
290
|
+
const file = path.resolve(runHome, ref.path), relative = path.relative(runHome, file);
|
|
291
|
+
if (relative.startsWith('..') || path.isAbsolute(relative))
|
|
292
|
+
throw new AppError('context_source_checksum_mismatch', 'Stage context escaped RUN', 2);
|
|
293
|
+
const loaded = loadExternalStageContext({ file, expectedSha256: ref.sha256, stage: 'code' });
|
|
294
|
+
const sources = loaded.value.sources?.filter(item => item.role === 'browser_environment_capabilities' && item.root === 'run') ?? [];
|
|
295
|
+
if (!sources.length)
|
|
296
|
+
return {};
|
|
297
|
+
if (sources.length !== 1)
|
|
298
|
+
throw new AppError('context_source_checksum_mismatch', 'Browser capability source is ambiguous', 2);
|
|
299
|
+
const source = { ...sources[0], path: relocateDeclaredPath(sources[0].path, runContextRelocations(context, row.project_id, runId)) };
|
|
300
|
+
const filename = path.basename(source.path), namedHash = filename.match(/^browser-capabilities(?:-([a-f0-9]{64}))?\.json$/);
|
|
301
|
+
const expected = path.join(runHome, 'environment', filename);
|
|
302
|
+
let owned = false;
|
|
303
|
+
try {
|
|
304
|
+
owned = fs.realpathSync(source.path) === path.join(fs.realpathSync(runHome), 'environment', filename);
|
|
305
|
+
}
|
|
306
|
+
catch { /* Missing proof is not a foreign host lookup. */ }
|
|
307
|
+
if (!source.sha256 || !namedHash || namedHash[1] && namedHash[1] !== source.sha256 || path.resolve(source.path) !== expected || !owned)
|
|
308
|
+
throw new AppError('context_source_checksum_mismatch', 'Browser capability lacks its RUN binding', 2);
|
|
309
|
+
verifyImmutableContextSources({ ...loaded.value, sources: [source] });
|
|
310
|
+
return { DD_FLOW_BROWSER_CAPABILITY_PATH: source.path, DD_FLOW_BROWSER_CAPABILITY_SHA256: source.sha256 };
|
|
311
|
+
}
|
|
264
312
|
function sha256(value) { return crypto.createHash("sha256").update(value).digest("hex"); }
|
|
@@ -305,7 +305,7 @@ export async function reconcileVnextFanout(context, input) {
|
|
|
305
305
|
continue;
|
|
306
306
|
}
|
|
307
307
|
const link = active[0];
|
|
308
|
-
if (renderNativeChildFollowupInstruction(String(value.harness_id),
|
|
308
|
+
if (renderNativeChildFollowupInstruction(String(value.harness_id), child) && eligibleProviderChildOverload(child, value.parent_session_id)) {
|
|
309
309
|
issues.push({ code: "child_capacity_pending", work_id: link.work_id, session_id: child.session_id });
|
|
310
310
|
continue;
|
|
311
311
|
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_id": "dd-flow/verification-components@1",
|
|
3
|
+
"scope": "technical-matrix-publication-not-native-execution",
|
|
4
|
+
"matrix": {
|
|
5
|
+
"roots": [
|
|
6
|
+
"services/verification-matrix.js",
|
|
7
|
+
"services/stage-report-renderer.js",
|
|
8
|
+
"services/accepted-intent.js",
|
|
9
|
+
"services/check-runner-evidence.js",
|
|
10
|
+
"services/check-runner-proof.js"
|
|
11
|
+
],
|
|
12
|
+
"runner_proof_contract": "dd-flow/check-runner-proof@1",
|
|
13
|
+
"files": [
|
|
14
|
+
"cli/command-inputs.js",
|
|
15
|
+
"cli/command-metadata.js",
|
|
16
|
+
"cli/command-option-descriptions.js",
|
|
17
|
+
"cli/help.js",
|
|
18
|
+
"cli/input-preparation.js",
|
|
19
|
+
"cli/native-hook-preparation.js",
|
|
20
|
+
"domain/contracts.js",
|
|
21
|
+
"domain/diagnostic-aspects.js",
|
|
22
|
+
"domain/diagnostic-flows.js",
|
|
23
|
+
"domain/entity-ids.js",
|
|
24
|
+
"domain/flow-contract.js",
|
|
25
|
+
"domain/session-coverage.js",
|
|
26
|
+
"domain/stage-catalog.js",
|
|
27
|
+
"domain/stage-handler-identities.js",
|
|
28
|
+
"domain/validation.js",
|
|
29
|
+
"protocol/local-files.js",
|
|
30
|
+
"runtime/context.js",
|
|
31
|
+
"schemas/merge-result.schema.json",
|
|
32
|
+
"schemas/merge-stage-report-legacy-0.4.2.schema.json",
|
|
33
|
+
"schemas/merge-stage-report.schema.json",
|
|
34
|
+
"schemas/plan-aspect-map.schema.json",
|
|
35
|
+
"schemas/plan-review-decision.schema.json",
|
|
36
|
+
"schemas/plan-review-result.schema.json",
|
|
37
|
+
"schemas/plan-stage-report.schema.json",
|
|
38
|
+
"schemas/protocol-dashboard-data.schema.json",
|
|
39
|
+
"schemas/protocol-plan.schema.json",
|
|
40
|
+
"schemas/run-control-receipt.schema.json",
|
|
41
|
+
"schemas/run-control-request.schema.json",
|
|
42
|
+
"schemas/run-engine-binding.schema.json",
|
|
43
|
+
"schemas/stage-finish-input.schema.json",
|
|
44
|
+
"schemas/stage-prompt.schema.json",
|
|
45
|
+
"schemas/stage-report.schema.json",
|
|
46
|
+
"schemas/stage-start-response.schema.json",
|
|
47
|
+
"services/accepted-intent.js",
|
|
48
|
+
"services/audit.js",
|
|
49
|
+
"services/branch-context.js",
|
|
50
|
+
"services/build-info.js",
|
|
51
|
+
"services/canon.js",
|
|
52
|
+
"services/check-environment.js",
|
|
53
|
+
"services/check-runner-evidence.js",
|
|
54
|
+
"services/check-runner-proof.js",
|
|
55
|
+
"services/cli-operation-classifier.js",
|
|
56
|
+
"services/cli-upgrade-allowlist.js",
|
|
57
|
+
"services/code-checks.js",
|
|
58
|
+
"services/command-context.js",
|
|
59
|
+
"services/config.js",
|
|
60
|
+
"services/descriptor-coordinator-session.js",
|
|
61
|
+
"services/descriptor-root-work.js",
|
|
62
|
+
"services/descriptor-run-settlement.js",
|
|
63
|
+
"services/descriptor-run-start.js",
|
|
64
|
+
"services/descriptor-stage-coordinator.js",
|
|
65
|
+
"services/descriptor-stage-settlement.js",
|
|
66
|
+
"services/descriptor-stage-start.js",
|
|
67
|
+
"services/diagnostic-evidence.js",
|
|
68
|
+
"services/diagnostic-report-publication.js",
|
|
69
|
+
"services/diagnostic-report.js",
|
|
70
|
+
"services/diagnostic-snapshot.js",
|
|
71
|
+
"services/diagnostic-stage-handlers.js",
|
|
72
|
+
"services/diagnostic-stage-results.js",
|
|
73
|
+
"services/diagnostic-work-batch.js",
|
|
74
|
+
"services/diagnostic-work-collection.js",
|
|
75
|
+
"services/diagnostic-work-registration.js",
|
|
76
|
+
"services/diagnostic-work-results.js",
|
|
77
|
+
"services/engines.js",
|
|
78
|
+
"services/eval-snapshots.js",
|
|
79
|
+
"services/execution-bundles.js",
|
|
80
|
+
"services/execution-policy.js",
|
|
81
|
+
"services/executor-onboarding.js",
|
|
82
|
+
"services/external-work-launch.js",
|
|
83
|
+
"services/flow-descriptors.js",
|
|
84
|
+
"services/flow-guidance.js",
|
|
85
|
+
"services/frozen-engine.js",
|
|
86
|
+
"services/generic-execution.js",
|
|
87
|
+
"services/hook-memory-routing.js",
|
|
88
|
+
"services/hook-recovery-guard.js",
|
|
89
|
+
"services/hook-session-observation.js",
|
|
90
|
+
"services/hooks.js",
|
|
91
|
+
"services/hybrid-contracts.js",
|
|
92
|
+
"services/hybrid-digest.js",
|
|
93
|
+
"services/ids.js",
|
|
94
|
+
"services/installation-lock.js",
|
|
95
|
+
"services/installed-flow-source.js",
|
|
96
|
+
"services/lanes.js",
|
|
97
|
+
"services/lifecycle-command.js",
|
|
98
|
+
"services/lifecycle-contract.js",
|
|
99
|
+
"services/lifecycle-invocations.js",
|
|
100
|
+
"services/managed-daemon-binding.js",
|
|
101
|
+
"services/managed-processes.js",
|
|
102
|
+
"services/memory-accepted-composition.js",
|
|
103
|
+
"services/memory-baseline-preservation.js",
|
|
104
|
+
"services/memory-completed-correction-wave.js",
|
|
105
|
+
"services/memory-compose-handler.js",
|
|
106
|
+
"services/memory-composition-acceptance.js",
|
|
107
|
+
"services/memory-composition-graph.js",
|
|
108
|
+
"services/memory-composition-registration.js",
|
|
109
|
+
"services/memory-composition-work-custody.js",
|
|
110
|
+
"services/memory-composition-work-results.js",
|
|
111
|
+
"services/memory-corrected-review-acceptance.js",
|
|
112
|
+
"services/memory-corrected-review-batch.js",
|
|
113
|
+
"services/memory-corrected-review-findings.js",
|
|
114
|
+
"services/memory-corrected-review-inputs.js",
|
|
115
|
+
"services/memory-corrected-review-projection.js",
|
|
116
|
+
"services/memory-corrected-review-receipt.js",
|
|
117
|
+
"services/memory-corrected-review-registration.js",
|
|
118
|
+
"services/memory-correction-check-receipt.js",
|
|
119
|
+
"services/memory-correction-input-owner.js",
|
|
120
|
+
"services/memory-custody-snapshot.js",
|
|
121
|
+
"services/memory-discover-handler.js",
|
|
122
|
+
"services/memory-finish-evidence.js",
|
|
123
|
+
"services/memory-finish-handler.js",
|
|
124
|
+
"services/memory-finish-integration.js",
|
|
125
|
+
"services/memory-finish-readiness.js",
|
|
126
|
+
"services/memory-git-integration.js",
|
|
127
|
+
"services/memory-historical-corrected-review.js",
|
|
128
|
+
"services/memory-historical-original-review.js",
|
|
129
|
+
"services/memory-historical-repair-registration.js",
|
|
130
|
+
"services/memory-historical-second-review.js",
|
|
131
|
+
"services/memory-init-bootstrap-readiness.js",
|
|
132
|
+
"services/memory-init-engine-release.js",
|
|
133
|
+
"services/memory-init-git-policy.js",
|
|
134
|
+
"services/memory-init-lint-capability.js",
|
|
135
|
+
"services/memory-init-preflight.js",
|
|
136
|
+
"services/memory-init-project-bootstrap.js",
|
|
137
|
+
"services/memory-init-request-candidate.js",
|
|
138
|
+
"services/memory-init-request-input.js",
|
|
139
|
+
"services/memory-init-resource-storage.js",
|
|
140
|
+
"services/memory-init-run-allocation.js",
|
|
141
|
+
"services/memory-init-startup-custody.js",
|
|
142
|
+
"services/memory-init-storage.js",
|
|
143
|
+
"services/memory-init-worktrunk-capability.js",
|
|
144
|
+
"services/memory-layer-publication.js",
|
|
145
|
+
"services/memory-layer.js",
|
|
146
|
+
"services/memory-lint-config.js",
|
|
147
|
+
"services/memory-native-review-copy.js",
|
|
148
|
+
"services/memory-normal-flow-entry.js",
|
|
149
|
+
"services/memory-ordinary-defaults.js",
|
|
150
|
+
"services/memory-permissions.js",
|
|
151
|
+
"services/memory-preflight-bootstrap-custody.js",
|
|
152
|
+
"services/memory-preflight-handler.js",
|
|
153
|
+
"services/memory-repair-current-view.js",
|
|
154
|
+
"services/memory-repair-document-delta.js",
|
|
155
|
+
"services/memory-repair-history.js",
|
|
156
|
+
"services/memory-repair-physical-binding.js",
|
|
157
|
+
"services/memory-repair-publication-files.js",
|
|
158
|
+
"services/memory-repair-publication-intent.js",
|
|
159
|
+
"services/memory-repair-publication-plan.js",
|
|
160
|
+
"services/memory-repair-publication-source.js",
|
|
161
|
+
"services/memory-repair-publication.js",
|
|
162
|
+
"services/memory-repair-registration.js",
|
|
163
|
+
"services/memory-repair-work-baseline.js",
|
|
164
|
+
"services/memory-repair-work-completion.js",
|
|
165
|
+
"services/memory-repair-work-custody.js",
|
|
166
|
+
"services/memory-repair-work-results.js",
|
|
167
|
+
"services/memory-repair-workspace.js",
|
|
168
|
+
"services/memory-repair-writer-copy.js",
|
|
169
|
+
"services/memory-result-binding.js",
|
|
170
|
+
"services/memory-retained-review-authority.js",
|
|
171
|
+
"services/memory-retained-review-results.js",
|
|
172
|
+
"services/memory-retained-second-baseline.js",
|
|
173
|
+
"services/memory-retained-second-repairs.js",
|
|
174
|
+
"services/memory-review-acceptance.js",
|
|
175
|
+
"services/memory-review-correction-plan.js",
|
|
176
|
+
"services/memory-review-handler.js",
|
|
177
|
+
"services/memory-review-inputs.js",
|
|
178
|
+
"services/memory-review-limits.js",
|
|
179
|
+
"services/memory-review-receipt.js",
|
|
180
|
+
"services/memory-review-registration.js",
|
|
181
|
+
"services/memory-review-work-custody.js",
|
|
182
|
+
"services/memory-review-work-input.js",
|
|
183
|
+
"services/memory-review-work-results.js",
|
|
184
|
+
"services/memory-second-corrected-review-inputs.js",
|
|
185
|
+
"services/memory-second-correction-plan.js",
|
|
186
|
+
"services/memory-second-repair-baseline.js",
|
|
187
|
+
"services/memory-second-repair-launch.js",
|
|
188
|
+
"services/memory-second-repair-registration.js",
|
|
189
|
+
"services/memory-second-repair-source.js",
|
|
190
|
+
"services/memory-second-review-acceptance.js",
|
|
191
|
+
"services/memory-source-observations.js",
|
|
192
|
+
"services/memory-stage-dispatch.js",
|
|
193
|
+
"services/memory-stage-results.js",
|
|
194
|
+
"services/memory-tool-probe.js",
|
|
195
|
+
"services/memory-upgrade-analysis-handler.js",
|
|
196
|
+
"services/memory-upgrade-bootstrap-readiness.js",
|
|
197
|
+
"services/memory-upgrade-evidence.js",
|
|
198
|
+
"services/memory-upgrade-inventory.js",
|
|
199
|
+
"services/memory-upgrade-publication-custody.js",
|
|
200
|
+
"services/memory-upgrade-publication.js",
|
|
201
|
+
"services/memory-upgrade-selection.js",
|
|
202
|
+
"services/memory-upgrade-storage-readiness.js",
|
|
203
|
+
"services/memory-verification-acceptance.js",
|
|
204
|
+
"services/memory-verification-checks.js",
|
|
205
|
+
"services/memory-verification-receipt.js",
|
|
206
|
+
"services/memory-verify-handler.js",
|
|
207
|
+
"services/memory-work-result-json.js",
|
|
208
|
+
"services/memory-work-result-preparation.js",
|
|
209
|
+
"services/merge-queue.js",
|
|
210
|
+
"services/migrations.js",
|
|
211
|
+
"services/native-session-control.js",
|
|
212
|
+
"services/operator-profiles.js",
|
|
213
|
+
"services/plan-runtime.js",
|
|
214
|
+
"services/portable-refs.js",
|
|
215
|
+
"services/project-registry.js",
|
|
216
|
+
"services/project-summary.js",
|
|
217
|
+
"services/projects.js",
|
|
218
|
+
"services/prompt-delivery.js",
|
|
219
|
+
"services/protocol-lifecycle.js",
|
|
220
|
+
"services/protocols.js",
|
|
221
|
+
"services/provider-capacity.js",
|
|
222
|
+
"services/recovery-snapshot-database.js",
|
|
223
|
+
"services/release-archive.js",
|
|
224
|
+
"services/release-cache.js",
|
|
225
|
+
"services/release-download.js",
|
|
226
|
+
"services/release-envelope.js",
|
|
227
|
+
"services/release-manifest.js",
|
|
228
|
+
"services/release-payload.js",
|
|
229
|
+
"services/release-source.js",
|
|
230
|
+
"services/repair-intents.js",
|
|
231
|
+
"services/repair-receipt.js",
|
|
232
|
+
"services/review-copy.js",
|
|
233
|
+
"services/review-deferral.js",
|
|
234
|
+
"services/run-control-receipt.js",
|
|
235
|
+
"services/run-control.js",
|
|
236
|
+
"services/run-controller-state.js",
|
|
237
|
+
"services/run-engine-bindings.js",
|
|
238
|
+
"services/run-observations.js",
|
|
239
|
+
"services/run-projection.js",
|
|
240
|
+
"services/run-recovery-guard.js",
|
|
241
|
+
"services/run-recovery.js",
|
|
242
|
+
"services/run-start-custody.js",
|
|
243
|
+
"services/runs.js",
|
|
244
|
+
"services/runtime-budget.js",
|
|
245
|
+
"services/runtime-command.js",
|
|
246
|
+
"services/schema-validation.js",
|
|
247
|
+
"services/scope-writer-cleanup.js",
|
|
248
|
+
"services/session-identity.js",
|
|
249
|
+
"services/sessions.js",
|
|
250
|
+
"services/setup.js",
|
|
251
|
+
"services/stage-context.js",
|
|
252
|
+
"services/stage-handlers.js",
|
|
253
|
+
"services/stage-lifecycle.js",
|
|
254
|
+
"services/stage-pause.js",
|
|
255
|
+
"services/stage-report-renderer.js",
|
|
256
|
+
"services/stage-work-graph.js",
|
|
257
|
+
"services/tooling.js",
|
|
258
|
+
"services/usage.js",
|
|
259
|
+
"services/verification-matrix.js",
|
|
260
|
+
"services/version-status.js",
|
|
261
|
+
"services/vnext-code-review.js",
|
|
262
|
+
"services/vnext-code.js",
|
|
263
|
+
"services/vnext-contracts.js",
|
|
264
|
+
"services/vnext-execution-profile.js",
|
|
265
|
+
"services/vnext-fanout.js",
|
|
266
|
+
"services/vnext-merge.js",
|
|
267
|
+
"services/vnext-plan-review.js",
|
|
268
|
+
"services/vnext-plan.js",
|
|
269
|
+
"services/vnext-protocolize.js",
|
|
270
|
+
"services/vnext-specify.js",
|
|
271
|
+
"services/vnext-workspace-policy.js",
|
|
272
|
+
"services/work-registry.js",
|
|
273
|
+
"services/workspace-bootstrap.js",
|
|
274
|
+
"services/workspace-files.js",
|
|
275
|
+
"services/worktrees.js",
|
|
276
|
+
"shared/entity-references.js",
|
|
277
|
+
"shared/errors.js",
|
|
278
|
+
"shared/json.js",
|
|
279
|
+
"storage/agent-output.js",
|
|
280
|
+
"storage/database.js",
|
|
281
|
+
"storage/foreign-key-transaction.js",
|
|
282
|
+
"storage/immutable-input.js",
|
|
283
|
+
"storage/import-guard.js",
|
|
284
|
+
"storage/native-cleanup.js",
|
|
285
|
+
"storage/paths.js",
|
|
286
|
+
"storage/projection-lock.js",
|
|
287
|
+
"storage/work-references.js",
|
|
288
|
+
"storage/writer-contract.js"
|
|
289
|
+
],
|
|
290
|
+
"dependencies": [
|
|
291
|
+
"ajv/dist/2020.js",
|
|
292
|
+
"ajv/dist/ajv.js",
|
|
293
|
+
"semver",
|
|
294
|
+
"shell-quote",
|
|
295
|
+
"smol-toml",
|
|
296
|
+
"yaml"
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
}
|