harnery 0.45.0 → 0.45.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/dist/commander.js +0 -1
- package/dist/commands/files.d.ts +2 -2
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +4 -7
- package/dist/commands/servers.d.ts.map +1 -1
- package/dist/commands/servers.js +17 -11
- package/dist/commands/tunnel.d.ts +0 -15
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +153 -453
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +6 -45
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +0 -18
- package/dist/core/agents/live-authority-v3.d.ts +0 -1
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +0 -11
- package/dist/core/agents/live-lifecycle-v3.d.ts +2 -4
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
- package/dist/core/agents/live-lifecycle-v3.js +7 -28
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +14 -25
- package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-writer.js +0 -5
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +2 -7
- package/dist/core/agents/state/proc-start.d.ts +20 -31
- package/dist/core/agents/state/proc-start.d.ts.map +1 -1
- package/dist/core/agents/state/proc-start.js +37 -70
- package/dist/core/agents/state/service-process.d.ts +61 -0
- package/dist/core/agents/state/service-process.d.ts.map +1 -0
- package/dist/core/agents/state/service-process.js +143 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +70 -180
- package/dist/core/artifacts/activity.d.ts +4 -1
- package/dist/core/artifacts/activity.d.ts.map +1 -1
- package/dist/core/artifacts/activity.js +8 -2
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
- package/dist/core/artifacts/delivery-card.js +1 -2
- package/dist/core/artifacts/index.d.ts.map +1 -1
- package/dist/core/artifacts/index.js +38 -12
- package/dist/core/context/index.d.ts +6 -4
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +194 -256
- package/dist/core/context/observation.d.ts +9 -9
- package/dist/core/context/observation.d.ts.map +1 -1
- package/dist/core/context/observation.js +37 -6
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +0 -29
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +0 -1
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +0 -7
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +64 -77
- package/dist/core/events/v3/runtime-build.d.ts +14 -0
- package/dist/core/events/v3/runtime-build.d.ts.map +1 -1
- package/dist/core/events/v3/runtime-build.js +44 -0
- package/dist/core/governor/index.d.ts +2 -1
- package/dist/core/governor/index.d.ts.map +1 -1
- package/dist/core/governor/index.js +2 -1
- package/dist/core/governor/service-read.d.ts +3 -10
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +10 -94
- package/dist/core/governor/service.d.ts +3 -7
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +17 -182
- package/dist/core/hooks/cli.js +78 -48
- package/dist/core/hooks/resolve/owner.js +2 -2
- package/dist/core/resources/sampler.js +2 -2
- package/dist/core/resources/service-status.d.ts +2 -14
- package/dist/core/resources/service-status.d.ts.map +1 -1
- package/dist/core/resources/service-status.js +3 -23
- package/dist/core/resources/service.d.ts +3 -7
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +12 -101
- package/dist/core/resources/status.d.ts.map +1 -1
- package/dist/core/resources/status.js +3 -2
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +9 -2
- package/dist/core/servers/index.d.ts +11 -10
- package/dist/core/servers/index.d.ts.map +1 -1
- package/dist/core/servers/index.js +82 -192
- package/dist/core/servers/tunnels.d.ts +3 -5
- package/dist/core/servers/tunnels.d.ts.map +1 -1
- package/dist/core/servers/tunnels.js +2 -45
- package/dist/core/storage/durable-history.js +56 -22
- package/dist/core/storage/segments.d.ts.map +1 -1
- package/dist/core/storage/segments.js +73 -17
- package/dist/core/supervisor/service.d.ts +4 -7
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +23 -122
- package/dist/core/supervisor/services.js +2 -2
- package/dist/core/supervisor/status.d.ts +3 -17
- package/dist/core/supervisor/status.d.ts.map +1 -1
- package/dist/core/supervisor/status.js +7 -70
- package/dist/core/work/state.js +7 -7
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +23 -66
- package/dist/core/workflow/index.d.ts +3 -4
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -2
- package/dist/core/workflow/live-session-v3.d.ts +0 -6
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +5 -126
- package/dist/core/workflow/proof.d.ts +4 -4
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +34 -86
- package/dist/core/workflow/resume-lock.d.ts +17 -0
- package/dist/core/workflow/resume-lock.d.ts.map +1 -0
- package/dist/core/workflow/resume-lock.js +158 -0
- package/dist/core/workflow/run-state.d.ts +0 -21
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +3 -174
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +0 -19
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +0 -13
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +0 -19
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
- package/dist/core/workflow/spawn-opencode.js +0 -14
- package/dist/core/workflow/types.d.ts +11 -54
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.d.ts +4 -0
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +1 -1
- package/dist/core/workflow/workspaces/local-git.js +91 -210
- package/dist/core/workflow/workspaces/ownership.d.ts +0 -7
- package/dist/core/workflow/workspaces/ownership.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/ownership.js +3 -130
- package/dist/core/workflow/workspaces/reclaim.d.ts +4 -7
- package/dist/core/workflow/workspaces/reclaim.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/reclaim.js +0 -4
- package/dist/core/workflow/workspaces/recovery.d.ts +1 -1
- package/dist/core/workflow/workspaces/recovery.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/recovery.js +1 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +1 -4
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +0 -4
- package/dist/lib/tunnel/state.d.ts +6 -13
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +12 -58
- package/package.json +1 -6
- package/src/commander.ts +0 -10
- package/src/commands/files.ts +5 -13
- package/src/commands/servers.ts +23 -12
- package/src/commands/tunnel.ts +166 -533
- package/src/commands/workflow.ts +8 -58
- package/src/core/agents/coord-client.ts +0 -20
- package/src/core/agents/live-authority-v3.ts +0 -17
- package/src/core/agents/live-lifecycle-v3.ts +14 -52
- package/src/core/agents/state/heartbeat-writer.ts +12 -29
- package/src/core/agents/state/live-coordination-writer.ts +0 -29
- package/src/core/agents/state/pidmap.ts +2 -15
- package/src/core/agents/state/proc-start.ts +41 -69
- package/src/core/agents/state/service-process.ts +217 -0
- package/src/core/agents/state/stale-sweep.ts +82 -247
- package/src/core/artifacts/activity.ts +9 -2
- package/src/core/artifacts/delivery-card.ts +1 -7
- package/src/core/artifacts/index.ts +45 -12
- package/src/core/context/index.ts +207 -272
- package/src/core/context/observation.ts +40 -9
- package/src/core/events/v3/authority-outbox.ts +0 -56
- package/src/core/events/v3/producers/coordination-recorder.ts +0 -15
- package/src/core/events/v3/producers/recorder.ts +68 -94
- package/src/core/events/v3/runtime-build.ts +62 -0
- package/src/core/governor/index.ts +1 -2
- package/src/core/governor/service-read.ts +15 -114
- package/src/core/governor/service.ts +36 -220
- package/src/core/hooks/cli.ts +85 -47
- package/src/core/hooks/resolve/owner.ts +2 -2
- package/src/core/resources/sampler.ts +3 -2
- package/src/core/resources/service-status.ts +6 -35
- package/src/core/resources/service.ts +23 -133
- package/src/core/resources/status.ts +3 -2
- package/src/core/semantic/service.ts +8 -2
- package/src/core/servers/index.ts +86 -228
- package/src/core/servers/tunnels.ts +3 -55
- package/src/core/storage/durable-history.ts +52 -20
- package/src/core/storage/segments.ts +79 -17
- package/src/core/supervisor/service.ts +33 -155
- package/src/core/supervisor/services.ts +2 -2
- package/src/core/supervisor/status.ts +10 -85
- package/src/core/work/state.ts +7 -7
- package/src/core/workflow/engine.ts +22 -74
- package/src/core/workflow/index.ts +2 -13
- package/src/core/workflow/live-session-v3.ts +5 -146
- package/src/core/workflow/proof.ts +40 -104
- package/src/core/workflow/resume-lock.ts +179 -0
- package/src/core/workflow/run-state.ts +3 -207
- package/src/core/workflow/spawn-claude.ts +0 -18
- package/src/core/workflow/spawn-codex.ts +0 -13
- package/src/core/workflow/spawn-cursor.ts +0 -18
- package/src/core/workflow/spawn-opencode.ts +0 -14
- package/src/core/workflow/types.ts +11 -41
- package/src/core/workflow/workspaces/leases.ts +1 -1
- package/src/core/workflow/workspaces/local-git.ts +120 -239
- package/src/core/workflow/workspaces/ownership.ts +3 -158
- package/src/core/workflow/workspaces/reclaim.ts +3 -9
- package/src/core/workflow/workspaces/recovery.ts +1 -1
- package/src/core/workflow/workspaces/state.ts +1 -5
- package/src/lib/identities/assume.ts +0 -4
- package/src/lib/tunnel/state.ts +15 -70
- package/dist/commands/turn-rollback.d.ts +0 -5
- package/dist/commands/turn-rollback.d.ts.map +0 -1
- package/dist/commands/turn-rollback.js +0 -76
- package/dist/core/agents/state/process-handle.d.ts +0 -26
- package/dist/core/agents/state/process-handle.d.ts.map +0 -1
- package/dist/core/agents/state/process-handle.js +0 -121
- package/dist/core/agents/state/unchanged-file.d.ts +0 -44
- package/dist/core/agents/state/unchanged-file.d.ts.map +0 -1
- package/dist/core/agents/state/unchanged-file.js +0 -390
- package/dist/core/events/v3/generation-custody.d.ts +0 -5
- package/dist/core/events/v3/generation-custody.d.ts.map +0 -1
- package/dist/core/events/v3/generation-custody.js +0 -50
- package/dist/core/turn-rollback/content.d.ts +0 -53
- package/dist/core/turn-rollback/content.d.ts.map +0 -1
- package/dist/core/turn-rollback/content.js +0 -396
- package/dist/core/turn-rollback/index.d.ts +0 -72
- package/dist/core/turn-rollback/index.d.ts.map +0 -1
- package/dist/core/turn-rollback/index.js +0 -443
- package/dist/core/workflow/failure-evidence.d.ts +0 -16
- package/dist/core/workflow/failure-evidence.d.ts.map +0 -1
- package/dist/core/workflow/failure-evidence.js +0 -114
- package/dist/core/workflow/recovery-audit.d.ts +0 -30
- package/dist/core/workflow/recovery-audit.d.ts.map +0 -1
- package/dist/core/workflow/recovery-audit.js +0 -116
- package/src/commands/turn-rollback.ts +0 -111
- package/src/core/agents/state/process-handle.ts +0 -165
- package/src/core/agents/state/unchanged-file.ts +0 -456
- package/src/core/events/v3/generation-custody.ts +0 -59
- package/src/core/turn-rollback/content.ts +0 -499
- package/src/core/turn-rollback/index.ts +0 -580
- package/src/core/workflow/failure-evidence.ts +0 -141
- package/src/core/workflow/recovery-audit.ts +0 -181
|
@@ -37,10 +37,10 @@ import { freezeWorkflowAttemptContext } from "./attempt-context.js";
|
|
|
37
37
|
import { probeBilling } from "./billing.js";
|
|
38
38
|
import { stableDigest } from "./durable-record.js";
|
|
39
39
|
import { evidencePreflightError } from "./evidence-preflight.js";
|
|
40
|
-
import {
|
|
41
|
-
import { endWorkflowChildSessionV3, recordWorkflowChildTerminalFailureV3, startWorkflowChildSessionV3, } from "./live-session-v3.js";
|
|
40
|
+
import { endWorkflowChildSessionV3, startWorkflowChildSessionV3 } from "./live-session-v3.js";
|
|
42
41
|
import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
|
|
43
|
-
import { acquireWorkflowResumeLease
|
|
42
|
+
import { acquireWorkflowResumeLease } from "./resume-lock.js";
|
|
43
|
+
import { assertWorkflowRunResumable, assertWorkflowScriptUnchanged, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
44
44
|
import { assertProjectionWithinWorkspace, resolveGitGrantRoots } from "./sandbox-projection.js";
|
|
45
45
|
import { normalizeWorkflowSpecialists, resolveSpecialistAssignment } from "./specialists.js";
|
|
46
46
|
import { appendWorkflowTranscriptEvent } from "./transcript.js";
|
|
@@ -865,40 +865,23 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
865
865
|
},
|
|
866
866
|
});
|
|
867
867
|
agentProof.access = access;
|
|
868
|
-
let childGenerationId;
|
|
869
868
|
let recordAgentEnd;
|
|
870
869
|
const finalizeChild = () => {
|
|
871
870
|
try {
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
// Result publication is the resume-cache boundary, after canonical custody.
|
|
871
|
+
// Record the canonical terminal first. agent.end is the resume-cache
|
|
872
|
+
// boundary, so a child whose end was not recorded never reports success.
|
|
873
|
+
endWorkflowChildSessionV3({
|
|
874
|
+
coordRoot: opts.coordRoot,
|
|
875
|
+
instanceId: childInstanceId(runId, id),
|
|
876
|
+
runId,
|
|
877
|
+
agentId: id,
|
|
878
|
+
adapter,
|
|
879
|
+
cleanExit: agentProof.status === "succeeded",
|
|
880
|
+
});
|
|
883
881
|
recordAgentEnd?.();
|
|
884
882
|
}
|
|
885
883
|
catch (error) {
|
|
886
|
-
|
|
887
|
-
try {
|
|
888
|
-
if (childGenerationId)
|
|
889
|
-
recordWorkflowChildTerminalFailureV3({
|
|
890
|
-
coordRoot: opts.coordRoot,
|
|
891
|
-
instanceId: childInstanceId(runId, id),
|
|
892
|
-
runId,
|
|
893
|
-
agentId: id,
|
|
894
|
-
adapter,
|
|
895
|
-
expectedGenerationId: childGenerationId,
|
|
896
|
-
reason,
|
|
897
|
-
});
|
|
898
|
-
}
|
|
899
|
-
catch (visibilityError) {
|
|
900
|
-
reason += `; blocked lifecycle recording failed: ${visibilityError.message}`;
|
|
901
|
-
}
|
|
884
|
+
const reason = `V3 terminal recording failed: ${error.message}`;
|
|
902
885
|
const failure = new Error(agentProof.error ? `${agentProof.error}; ${reason}` : reason, {
|
|
903
886
|
cause: error,
|
|
904
887
|
});
|
|
@@ -930,7 +913,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
930
913
|
// Headless children do not reliably fire adapter hooks. The engine owns
|
|
931
914
|
// their canonical V3 start so every dispatched child has an auditable
|
|
932
915
|
// generation before it begins work.
|
|
933
|
-
|
|
916
|
+
startWorkflowChildSessionV3({
|
|
934
917
|
coordRoot: opts.coordRoot,
|
|
935
918
|
instanceId: childInstanceId(runId, id),
|
|
936
919
|
runId,
|
|
@@ -939,13 +922,9 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
939
922
|
label,
|
|
940
923
|
model: agentOpts.model,
|
|
941
924
|
});
|
|
942
|
-
if (!child.v3_generation_id)
|
|
943
|
-
throw new Error("workflow_child_v3_generation_missing");
|
|
944
|
-
childGenerationId = child.v3_generation_id;
|
|
945
925
|
let attemptPrompt = dispatchPrompt;
|
|
946
926
|
let last = null;
|
|
947
927
|
let agentCostUsd = 0;
|
|
948
|
-
let informativeAttempt;
|
|
949
928
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
950
929
|
last = await spawner({
|
|
951
930
|
prompt: attemptPrompt,
|
|
@@ -967,29 +946,15 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
967
946
|
agentCostUsd += last.costUsd ?? 0;
|
|
968
947
|
costUsd += last.costUsd ?? 0;
|
|
969
948
|
if (!last.ok) {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
effect: { state: "unknown" },
|
|
977
|
-
partial_output: informativeAttempt.partial_output,
|
|
978
|
-
}
|
|
979
|
-
: observed;
|
|
980
|
-
transcript("agent.attempt_failed", {
|
|
981
|
-
id,
|
|
982
|
-
attempt,
|
|
983
|
-
error: last.error,
|
|
984
|
-
failure_evidence: observed,
|
|
985
|
-
result_digest: digestResult(last.text, "text"),
|
|
986
|
-
text: last.text,
|
|
987
|
-
});
|
|
988
|
-
if (!canRetryFailedSpawn({ ...last, failureEvidence: agentProof.failure_evidence }))
|
|
949
|
+
transcript("agent.attempt_failed", { id, attempt, error: last.error });
|
|
950
|
+
// ADR 0046: an environment failure (the binary was absent) cannot be
|
|
951
|
+
// helped by retrying an unchanged environment, so stop the in-agent
|
|
952
|
+
// retry too — not just the outer attempt/replan budget. An upstream
|
|
953
|
+
// refusal keeps retrying here: the vendor may recover mid-loop.
|
|
954
|
+
if (last.class === "environment")
|
|
989
955
|
break;
|
|
990
|
-
continue;
|
|
956
|
+
continue; // spawn-level failure: retry with the original prompt
|
|
991
957
|
}
|
|
992
|
-
informativeAttempt = observeSpawnFailure({}, last.text, "final_message");
|
|
993
958
|
if (!agentOpts.schema) {
|
|
994
959
|
agentProof.status = "succeeded";
|
|
995
960
|
agentProof.cost_usd =
|
|
@@ -1030,14 +995,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1030
995
|
}, "json", parsed.value);
|
|
1031
996
|
return parsed.value;
|
|
1032
997
|
}
|
|
1033
|
-
|
|
1034
|
-
transcript("agent.schema_retry", {
|
|
1035
|
-
id,
|
|
1036
|
-
attempt,
|
|
1037
|
-
problems,
|
|
1038
|
-
rejected_text: last.text,
|
|
1039
|
-
result_digest: digestResult(last.text, "text"),
|
|
1040
|
-
});
|
|
998
|
+
transcript("agent.schema_retry", { id, attempt, problems });
|
|
1041
999
|
// Keep the original cache identity while making the actual output
|
|
1042
1000
|
// contract explicit. A full bounded copy of the rejected value lets the
|
|
1043
1001
|
// child repair omissions instead of reconstructing an unseen object.
|
|
@@ -1076,7 +1034,6 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1076
1034
|
finalizeChild();
|
|
1077
1035
|
}
|
|
1078
1036
|
finally {
|
|
1079
|
-
// A slot is disposable; unresolved custody remains visible and failed.
|
|
1080
1037
|
release();
|
|
1081
1038
|
}
|
|
1082
1039
|
}
|
|
@@ -4,10 +4,9 @@ export { assertWorkflowRunId, createWorkflowApproval, listWorkflowApprovals, rea
|
|
|
4
4
|
export { freezeWorkflowAttemptContext, isCanonicalWorkflowAttemptContext, normalizeWorkflowAttemptContext, } from "./attempt-context.js";
|
|
5
5
|
export { runWorkflow, WorkflowParkedError, WorkflowRunError } from "./engine.js";
|
|
6
6
|
export { buildWorkflowProof, createEvidenceRecord, deriveRunFailureClass, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
|
|
7
|
-
export
|
|
8
|
-
export {
|
|
9
|
-
export
|
|
10
|
-
export { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, recoverWorkflowResumeLease, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
7
|
+
export { acquireWorkflowResumeLease } from "./resume-lock.js";
|
|
8
|
+
export type { WorkflowRunManifest } from "./run-state.js";
|
|
9
|
+
export { assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
11
10
|
export { isUpstreamFailureText, vendorFailureText } from "./spawn-failure.js";
|
|
12
11
|
export type { AcceptanceCriterion, AcceptanceResult, AcceptanceStatus, AcceptanceSummary, AdapterEvidenceCapability, AdapterEvidenceCoverage, AdapterName, AgentOpts, EngineOpts, EvidenceKind, EvidenceSource, EvidenceStatus, ResultDigest, RunReport, Spawner, SpawnFailureClass, SpawnRequest, SpawnResult, StageSchema, WorkflowAgentProof, WorkflowApprovalMode, WorkflowAttemptContext, WorkflowAttemptFailureCause, WorkflowAttemptPriorContext, WorkflowAttemptUnresolvedCriterion, WorkflowContext, WorkflowDiagnosticAdmissionConfig, WorkflowDiagnosticAdmissionObservation, WorkflowDiagnosticAdmissionProof, WorkflowEvidenceInput, WorkflowEvidenceRecord, WorkflowMeta, WorkflowModule, WorkflowPolicyProof, WorkflowProof, WorkflowProofUnknown, WorkflowRepoEvidence, WorkflowRepoSnapshot, WorkflowRunStatus, WorkflowSpecialistProfile, WorkflowWorkContext, } from "./types.js";
|
|
13
12
|
export { WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION, WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION, WORKFLOW_PROOF_SCHEMA_VERSION, WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION, } from "./types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4CAA4C,EAC5C,KAAK,uCAAuC,EAC5C,kCAAkC,EAClC,KAAK,kCAAkC,GACxC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,gBAAgB,EAChB,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,4BAA4B,EAC5B,iCAAiC,EACjC,+BAA+B,GAChC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AACpB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ export { assertWorkflowRunId, createWorkflowApproval, listWorkflowApprovals, rea
|
|
|
3
3
|
export { freezeWorkflowAttemptContext, isCanonicalWorkflowAttemptContext, normalizeWorkflowAttemptContext, } from "./attempt-context.js";
|
|
4
4
|
export { runWorkflow, WorkflowParkedError, WorkflowRunError } from "./engine.js";
|
|
5
5
|
export { buildWorkflowProof, createEvidenceRecord, deriveRunFailureClass, digestResult, normalizeWorkflowMeta, readWorkflowProof, renderWorkflowProof, rollupAcceptance, writeWorkflowProof, } from "./proof.js";
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
6
|
+
export { acquireWorkflowResumeLease } from "./resume-lock.js";
|
|
7
|
+
export { assertWorkflowRunResumable, assertWorkflowScriptUnchanged, readWorkflowRunManifest, WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION, workflowRunManifestPath, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
8
8
|
export { isUpstreamFailureText, vendorFailureText } from "./spawn-failure.js";
|
|
9
9
|
export { WORKFLOW_ATTEMPT_CONTEXT_SCHEMA_VERSION, WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION, WORKFLOW_PROOF_SCHEMA_VERSION, WORKFLOW_WORK_CONTEXT_SCHEMA_VERSION, } from "./types.js";
|
|
10
10
|
export { applyIntegration, assertWorkspaceLifecycleTransition, cancelWorkspace, cleanupWorkspace, createLocalGitWorktreeProvider, deriveWorkspaceLifecycle, IntegrationPrepareParkedError, inspectWorkflowWorkspace, isWorkspaceLifecycleState, listWorkflowWorkspaceInspections, prepareIntegration, probeLocalGitWorktreeProvider, readWorkflowWorkspaceStatus, renderWorkflowWorkspaceStatus, validateProviderEventChain, WORKSPACE_BINDING_SCHEMA_VERSION, WORKSPACE_RECEIPT_SCHEMA_VERSION, } from "./workspaces/index.js";
|
|
@@ -14,12 +14,6 @@ export declare function startWorkflowChildSessionV3(input: WorkflowChildSessionV
|
|
|
14
14
|
/** Record the authoritative terminal before removing the disposable coordination cache. */
|
|
15
15
|
export declare function endWorkflowChildSessionV3(input: WorkflowChildSessionV3Input & {
|
|
16
16
|
cleanExit: boolean;
|
|
17
|
-
expectedGenerationId: string;
|
|
18
|
-
}): void;
|
|
19
|
-
/** Persist unresolved terminal custody only for the generation this dispatch owns. */
|
|
20
|
-
export declare function recordWorkflowChildTerminalFailureV3(input: WorkflowChildSessionV3Input & {
|
|
21
|
-
expectedGenerationId: string;
|
|
22
|
-
reason: string;
|
|
23
17
|
}): void;
|
|
24
18
|
export { stableScopeId } from "./scope-id.js";
|
|
25
19
|
//# sourceMappingURL=live-session-v3.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live-session-v3.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/live-session-v3.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"live-session-v3.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/live-session-v3.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,SAAS,EAEf,MAAM,qCAAqC,CAAC;AAY7C,MAAM,WAAW,2BAA2B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,8FAA8F;AAC9F,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,2BAA2B,GAAG,SAAS,CAiDzF;AAED,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,2BAA2B,GAAG;IAAE,SAAS,EAAE,OAAO,CAAA;CAAE,GAC1D,IAAI,CAmBN;AAgBD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { existsSync, linkSync, readdirSync, readFileSync, renameSync, unlinkSync } from "node:fs";
|
|
3
|
-
import { basename, dirname } from "node:path";
|
|
4
1
|
import { adapterFromPlatform } from "../adapter.js";
|
|
5
|
-
import {
|
|
2
|
+
import { recordLiveTaskChangeV3 } from "../agents/live-authority-v3.js";
|
|
6
3
|
import { endSessionExplicitV3 } from "../agents/session-finalizer-v3.js";
|
|
7
|
-
import {
|
|
8
|
-
import { readHeartbeat, setIdentityCache, } from "../agents/state/heartbeat-writer.js";
|
|
4
|
+
import { clearCoordinationCache, setIdentityCache, } from "../agents/state/heartbeat-writer.js";
|
|
9
5
|
import { readLiveCoordinationRow } from "../agents/state/live-coordination-view.js";
|
|
10
6
|
import { ensureLiveCoordinationHeartbeat } from "../agents/state/live-coordination-writer.js";
|
|
11
7
|
import { assignName } from "../agents/state/names.js";
|
|
12
8
|
import { coordFreshnessSeconds } from "../config.js";
|
|
13
9
|
import { ensureEventLedgerV3 } from "../events/v3/bootstrap.js";
|
|
14
|
-
import {
|
|
15
|
-
import { withGenerationCustodyV3 } from "../events/v3/generation-custody.js";
|
|
16
|
-
import { liveInstanceIdV3, recordLiveHookSignalV3, resolveLiveEventLedgerRouteV3, } from "../events/v3/live-routing.js";
|
|
17
|
-
import { readHookProducerStateV3 } from "../events/v3/producers/recorder.js";
|
|
18
|
-
import { fsyncParentDirectory } from "./durable-record.js";
|
|
10
|
+
import { recordLiveHookSignalV3, resolveLiveEventLedgerRouteV3, } from "../events/v3/live-routing.js";
|
|
19
11
|
import { stableScopeId } from "./scope-id.js";
|
|
20
12
|
/** Start a headless workflow child through the same canonical V3 producer as native hooks. */
|
|
21
13
|
export function startWorkflowChildSessionV3(input) {
|
|
@@ -62,38 +54,13 @@ export function startWorkflowChildSessionV3(input) {
|
|
|
62
54
|
const projected = readLiveCoordinationRow(input.coordRoot, input.instanceId);
|
|
63
55
|
if (!projected)
|
|
64
56
|
throw new Error("workflow_child_v3_projection_missing");
|
|
65
|
-
const own = readHookProducerStateV3(input.coordRoot, adapter, sessionId);
|
|
66
|
-
if (!own || own.terminal || own.generation_id !== projected.v3_generation_id) {
|
|
67
|
-
throw new Error("workflow_child_v3_start_generation_changed");
|
|
68
|
-
}
|
|
69
57
|
return projected;
|
|
70
58
|
}
|
|
71
59
|
/** Record the authoritative terminal before removing the disposable coordination cache. */
|
|
72
60
|
export function endWorkflowChildSessionV3(input) {
|
|
73
|
-
withGenerationCustodyV3(input.coordRoot, [liveInstanceIdV3(input.instanceId)], () => endExpectedChild(input));
|
|
74
|
-
}
|
|
75
|
-
function endExpectedChild(input) {
|
|
76
61
|
requireV3Route(input.coordRoot);
|
|
77
|
-
const view = requireAuthoritySafeCoordinationViewV3(readCoordinationViewV3(input.coordRoot));
|
|
78
|
-
const instanceId = liveInstanceIdV3(input.instanceId);
|
|
79
|
-
const current = view.instances[instanceId];
|
|
80
|
-
const terminal = view.terminal_generations[input.expectedGenerationId];
|
|
81
|
-
if (terminal?.instance_id === instanceId)
|
|
82
|
-
recoverHeldCaches(input);
|
|
83
|
-
if (current && current.generation_id !== input.expectedGenerationId) {
|
|
84
|
-
throw new Error("workflow_child_v3_generation_changed");
|
|
85
|
-
}
|
|
86
|
-
if (!current) {
|
|
87
|
-
if (!terminal || terminal.instance_id !== instanceId)
|
|
88
|
-
throw new Error("workflow_child_v3_generation_missing");
|
|
89
|
-
if (terminal.terminal?.outcome !== (input.cleanExit ? "succeeded" : "failed")) {
|
|
90
|
-
throw new Error("workflow_child_v3_terminal_outcome_changed");
|
|
91
|
-
}
|
|
92
|
-
clearExpectedCache(input);
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
62
|
const row = readLiveCoordinationRow(input.coordRoot, input.instanceId);
|
|
96
|
-
if (!row?.v3_instance_id || row.v3_generation_id
|
|
63
|
+
if (!row?.v3_instance_id || !row.v3_generation_id) {
|
|
97
64
|
throw new Error("workflow_child_v3_generation_missing");
|
|
98
65
|
}
|
|
99
66
|
const result = endSessionExplicitV3({
|
|
@@ -106,95 +73,7 @@ function endExpectedChild(input) {
|
|
|
106
73
|
if (result.state !== "recorded" && result.state !== "already_ended") {
|
|
107
74
|
throw new Error(`workflow_child_v3_end_failed:${result.state}${"reason" in result ? `:${result.reason}` : ""}`);
|
|
108
75
|
}
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
/** Persist unresolved terminal custody only for the generation this dispatch owns. */
|
|
112
|
-
export function recordWorkflowChildTerminalFailureV3(input) {
|
|
113
|
-
withGenerationCustodyV3(input.coordRoot, [liveInstanceIdV3(input.instanceId)], () => {
|
|
114
|
-
const row = readLiveCoordinationRow(input.coordRoot, input.instanceId);
|
|
115
|
-
if (!row || row.v3_generation_id !== input.expectedGenerationId)
|
|
116
|
-
return;
|
|
117
|
-
recordLiveLifecycleChangeV3({
|
|
118
|
-
coordRoot: input.coordRoot,
|
|
119
|
-
owner: input.instanceId,
|
|
120
|
-
nativeSessionId: input.sessionId ?? input.instanceId,
|
|
121
|
-
adapter: workflowAdapter(input.adapter),
|
|
122
|
-
expectedGenerationId: input.expectedGenerationId,
|
|
123
|
-
state: "blocked",
|
|
124
|
-
reason: input.reason,
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
function heldPrefix(input) {
|
|
129
|
-
if (!/^gen_[a-zA-Z0-9._-]{1,128}$/.test(input.expectedGenerationId))
|
|
130
|
-
throw new Error("workflow_child_v3_generation_invalid");
|
|
131
|
-
return `${basename(heartbeatPath(input.coordRoot, input.instanceId))}.terminal-${input.expectedGenerationId}-`;
|
|
132
|
-
}
|
|
133
|
-
function recoverHeldCaches(input) {
|
|
134
|
-
const path = heartbeatPath(input.coordRoot, input.instanceId);
|
|
135
|
-
if (!existsSync(dirname(path)))
|
|
136
|
-
return;
|
|
137
|
-
const prefix = heldPrefix(input);
|
|
138
|
-
for (const name of readdirSync(dirname(path)).filter((value) => value.startsWith(prefix))) {
|
|
139
|
-
finishHeldCache(`${dirname(path)}/${name}`, path, input.expectedGenerationId);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
function clearExpectedCache(input) {
|
|
143
|
-
recoverHeldCaches(input);
|
|
144
|
-
if (readHeartbeat(input.coordRoot, input.instanceId)?.v3_generation_id !==
|
|
145
|
-
input.expectedGenerationId)
|
|
146
|
-
return;
|
|
147
|
-
const path = heartbeatPath(input.coordRoot, input.instanceId);
|
|
148
|
-
const held = `${dirname(path)}/${heldPrefix(input)}${randomUUID()}`;
|
|
149
|
-
try {
|
|
150
|
-
// A unique held name pins the actual bytes atomically. Checking before
|
|
151
|
-
// unlink alone could consume a replacement published at this boundary.
|
|
152
|
-
renameSync(path, held);
|
|
153
|
-
fsyncParentDirectory(path);
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
if (error.code === "ENOENT")
|
|
157
|
-
return;
|
|
158
|
-
throw error;
|
|
159
|
-
}
|
|
160
|
-
finishHeldCache(held, path, input.expectedGenerationId);
|
|
161
|
-
}
|
|
162
|
-
function finishHeldCache(held, path, expectedGenerationId) {
|
|
163
|
-
let removed = false;
|
|
164
|
-
let cleanupFailed = false;
|
|
165
|
-
let cleanupError;
|
|
166
|
-
try {
|
|
167
|
-
const cache = JSON.parse(readFileSync(held, "utf8"));
|
|
168
|
-
if (cache.v3_generation_id === expectedGenerationId) {
|
|
169
|
-
unlinkSync(held);
|
|
170
|
-
fsyncParentDirectory(held);
|
|
171
|
-
removed = true;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
catch (error) {
|
|
175
|
-
cleanupFailed = true;
|
|
176
|
-
cleanupError = error;
|
|
177
|
-
}
|
|
178
|
-
if (!removed) {
|
|
179
|
-
try {
|
|
180
|
-
// Never overwrite a later publication. Keep the held evidence when
|
|
181
|
-
// another cache already owns the live name.
|
|
182
|
-
linkSync(held, path);
|
|
183
|
-
fsyncParentDirectory(path);
|
|
184
|
-
unlinkSync(held);
|
|
185
|
-
fsyncParentDirectory(held);
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
if (error.code !== "EEXIST") {
|
|
189
|
-
if (cleanupFailed) {
|
|
190
|
-
throw new AggregateError([cleanupError, error], `workflow_child_v3_cache_cleanup_and_restore_failed: ${String(cleanupError)}; restoration: ${String(error)}`);
|
|
191
|
-
}
|
|
192
|
-
throw error;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (cleanupFailed)
|
|
197
|
-
throw cleanupError;
|
|
76
|
+
clearCoordinationCache(input.coordRoot, input.instanceId);
|
|
198
77
|
}
|
|
199
78
|
function requireV3Route(coordRoot) {
|
|
200
79
|
let route = resolveLiveEventLedgerRouteV3(coordRoot);
|
|
@@ -72,12 +72,12 @@ export declare function digestResult(value: unknown, kind?: "text" | "json"): Re
|
|
|
72
72
|
* attempt was informative about the work — charge it. This also keeps a
|
|
73
73
|
* resumed run whose earlier segment did real work from being written off by
|
|
74
74
|
* a later environment failure.
|
|
75
|
-
* 3.
|
|
76
|
-
*
|
|
77
|
-
*
|
|
75
|
+
* 3. Otherwise, among the failed agents, environment wins over upstream: a
|
|
76
|
+
* missing binary means nothing ran at all, and it is the operator-chosen
|
|
77
|
+
* hard stop.
|
|
78
78
|
* 4. Anything else is undefined ⇒ a charged work failure, exactly as today.
|
|
79
79
|
*/
|
|
80
|
-
export declare function deriveRunFailureClass(status: "succeeded" | "failed", agents: readonly Pick<WorkflowAgentProof, "status" | "class"
|
|
80
|
+
export declare function deriveRunFailureClass(status: "succeeded" | "failed", agents: readonly Pick<WorkflowAgentProof, "status" | "class">[]): SpawnFailureClass | undefined;
|
|
81
81
|
export declare function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProof;
|
|
82
82
|
export declare function writeWorkflowProof(path: string, proof: WorkflowProof): void;
|
|
83
83
|
export declare function readWorkflowProof(coordRoot: string, runId: string): WorkflowProof;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { repoComparisonProblems } from "../context/observation.js";
|
|
5
5
|
import { DIAGNOSTIC_ADVICE_SCHEMA_VERSION } from "../diagnostics/contract.js";
|
|
6
6
|
import { policyDigest } from "../policy/index.js";
|
|
7
7
|
import { isCanonicalWorkflowAttemptContext } from "./attempt-context.js";
|
|
8
8
|
import { stableDigest, writeImmutableJson } from "./durable-record.js";
|
|
9
|
-
import { failureEvidenceAllowsUncharged, isSpawnFailureEvidence } from "./failure-evidence.js";
|
|
10
9
|
import { readWorkflowRunManifest } from "./run-state.js";
|
|
11
10
|
import { EVIDENCE_KINDS, WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION, WORKFLOW_PROOF_SCHEMA_VERSION, } from "./types.js";
|
|
12
11
|
import { isCanonicalWorkflowWorkContext } from "./work-context.js";
|
|
@@ -127,18 +126,15 @@ export function digestResult(value, kind) {
|
|
|
127
126
|
* attempt was informative about the work — charge it. This also keeps a
|
|
128
127
|
* resumed run whose earlier segment did real work from being written off by
|
|
129
128
|
* a later environment failure.
|
|
130
|
-
* 3.
|
|
131
|
-
*
|
|
132
|
-
*
|
|
129
|
+
* 3. Otherwise, among the failed agents, environment wins over upstream: a
|
|
130
|
+
* missing binary means nothing ran at all, and it is the operator-chosen
|
|
131
|
+
* hard stop.
|
|
133
132
|
* 4. Anything else is undefined ⇒ a charged work failure, exactly as today.
|
|
134
133
|
*/
|
|
135
134
|
export function deriveRunFailureClass(status, agents) {
|
|
136
135
|
if (status !== "failed")
|
|
137
136
|
return undefined;
|
|
138
|
-
if (agents.
|
|
139
|
-
agents.some((agent) => agent.status !== "failed" ||
|
|
140
|
-
(agent.class !== "environment" && agent.class !== "upstream") ||
|
|
141
|
-
!failureEvidenceAllowsUncharged(agent.failure_evidence))) {
|
|
137
|
+
if (agents.some((agent) => agent.status === "succeeded" || agent.status === "cached")) {
|
|
142
138
|
return undefined;
|
|
143
139
|
}
|
|
144
140
|
const failed = agents.filter((agent) => agent.status === "failed");
|
|
@@ -267,10 +263,6 @@ export function readWorkflowProof(coordRoot, runId) {
|
|
|
267
263
|
proof.run.class !== "environment" &&
|
|
268
264
|
proof.run.class !== "upstream" &&
|
|
269
265
|
proof.run.class !== "decision") ||
|
|
270
|
-
!Array.isArray(proof.agents) ||
|
|
271
|
-
proof.agents.some((agent) => !agent ||
|
|
272
|
-
typeof agent !== "object" ||
|
|
273
|
-
(agent.failure_evidence !== undefined && !isSpawnFailureEvidence(agent.failure_evidence))) ||
|
|
274
266
|
(proof.run.work_context !== undefined &&
|
|
275
267
|
(!proof.run.work_item_id ||
|
|
276
268
|
proof.run.work_context.id !== proof.run.work_item_id ||
|
|
@@ -284,13 +276,8 @@ export function readWorkflowProof(coordRoot, runId) {
|
|
|
284
276
|
!isWorkspaceExecutionEvidence(proof.execution, runId, proof.run.status))) {
|
|
285
277
|
throw new Error(`workflow proof at ${path} has an unsupported or mismatched schema`);
|
|
286
278
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
proof.repository.after.dirty_paths_truncated ||
|
|
290
|
-
!proof.repository.before.branch?.trim() ||
|
|
291
|
-
!proof.repository.after.branch?.trim() ||
|
|
292
|
-
!proof.repository.before.head?.trim() ||
|
|
293
|
-
!proof.repository.after.head?.trim()) {
|
|
279
|
+
// Packets written before observation checks may carry unproven drift.
|
|
280
|
+
if (repoProblems(proof.repository).length > 0) {
|
|
294
281
|
proof.repository = buildRepoEvidence(proof.repository.before, proof.repository.after);
|
|
295
282
|
proof.unknowns = proof.unknowns.filter((item) => item.code !== "repository_drift_incomplete");
|
|
296
283
|
proof.unknowns.push({
|
|
@@ -392,26 +379,16 @@ export function renderWorkflowProof(proof) {
|
|
|
392
379
|
`${observation.advice.assessment.recommended_action}; action none`
|
|
393
380
|
: "admission: shadow not needed; no real child dispatch");
|
|
394
381
|
}
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
!proof.repository.after.dirty_paths_truncated &&
|
|
399
|
-
proof.repository.before.branch?.trim() &&
|
|
400
|
-
proof.repository.after.branch?.trim() &&
|
|
401
|
-
proof.repository.before.head?.trim() &&
|
|
402
|
-
proof.repository.after.head?.trim()
|
|
403
|
-
? proof.repository
|
|
404
|
-
: buildRepoEvidence(proof.repository.before, proof.repository.after);
|
|
405
|
-
const drift = repo.drift;
|
|
406
|
-
if (!comparable) {
|
|
407
|
-
lines.push(`repository: drift unknown. ${drift.note}`);
|
|
382
|
+
const problems = repoProblems(proof.repository);
|
|
383
|
+
if (problems.length > 0) {
|
|
384
|
+
lines.push(`repository: drift unknown. ${unverifiedDrift(problems)}`);
|
|
408
385
|
}
|
|
409
386
|
else {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
387
|
+
const { before, after, drift } = proof.repository;
|
|
388
|
+
lines.push(`repository: branch ${before.branch} -> ${after.branch}; ` +
|
|
389
|
+
`HEAD ${short(before.head)} -> ${short(after.head)}; ` +
|
|
390
|
+
`${drift.dirty_paths_added?.length ?? "unknown"} dirty added, ` +
|
|
391
|
+
`${drift.dirty_paths_cleared?.length ?? "unknown"} cleared`);
|
|
415
392
|
}
|
|
416
393
|
if (proof.unknowns.length > 0) {
|
|
417
394
|
lines.push(`unknowns: ${proof.unknowns.length}`);
|
|
@@ -424,8 +401,8 @@ export function renderWorkflowProof(proof) {
|
|
|
424
401
|
function buildRepoEvidence(beforeRaw, afterRaw) {
|
|
425
402
|
const before = normalizeRepoSnapshot(beforeRaw);
|
|
426
403
|
const after = normalizeRepoSnapshot(afterRaw);
|
|
427
|
-
const
|
|
428
|
-
if (
|
|
404
|
+
const problems = repoProblems({ before, after });
|
|
405
|
+
if (problems.length > 0) {
|
|
429
406
|
return {
|
|
430
407
|
source: "engine",
|
|
431
408
|
before,
|
|
@@ -437,46 +414,37 @@ function buildRepoEvidence(beforeRaw, afterRaw) {
|
|
|
437
414
|
dirty_paths_cleared: null,
|
|
438
415
|
dirty_paths_retained: null,
|
|
439
416
|
incomplete: true,
|
|
440
|
-
note:
|
|
417
|
+
note: unverifiedDrift(problems),
|
|
441
418
|
},
|
|
442
419
|
};
|
|
443
420
|
}
|
|
444
|
-
const pathsComparable = !before.dirty_paths_truncated && !after.dirty_paths_truncated;
|
|
445
|
-
const branchKnown = Boolean(before.branch && after.branch);
|
|
446
|
-
const headKnown = Boolean(before.head && after.head);
|
|
447
421
|
const beforeDirty = new Set(before.dirty_paths);
|
|
448
422
|
const afterDirty = new Set(after.dirty_paths);
|
|
449
423
|
const retained = after.dirty_paths.filter((path) => beforeDirty.has(path));
|
|
450
|
-
const
|
|
451
|
-
...(!pathsComparable
|
|
452
|
-
? ["Dirty-path drift is unknown because a snapshot list was truncated."]
|
|
453
|
-
: []),
|
|
454
|
-
...(!branchKnown ? ["Branch drift is unknown because a snapshot has no branch."] : []),
|
|
455
|
-
...(!headKnown ? ["HEAD drift is unknown because a snapshot has no HEAD."] : []),
|
|
456
|
-
...(pathsComparable && retained.length > 0
|
|
457
|
-
? ["Snapshots cannot prove whether retained dirty paths changed during the run."]
|
|
458
|
-
: []),
|
|
459
|
-
];
|
|
460
|
-
const incomplete = notes.length > 0;
|
|
424
|
+
const incomplete = retained.length > 0;
|
|
461
425
|
return {
|
|
462
426
|
source: "engine",
|
|
463
427
|
before,
|
|
464
428
|
after,
|
|
465
429
|
drift: {
|
|
466
|
-
branch_changed:
|
|
467
|
-
head_changed:
|
|
468
|
-
dirty_paths_added:
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
dirty_paths_cleared: pathsComparable
|
|
472
|
-
? before.dirty_paths.filter((path) => !afterDirty.has(path))
|
|
473
|
-
: null,
|
|
474
|
-
dirty_paths_retained: pathsComparable ? retained : null,
|
|
430
|
+
branch_changed: before.branch !== after.branch,
|
|
431
|
+
head_changed: before.head !== after.head,
|
|
432
|
+
dirty_paths_added: after.dirty_paths.filter((path) => !beforeDirty.has(path)),
|
|
433
|
+
dirty_paths_cleared: before.dirty_paths.filter((path) => !afterDirty.has(path)),
|
|
434
|
+
dirty_paths_retained: retained,
|
|
475
435
|
incomplete,
|
|
476
|
-
note: incomplete
|
|
436
|
+
note: incomplete
|
|
437
|
+
? "Snapshots cannot prove whether retained dirty paths changed during the run."
|
|
438
|
+
: undefined,
|
|
477
439
|
},
|
|
478
440
|
};
|
|
479
441
|
}
|
|
442
|
+
function repoProblems(repository) {
|
|
443
|
+
return repoComparisonProblems(repository.before, repository.after, ["before", "after"]);
|
|
444
|
+
}
|
|
445
|
+
function unverifiedDrift(problems) {
|
|
446
|
+
return `Repository drift could not be verified: ${problems.join("; ")}. Re-check before editing.`;
|
|
447
|
+
}
|
|
480
448
|
function normalizeRepoSnapshot(snapshot) {
|
|
481
449
|
return {
|
|
482
450
|
cwd: snapshot.cwd,
|
|
@@ -491,26 +459,6 @@ function normalizeRepoSnapshot(snapshot) {
|
|
|
491
459
|
dirty_paths_truncated: snapshot.dirty_paths_truncated,
|
|
492
460
|
};
|
|
493
461
|
}
|
|
494
|
-
function snapshotFailure(label, snapshot) {
|
|
495
|
-
return `${label} snapshot is ${snapshot.observation}${snapshot.observation_detail ? ` (${snapshot.observation_detail})` : ""}`;
|
|
496
|
-
}
|
|
497
|
-
function repoComparisonProblem(before, after) {
|
|
498
|
-
if (!observationsComparable(before, after)) {
|
|
499
|
-
return [
|
|
500
|
-
...(before.observation !== "ok" ? [snapshotFailure("before", before)] : []),
|
|
501
|
-
...(after.observation !== "ok" ? [snapshotFailure("after", after)] : []),
|
|
502
|
-
].join("; ");
|
|
503
|
-
}
|
|
504
|
-
const unknownRoots = [
|
|
505
|
-
...(!before.root || !isAbsolute(before.root) ? ["before"] : []),
|
|
506
|
-
...(!after.root || !isAbsolute(after.root) ? ["after"] : []),
|
|
507
|
-
];
|
|
508
|
-
if (unknownRoots.length > 0)
|
|
509
|
-
return `${unknownRoots.join(" and ")} snapshot repository root is unknown`;
|
|
510
|
-
if (before.root !== after.root)
|
|
511
|
-
return "snapshots name different repository roots";
|
|
512
|
-
return undefined;
|
|
513
|
-
}
|
|
514
462
|
function buildAdapterCoverage(agents, claims, attestations) {
|
|
515
463
|
return [...new Set(agents.map((agent) => agent.adapter))].map((adapter) => {
|
|
516
464
|
const adapterAgents = agents.filter((agent) => agent.adapter === adapter);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type WorkflowResumeOwnerState = "dead" | "live" | "unknown";
|
|
2
|
+
export interface WorkflowResumeLockOwner {
|
|
3
|
+
pid: number;
|
|
4
|
+
host: string;
|
|
5
|
+
created_at: string;
|
|
6
|
+
start_token?: string | null;
|
|
7
|
+
}
|
|
8
|
+
/** Acquire the exclusive lease shared by resume and reclaim. A lock whose
|
|
9
|
+
* same-host owner has exited, or whose PID now names a different process, is
|
|
10
|
+
* retired automatically. Every other existing lock refuses. */
|
|
11
|
+
export declare function acquireWorkflowResumeLease(coordRoot: string, runId: string): () => void;
|
|
12
|
+
export declare function workflowResumeLockPath(coordRoot: string, runId: string): string;
|
|
13
|
+
/** Only a same-host owner can be proven gone: by ESRCH, or by a recorded start
|
|
14
|
+
* token that no longer matches its PID. Foreign and unreadable owners stay live. */
|
|
15
|
+
export declare function workflowResumeOwnerState(owner: WorkflowResumeLockOwner): WorkflowResumeOwnerState;
|
|
16
|
+
export declare function readWorkflowResumeLock(coordRoot: string, runId: string): WorkflowResumeLockOwner | null;
|
|
17
|
+
//# sourceMappingURL=resume-lock.d.ts.map
|