harnery 0.43.0 → 0.45.0
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/README.md +3 -3
- package/dist/commander.js +1 -0
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +41 -48
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +38 -11
- package/dist/commands/diagnostics.d.ts.map +1 -1
- package/dist/commands/diagnostics.js +10 -0
- package/dist/commands/doctor.d.ts +12 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +22 -7
- package/dist/commands/files.d.ts +2 -2
- package/dist/commands/files.d.ts.map +1 -1
- package/dist/commands/files.js +7 -4
- package/dist/commands/governor.js +22 -10
- package/dist/commands/inbox.d.ts +1 -1
- package/dist/commands/inbox.d.ts.map +1 -1
- package/dist/commands/inbox.js +55 -2
- package/dist/commands/rm.d.ts.map +1 -1
- package/dist/commands/rm.js +28 -4
- package/dist/commands/servers.d.ts.map +1 -1
- package/dist/commands/servers.js +26 -17
- package/dist/commands/supervisor.d.ts.map +1 -1
- package/dist/commands/supervisor.js +7 -2
- package/dist/commands/toc.d.ts +14 -0
- package/dist/commands/toc.d.ts.map +1 -1
- package/dist/commands/toc.js +7 -4
- package/dist/commands/tunnel.d.ts +15 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +453 -153
- package/dist/commands/turn-rollback.d.ts +5 -0
- package/dist/commands/turn-rollback.d.ts.map +1 -0
- package/dist/commands/turn-rollback.js +76 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +68 -30
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +18 -0
- package/dist/core/agents/live-authority-v3.d.ts +1 -0
- package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
- package/dist/core/agents/live-authority-v3.js +11 -0
- package/dist/core/agents/live-lifecycle-v3.d.ts +4 -2
- package/dist/core/agents/live-lifecycle-v3.d.ts.map +1 -1
- package/dist/core/agents/live-lifecycle-v3.js +28 -7
- package/dist/core/agents/mailbox.d.ts +9 -8
- package/dist/core/agents/mailbox.d.ts.map +1 -1
- package/dist/core/agents/mailbox.js +24 -17
- package/dist/core/agents/render/prompt-context.d.ts +2 -0
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +8 -12
- package/dist/core/agents/render/session-context.d.ts +2 -8
- package/dist/core/agents/render/session-context.d.ts.map +1 -1
- package/dist/core/agents/render/session-context.js +7 -30
- package/dist/core/agents/rules/stop-hook.js +3 -3
- package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +25 -14
- package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -1
- package/dist/core/agents/state/live-coordination-writer.js +5 -0
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +5 -0
- package/dist/core/agents/state/proc-start.d.ts +19 -1
- package/dist/core/agents/state/proc-start.d.ts.map +1 -1
- package/dist/core/agents/state/proc-start.js +46 -1
- package/dist/core/agents/state/process-handle.d.ts +26 -0
- package/dist/core/agents/state/process-handle.d.ts.map +1 -0
- package/dist/core/agents/state/process-handle.js +121 -0
- package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
- package/dist/core/agents/state/stale-sweep.js +180 -70
- package/dist/core/agents/state/unchanged-file.d.ts +44 -0
- package/dist/core/agents/state/unchanged-file.d.ts.map +1 -0
- package/dist/core/agents/state/unchanged-file.js +390 -0
- package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
- package/dist/core/artifacts/delivery-card.js +2 -1
- package/dist/core/context/index.d.ts +22 -10
- package/dist/core/context/index.d.ts.map +1 -1
- package/dist/core/context/index.js +381 -119
- package/dist/core/context/observation.d.ts +26 -0
- package/dist/core/context/observation.d.ts.map +1 -0
- package/dist/core/context/observation.js +11 -0
- package/dist/core/diagnostics/bundle.d.ts.map +1 -1
- package/dist/core/diagnostics/bundle.js +25 -14
- package/dist/core/diagnostics/path-identity.d.ts +3 -0
- package/dist/core/diagnostics/path-identity.d.ts.map +1 -0
- package/dist/core/diagnostics/path-identity.js +12 -0
- package/dist/core/diagnostics/sanitize.d.ts.map +1 -1
- package/dist/core/diagnostics/sanitize.js +4 -3
- package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
- package/dist/core/events/v3/authority-outbox.js +29 -0
- package/dist/core/events/v3/generation-custody.d.ts +5 -0
- package/dist/core/events/v3/generation-custody.d.ts.map +1 -0
- package/dist/core/events/v3/generation-custody.js +50 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts +1 -0
- package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/coordination-recorder.js +7 -0
- package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
- package/dist/core/events/v3/producers/recorder.js +77 -64
- package/dist/core/governor/planning.d.ts.map +1 -1
- package/dist/core/governor/planning.js +14 -1
- package/dist/core/governor/service-read.d.ts +10 -2
- package/dist/core/governor/service-read.d.ts.map +1 -1
- package/dist/core/governor/service-read.js +105 -22
- package/dist/core/governor/service.d.ts +20 -2
- package/dist/core/governor/service.d.ts.map +1 -1
- package/dist/core/governor/service.js +72 -47
- package/dist/core/hooks/cli.js +33 -5
- package/dist/core/inbox/contract.d.ts +2 -1
- package/dist/core/inbox/contract.d.ts.map +1 -1
- package/dist/core/inbox/index.d.ts +2 -0
- package/dist/core/inbox/index.d.ts.map +1 -1
- package/dist/core/inbox/index.js +2 -0
- package/dist/core/inbox/peer-messages.d.ts +37 -0
- package/dist/core/inbox/peer-messages.d.ts.map +1 -0
- package/dist/core/inbox/peer-messages.js +72 -0
- package/dist/core/inbox/service.d.ts +8 -1
- package/dist/core/inbox/service.d.ts.map +1 -1
- package/dist/core/inbox/service.js +67 -21
- package/dist/core/inbox/targets.d.ts +22 -0
- package/dist/core/inbox/targets.d.ts.map +1 -0
- package/dist/core/inbox/targets.js +108 -0
- package/dist/core/inbox/watcher.js +7 -3
- package/dist/core/journal/index.d.ts.map +1 -1
- package/dist/core/journal/index.js +17 -2
- package/dist/core/resources/contract.d.ts +3 -0
- package/dist/core/resources/contract.d.ts.map +1 -1
- package/dist/core/resources/service-status.d.ts +14 -1
- package/dist/core/resources/service-status.d.ts.map +1 -1
- package/dist/core/resources/service-status.js +23 -13
- package/dist/core/resources/service.d.ts +7 -13
- package/dist/core/resources/service.d.ts.map +1 -1
- package/dist/core/resources/service.js +34 -91
- package/dist/core/resources/status.d.ts +2 -5
- package/dist/core/resources/status.d.ts.map +1 -1
- package/dist/core/resources/status.js +36 -7
- package/dist/core/semantic/service.d.ts.map +1 -1
- package/dist/core/semantic/service.js +2 -9
- package/dist/core/servers/index.d.ts +34 -22
- package/dist/core/servers/index.d.ts.map +1 -1
- package/dist/core/servers/index.js +297 -144
- package/dist/core/servers/tunnels.d.ts +7 -7
- package/dist/core/servers/tunnels.d.ts.map +1 -1
- package/dist/core/servers/tunnels.js +47 -10
- package/dist/core/supervisor/contract.d.ts +12 -0
- package/dist/core/supervisor/contract.d.ts.map +1 -1
- package/dist/core/supervisor/explanations.d.ts.map +1 -1
- package/dist/core/supervisor/explanations.js +2 -1
- package/dist/core/supervisor/findings.d.ts.map +1 -1
- package/dist/core/supervisor/findings.js +54 -9
- package/dist/core/supervisor/service.d.ts +7 -1
- package/dist/core/supervisor/service.d.ts.map +1 -1
- package/dist/core/supervisor/service.js +59 -29
- package/dist/core/supervisor/services.d.ts.map +1 -1
- package/dist/core/supervisor/services.js +22 -1
- package/dist/core/supervisor/status.d.ts +17 -2
- package/dist/core/supervisor/status.d.ts.map +1 -1
- package/dist/core/supervisor/status.js +70 -12
- package/dist/core/supervisor/timeline.d.ts.map +1 -1
- package/dist/core/supervisor/timeline.js +2 -1
- package/dist/core/turn-rollback/content.d.ts +53 -0
- package/dist/core/turn-rollback/content.d.ts.map +1 -0
- package/dist/core/turn-rollback/content.js +396 -0
- package/dist/core/turn-rollback/index.d.ts +72 -0
- package/dist/core/turn-rollback/index.d.ts.map +1 -0
- package/dist/core/turn-rollback/index.js +443 -0
- package/dist/core/work/state.js +7 -7
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +105 -32
- package/dist/core/workflow/failure-evidence.d.ts +16 -0
- package/dist/core/workflow/failure-evidence.d.ts.map +1 -0
- package/dist/core/workflow/failure-evidence.js +114 -0
- package/dist/core/workflow/index.d.ts +5 -3
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +3 -2
- package/dist/core/workflow/live-session-v3.d.ts +6 -0
- package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
- package/dist/core/workflow/live-session-v3.js +126 -5
- package/dist/core/workflow/proof.d.ts +5 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +115 -20
- package/dist/core/workflow/recovery-audit.d.ts +30 -0
- package/dist/core/workflow/recovery-audit.d.ts.map +1 -0
- package/dist/core/workflow/recovery-audit.js +116 -0
- package/dist/core/workflow/run-state.d.ts +20 -1
- package/dist/core/workflow/run-state.d.ts.map +1 -1
- package/dist/core/workflow/run-state.js +141 -32
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +19 -0
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +13 -0
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +19 -0
- package/dist/core/workflow/spawn-opencode.d.ts.map +1 -1
- package/dist/core/workflow/spawn-opencode.js +14 -0
- package/dist/core/workflow/types.d.ts +64 -17
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/index.d.ts +0 -1
- package/dist/core/workflow/workspaces/index.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/index.js +0 -1
- package/dist/core/workflow/workspaces/leases.d.ts +3 -1
- package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/leases.js +30 -16
- package/dist/core/workflow/workspaces/local-git.d.ts +6 -2
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +328 -8
- package/dist/core/workflow/workspaces/ownership.d.ts +11 -0
- package/dist/core/workflow/workspaces/ownership.d.ts.map +1 -0
- package/dist/core/workflow/workspaces/ownership.js +194 -0
- package/dist/core/workflow/workspaces/reclaim.d.ts +40 -0
- package/dist/core/workflow/workspaces/reclaim.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/reclaim.js +14 -0
- package/dist/core/workflow/workspaces/recovery.d.ts +2 -0
- package/dist/core/workflow/workspaces/recovery.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/recovery.js +42 -10
- package/dist/core/workflow/workspaces/state.d.ts +1 -0
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +21 -1
- package/dist/lib/browser/windows-chrome.d.ts +100 -12
- package/dist/lib/browser/windows-chrome.d.ts.map +1 -1
- package/dist/lib/browser/windows-chrome.js +262 -73
- package/dist/lib/docs-links.d.ts.map +1 -1
- package/dist/lib/docs-links.js +45 -2
- package/dist/lib/guarded-remove.d.ts +7 -0
- package/dist/lib/guarded-remove.d.ts.map +1 -1
- package/dist/lib/guarded-remove.js +106 -12
- package/dist/lib/identities/assume.d.ts.map +1 -1
- package/dist/lib/identities/assume.js +4 -0
- package/dist/lib/tunnel/state.d.ts +13 -6
- package/dist/lib/tunnel/state.d.ts.map +1 -1
- package/dist/lib/tunnel/state.js +58 -12
- package/dist/lib/zip/index.d.ts +41 -0
- package/dist/lib/zip/index.d.ts.map +1 -0
- package/dist/lib/zip/index.js +398 -0
- package/package.json +12 -1
- package/src/commander.ts +10 -0
- package/src/commands/agents.ts +54 -63
- package/src/commands/browse.ts +50 -14
- package/src/commands/diagnostics.ts +10 -0
- package/src/commands/doctor.ts +26 -7
- package/src/commands/files.ts +13 -5
- package/src/commands/governor.ts +23 -10
- package/src/commands/inbox.ts +52 -2
- package/src/commands/rm.ts +43 -4
- package/src/commands/servers.ts +27 -26
- package/src/commands/supervisor.ts +7 -2
- package/src/commands/toc.ts +14 -6
- package/src/commands/tunnel.ts +533 -166
- package/src/commands/turn-rollback.ts +111 -0
- package/src/commands/workflow.ts +89 -30
- package/src/core/agents/coord-client.ts +20 -0
- package/src/core/agents/live-authority-v3.ts +17 -0
- package/src/core/agents/live-lifecycle-v3.ts +52 -14
- package/src/core/agents/mailbox.ts +26 -17
- package/src/core/agents/render/prompt-context.ts +10 -12
- package/src/core/agents/render/session-context.ts +9 -32
- package/src/core/agents/rules/stop-hook.ts +3 -3
- package/src/core/agents/state/heartbeat-writer.ts +29 -12
- package/src/core/agents/state/live-coordination-writer.ts +29 -0
- package/src/core/agents/state/pidmap.ts +13 -0
- package/src/core/agents/state/proc-start.ts +62 -2
- package/src/core/agents/state/process-handle.ts +165 -0
- package/src/core/agents/state/stale-sweep.ts +247 -82
- package/src/core/agents/state/unchanged-file.ts +456 -0
- package/src/core/artifacts/delivery-card.ts +7 -1
- package/src/core/context/index.ts +446 -136
- package/src/core/context/observation.ts +29 -0
- package/src/core/diagnostics/bundle.ts +23 -18
- package/src/core/diagnostics/path-identity.ts +15 -0
- package/src/core/diagnostics/sanitize.ts +4 -3
- package/src/core/events/v3/authority-outbox.ts +56 -0
- package/src/core/events/v3/generation-custody.ts +59 -0
- package/src/core/events/v3/producers/coordination-recorder.ts +15 -0
- package/src/core/events/v3/producers/recorder.ts +94 -68
- package/src/core/governor/planning.ts +20 -8
- package/src/core/governor/service-read.ts +128 -20
- package/src/core/governor/service.ts +119 -42
- package/src/core/hooks/cli.ts +33 -5
- package/src/core/inbox/contract.ts +2 -1
- package/src/core/inbox/index.ts +2 -0
- package/src/core/inbox/peer-messages.ts +94 -0
- package/src/core/inbox/service.ts +88 -22
- package/src/core/inbox/targets.ts +148 -0
- package/src/core/inbox/watcher.ts +8 -9
- package/src/core/journal/index.ts +19 -2
- package/src/core/resources/contract.ts +4 -0
- package/src/core/resources/service-status.ts +35 -12
- package/src/core/resources/service.ts +57 -95
- package/src/core/resources/status.ts +57 -8
- package/src/core/semantic/service.ts +2 -8
- package/src/core/servers/index.ts +376 -141
- package/src/core/servers/tunnels.ts +57 -13
- package/src/core/supervisor/contract.ts +13 -0
- package/src/core/supervisor/explanations.ts +4 -1
- package/src/core/supervisor/findings.ts +68 -10
- package/src/core/supervisor/service.ts +87 -26
- package/src/core/supervisor/services.ts +26 -8
- package/src/core/supervisor/status.ts +89 -12
- package/src/core/supervisor/timeline.ts +2 -1
- package/src/core/turn-rollback/content.ts +499 -0
- package/src/core/turn-rollback/index.ts +580 -0
- package/src/core/work/state.ts +7 -7
- package/src/core/workflow/engine.ts +131 -49
- package/src/core/workflow/failure-evidence.ts +141 -0
- package/src/core/workflow/index.ts +12 -2
- package/src/core/workflow/live-session-v3.ts +146 -5
- package/src/core/workflow/proof.ts +134 -26
- package/src/core/workflow/recovery-audit.ts +181 -0
- package/src/core/workflow/run-state.ts +165 -34
- package/src/core/workflow/spawn-claude.ts +18 -0
- package/src/core/workflow/spawn-codex.ts +13 -0
- package/src/core/workflow/spawn-cursor.ts +18 -0
- package/src/core/workflow/spawn-opencode.ts +14 -0
- package/src/core/workflow/types.ts +51 -17
- package/src/core/workflow/workspaces/index.ts +0 -1
- package/src/core/workflow/workspaces/leases.ts +48 -17
- package/src/core/workflow/workspaces/local-git.ts +388 -7
- package/src/core/workflow/workspaces/ownership.ts +232 -0
- package/src/core/workflow/workspaces/reclaim.ts +62 -0
- package/src/core/workflow/workspaces/recovery.ts +45 -10
- package/src/core/workflow/workspaces/state.ts +20 -0
- package/src/lib/browser/windows-chrome.ts +346 -86
- package/src/lib/docs-links.ts +49 -2
- package/src/lib/guarded-remove.ts +132 -14
- package/src/lib/identities/assume.ts +4 -0
- package/src/lib/tunnel/state.ts +70 -15
- package/src/lib/zip/index.ts +483 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/proof.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
-
import { join } from "node:path";
|
|
3
|
+
import { isAbsolute, join } from "node:path";
|
|
4
|
+
import { observationsComparable } from "../context/observation.js";
|
|
4
5
|
import { DIAGNOSTIC_ADVICE_SCHEMA_VERSION } from "../diagnostics/contract.js";
|
|
5
6
|
import { policyDigest } from "../policy/index.js";
|
|
6
7
|
import { isCanonicalWorkflowAttemptContext } from "./attempt-context.js";
|
|
7
8
|
import { stableDigest, writeImmutableJson } from "./durable-record.js";
|
|
9
|
+
import { failureEvidenceAllowsUncharged, isSpawnFailureEvidence } from "./failure-evidence.js";
|
|
8
10
|
import { readWorkflowRunManifest } from "./run-state.js";
|
|
9
11
|
import { EVIDENCE_KINDS, WORKFLOW_DIAGNOSTIC_ADMISSION_SCHEMA_VERSION, WORKFLOW_PROOF_SCHEMA_VERSION, } from "./types.js";
|
|
10
12
|
import { isCanonicalWorkflowWorkContext } from "./work-context.js";
|
|
@@ -125,15 +127,18 @@ export function digestResult(value, kind) {
|
|
|
125
127
|
* attempt was informative about the work — charge it. This also keeps a
|
|
126
128
|
* resumed run whose earlier segment did real work from being written off by
|
|
127
129
|
* a later environment failure.
|
|
128
|
-
* 3.
|
|
129
|
-
*
|
|
130
|
-
* hard stop.
|
|
130
|
+
* 3. Every participant must have failed with positive no-effect evidence,
|
|
131
|
+
* observed absent output and no refusal. A class alone is insufficient.
|
|
132
|
+
* Among those eligible failures, environment is the hard stop.
|
|
131
133
|
* 4. Anything else is undefined ⇒ a charged work failure, exactly as today.
|
|
132
134
|
*/
|
|
133
135
|
export function deriveRunFailureClass(status, agents) {
|
|
134
136
|
if (status !== "failed")
|
|
135
137
|
return undefined;
|
|
136
|
-
if (agents.
|
|
138
|
+
if (agents.length === 0 ||
|
|
139
|
+
agents.some((agent) => agent.status !== "failed" ||
|
|
140
|
+
(agent.class !== "environment" && agent.class !== "upstream") ||
|
|
141
|
+
!failureEvidenceAllowsUncharged(agent.failure_evidence))) {
|
|
137
142
|
return undefined;
|
|
138
143
|
}
|
|
139
144
|
const failed = agents.filter((agent) => agent.status === "failed");
|
|
@@ -262,6 +267,10 @@ export function readWorkflowProof(coordRoot, runId) {
|
|
|
262
267
|
proof.run.class !== "environment" &&
|
|
263
268
|
proof.run.class !== "upstream" &&
|
|
264
269
|
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))) ||
|
|
265
274
|
(proof.run.work_context !== undefined &&
|
|
266
275
|
(!proof.run.work_item_id ||
|
|
267
276
|
proof.run.work_context.id !== proof.run.work_item_id ||
|
|
@@ -275,6 +284,20 @@ export function readWorkflowProof(coordRoot, runId) {
|
|
|
275
284
|
!isWorkspaceExecutionEvidence(proof.execution, runId, proof.run.status))) {
|
|
276
285
|
throw new Error(`workflow proof at ${path} has an unsupported or mismatched schema`);
|
|
277
286
|
}
|
|
287
|
+
if (repoComparisonProblem(proof.repository.before, proof.repository.after) !== undefined ||
|
|
288
|
+
proof.repository.before.dirty_paths_truncated ||
|
|
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()) {
|
|
294
|
+
proof.repository = buildRepoEvidence(proof.repository.before, proof.repository.after);
|
|
295
|
+
proof.unknowns = proof.unknowns.filter((item) => item.code !== "repository_drift_incomplete");
|
|
296
|
+
proof.unknowns.push({
|
|
297
|
+
code: "repository_drift_incomplete",
|
|
298
|
+
message: proof.repository.drift.note,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
278
301
|
const manifestPath = join(coordRoot, ".harnery", "workflows", runId, "run.json");
|
|
279
302
|
if (proof.execution === undefined && !existsSync(manifestPath))
|
|
280
303
|
return proof;
|
|
@@ -369,11 +392,27 @@ export function renderWorkflowProof(proof) {
|
|
|
369
392
|
`${observation.advice.assessment.recommended_action}; action none`
|
|
370
393
|
: "admission: shadow not needed; no real child dispatch");
|
|
371
394
|
}
|
|
372
|
-
const
|
|
395
|
+
const comparable = repoComparisonProblem(proof.repository.before, proof.repository.after) === undefined;
|
|
396
|
+
const repo = comparable &&
|
|
397
|
+
!proof.repository.before.dirty_paths_truncated &&
|
|
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);
|
|
373
405
|
const drift = repo.drift;
|
|
374
|
-
|
|
375
|
-
`
|
|
376
|
-
|
|
406
|
+
if (!comparable) {
|
|
407
|
+
lines.push(`repository: drift unknown. ${drift.note}`);
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
const paths = drift.dirty_paths_added === null || drift.dirty_paths_cleared === null
|
|
411
|
+
? "dirty-path drift unknown"
|
|
412
|
+
: `${drift.dirty_paths_added.length} dirty added, ${drift.dirty_paths_cleared.length} cleared`;
|
|
413
|
+
lines.push(`repository: branch ${repo.before.branch ?? "unknown"} -> ${repo.after.branch ?? "unknown"}; ` +
|
|
414
|
+
`HEAD ${short(repo.before.head)} -> ${short(repo.after.head)}; ${paths}`);
|
|
415
|
+
}
|
|
377
416
|
if (proof.unknowns.length > 0) {
|
|
378
417
|
lines.push(`unknowns: ${proof.unknowns.length}`);
|
|
379
418
|
for (const unknown of proof.unknowns)
|
|
@@ -385,37 +424,93 @@ export function renderWorkflowProof(proof) {
|
|
|
385
424
|
function buildRepoEvidence(beforeRaw, afterRaw) {
|
|
386
425
|
const before = normalizeRepoSnapshot(beforeRaw);
|
|
387
426
|
const after = normalizeRepoSnapshot(afterRaw);
|
|
427
|
+
const problem = repoComparisonProblem(before, after);
|
|
428
|
+
if (problem !== undefined) {
|
|
429
|
+
return {
|
|
430
|
+
source: "engine",
|
|
431
|
+
before,
|
|
432
|
+
after,
|
|
433
|
+
drift: {
|
|
434
|
+
branch_changed: null,
|
|
435
|
+
head_changed: null,
|
|
436
|
+
dirty_paths_added: null,
|
|
437
|
+
dirty_paths_cleared: null,
|
|
438
|
+
dirty_paths_retained: null,
|
|
439
|
+
incomplete: true,
|
|
440
|
+
note: `Repository drift could not be verified: ${problem}. Re-check before editing.`,
|
|
441
|
+
},
|
|
442
|
+
};
|
|
443
|
+
}
|
|
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);
|
|
388
447
|
const beforeDirty = new Set(before.dirty_paths);
|
|
389
448
|
const afterDirty = new Set(after.dirty_paths);
|
|
390
449
|
const retained = after.dirty_paths.filter((path) => beforeDirty.has(path));
|
|
391
|
-
const
|
|
450
|
+
const notes = [
|
|
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;
|
|
392
461
|
return {
|
|
393
462
|
source: "engine",
|
|
394
463
|
before,
|
|
395
464
|
after,
|
|
396
465
|
drift: {
|
|
397
|
-
branch_changed: before.branch !== after.branch,
|
|
398
|
-
head_changed: before.head !== after.head,
|
|
399
|
-
dirty_paths_added:
|
|
400
|
-
|
|
401
|
-
|
|
466
|
+
branch_changed: branchKnown ? before.branch !== after.branch : null,
|
|
467
|
+
head_changed: headKnown ? before.head !== after.head : null,
|
|
468
|
+
dirty_paths_added: pathsComparable
|
|
469
|
+
? after.dirty_paths.filter((path) => !beforeDirty.has(path))
|
|
470
|
+
: null,
|
|
471
|
+
dirty_paths_cleared: pathsComparable
|
|
472
|
+
? before.dirty_paths.filter((path) => !afterDirty.has(path))
|
|
473
|
+
: null,
|
|
474
|
+
dirty_paths_retained: pathsComparable ? retained : null,
|
|
402
475
|
incomplete,
|
|
403
|
-
note: incomplete
|
|
404
|
-
? "Snapshots cannot prove whether retained dirty paths changed during the run, and truncated lists may omit paths."
|
|
405
|
-
: undefined,
|
|
476
|
+
note: incomplete ? notes.join(" ") : undefined,
|
|
406
477
|
},
|
|
407
478
|
};
|
|
408
479
|
}
|
|
409
480
|
function normalizeRepoSnapshot(snapshot) {
|
|
410
481
|
return {
|
|
411
482
|
cwd: snapshot.cwd,
|
|
483
|
+
observation: snapshot.observation ?? "unavailable",
|
|
484
|
+
observation_detail: snapshot.observation
|
|
485
|
+
? clippedOptional(snapshot.observation_detail, 500)
|
|
486
|
+
: "No repository observation was recorded.",
|
|
412
487
|
root: snapshot.root,
|
|
413
|
-
branch: snapshot.branch,
|
|
414
|
-
head: snapshot.head,
|
|
488
|
+
branch: snapshot.branch?.trim() || undefined,
|
|
489
|
+
head: snapshot.head?.trim() || undefined,
|
|
415
490
|
dirty_paths: snapshot.dirty_paths,
|
|
416
491
|
dirty_paths_truncated: snapshot.dirty_paths_truncated,
|
|
417
492
|
};
|
|
418
493
|
}
|
|
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
|
+
}
|
|
419
514
|
function buildAdapterCoverage(agents, claims, attestations) {
|
|
420
515
|
return [...new Set(agents.map((agent) => agent.adapter))].map((adapter) => {
|
|
421
516
|
const adapterAgents = agents.filter((agent) => agent.adapter === adapter);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface WorkflowRecoveryAuthorization {
|
|
2
|
+
actor: string;
|
|
3
|
+
reason: string;
|
|
4
|
+
}
|
|
5
|
+
export interface WorkflowRecoveryIntent extends WorkflowRecoveryAuthorization {
|
|
6
|
+
schema_version: 1;
|
|
7
|
+
operation_id: string;
|
|
8
|
+
run_id: string;
|
|
9
|
+
action: "reclaim_unknown_liveness" | "unlock_resume";
|
|
10
|
+
target_sha256: string;
|
|
11
|
+
target: Record<string, unknown>;
|
|
12
|
+
recorded_at: string;
|
|
13
|
+
pid: number;
|
|
14
|
+
host: string;
|
|
15
|
+
outcome: "unknown";
|
|
16
|
+
}
|
|
17
|
+
export interface WorkflowRecoveryRecord {
|
|
18
|
+
intent: WorkflowRecoveryIntent;
|
|
19
|
+
outcome: "unknown" | "completed";
|
|
20
|
+
}
|
|
21
|
+
export declare function validateWorkflowRecoveryAuthorization(authorization: WorkflowRecoveryAuthorization): void;
|
|
22
|
+
/** Canonical recovery ledger: immutable intent is durable before effects.
|
|
23
|
+
* Completion cites that exact intent; absence always means unknown. */
|
|
24
|
+
export declare function beginWorkflowRecovery(coordRoot: string, input: Omit<WorkflowRecoveryIntent, "schema_version" | "operation_id" | "recorded_at" | "pid" | "host" | "outcome">): {
|
|
25
|
+
intent: WorkflowRecoveryIntent;
|
|
26
|
+
assertCurrent(): void;
|
|
27
|
+
complete(): void;
|
|
28
|
+
};
|
|
29
|
+
export declare function readWorkflowRecoveryLedger(coordRoot: string, runId: string): WorkflowRecoveryRecord[];
|
|
30
|
+
//# sourceMappingURL=recovery-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-audit.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/recovery-audit.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAuB,SAAQ,6BAA6B;IAC3E,cAAc,EAAE,CAAC,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,0BAA0B,GAAG,eAAe,CAAC;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,sBAAsB,CAAC;IAC/B,OAAO,EAAE,SAAS,GAAG,WAAW,CAAC;CAClC;AAED,wBAAgB,qCAAqC,CACnD,aAAa,EAAE,6BAA6B,GAC3C,IAAI,CAmBN;AAED;uEACuE;AACvE,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,IAAI,CACT,sBAAsB,EACtB,gBAAgB,GAAG,cAAc,GAAG,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAC/E,GACA;IAAE,MAAM,EAAE,sBAAsB,CAAC;IAAC,aAAa,IAAI,IAAI,CAAC;IAAC,QAAQ,IAAI,IAAI,CAAA;CAAE,CAmD7E;AAkBD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,sBAAsB,EAAE,CAyC1B"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, readdirSync } from "node:fs";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { stateDirMode } from "../storage/modes.js";
|
|
6
|
+
import { assertWorkflowRunId } from "./approvals.js";
|
|
7
|
+
import { fsyncParentDirectory, readJsonRecord, stableDigest, writeImmutableJson, } from "./durable-record.js";
|
|
8
|
+
export function validateWorkflowRecoveryAuthorization(authorization) {
|
|
9
|
+
for (const [field, limit] of [
|
|
10
|
+
["actor", 200],
|
|
11
|
+
["reason", 2_000],
|
|
12
|
+
]) {
|
|
13
|
+
const value = authorization[field];
|
|
14
|
+
if (typeof value !== "string" ||
|
|
15
|
+
!value.trim() ||
|
|
16
|
+
value.length > limit ||
|
|
17
|
+
Array.from(value).some((character) => character.charCodeAt(0) < 32 || character.charCodeAt(0) === 127)) {
|
|
18
|
+
throw new Error(`workflow recovery requires a nonempty ${field} of at most ${limit} characters without control characters`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Canonical recovery ledger: immutable intent is durable before effects.
|
|
23
|
+
* Completion cites that exact intent; absence always means unknown. */
|
|
24
|
+
export function beginWorkflowRecovery(coordRoot, input) {
|
|
25
|
+
assertWorkflowRunId(input.run_id);
|
|
26
|
+
validateWorkflowRecoveryAuthorization(input);
|
|
27
|
+
if (!/^[a-f0-9]{64}$/.test(input.target_sha256))
|
|
28
|
+
throw new Error("workflow recovery requires an exact preview digest");
|
|
29
|
+
const intent = {
|
|
30
|
+
...input,
|
|
31
|
+
schema_version: 1,
|
|
32
|
+
operation_id: `recovery-${randomUUID()}`,
|
|
33
|
+
recorded_at: new Date().toISOString(),
|
|
34
|
+
pid: process.pid,
|
|
35
|
+
host: hostname(),
|
|
36
|
+
outcome: "unknown",
|
|
37
|
+
};
|
|
38
|
+
const directory = join(coordRoot, ".harnery", "workflows", input.run_id, "recovery", intent.operation_id);
|
|
39
|
+
// Sync each newly published directory name too. Syncing only the intent's
|
|
40
|
+
// immediate parent cannot make a newly created ancestor durable.
|
|
41
|
+
const runDirectory = join(coordRoot, ".harnery", "workflows", input.run_id);
|
|
42
|
+
ensureDurableDirectory(runDirectory);
|
|
43
|
+
const ledgerDirectory = join(runDirectory, "recovery");
|
|
44
|
+
ensureDurableDirectory(ledgerDirectory);
|
|
45
|
+
fsyncParentDirectory(ledgerDirectory);
|
|
46
|
+
mkdirSync(directory, { mode: stateDirMode() });
|
|
47
|
+
fsyncParentDirectory(directory);
|
|
48
|
+
const intentPath = join(directory, "intent.json");
|
|
49
|
+
writeImmutableJson(intentPath, intent);
|
|
50
|
+
const assertCurrent = () => {
|
|
51
|
+
if (stableDigest(readJsonRecord(intentPath, "recovery intent")) !== stableDigest(intent))
|
|
52
|
+
throw new Error("workflow recovery audit authority changed");
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
intent,
|
|
56
|
+
assertCurrent,
|
|
57
|
+
complete: () => {
|
|
58
|
+
assertCurrent();
|
|
59
|
+
writeImmutableJson(join(directory, "completion.json"), {
|
|
60
|
+
schema_version: 1,
|
|
61
|
+
operation_id: intent.operation_id,
|
|
62
|
+
intent_sha256: stableDigest(intent),
|
|
63
|
+
outcome: "completed",
|
|
64
|
+
recorded_at: new Date().toISOString(),
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function ensureDurableDirectory(path) {
|
|
70
|
+
if (existsSync(path)) {
|
|
71
|
+
if (!lstatSync(path).isDirectory())
|
|
72
|
+
throw new Error("workflow recovery ledger is not a directory");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
ensureDurableDirectory(dirname(path));
|
|
76
|
+
try {
|
|
77
|
+
mkdirSync(path, { mode: stateDirMode() });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (error.code !== "EEXIST" || !lstatSync(path).isDirectory())
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
fsyncParentDirectory(path);
|
|
84
|
+
}
|
|
85
|
+
export function readWorkflowRecoveryLedger(coordRoot, runId) {
|
|
86
|
+
assertWorkflowRunId(runId);
|
|
87
|
+
const directory = join(coordRoot, ".harnery", "workflows", runId, "recovery");
|
|
88
|
+
if (!existsSync(directory))
|
|
89
|
+
return [];
|
|
90
|
+
return readdirSync(directory)
|
|
91
|
+
.sort()
|
|
92
|
+
.map((entry) => {
|
|
93
|
+
if (!/^recovery-[a-f0-9-]{36}$/.test(entry))
|
|
94
|
+
throw new Error("invalid workflow recovery ledger entry");
|
|
95
|
+
const intent = readJsonRecord(join(directory, entry, "intent.json"), "recovery intent");
|
|
96
|
+
if (intent.schema_version !== 1 ||
|
|
97
|
+
intent.operation_id !== entry ||
|
|
98
|
+
intent.run_id !== runId ||
|
|
99
|
+
intent.outcome !== "unknown" ||
|
|
100
|
+
!["reclaim_unknown_liveness", "unlock_resume"].includes(intent.action) ||
|
|
101
|
+
!/^[a-f0-9]{64}$/.test(intent.target_sha256)) {
|
|
102
|
+
throw new Error("invalid workflow recovery intent authority");
|
|
103
|
+
}
|
|
104
|
+
validateWorkflowRecoveryAuthorization(intent);
|
|
105
|
+
const completionPath = join(directory, entry, "completion.json");
|
|
106
|
+
if (!existsSync(completionPath))
|
|
107
|
+
return { intent, outcome: "unknown" };
|
|
108
|
+
const completion = readJsonRecord(completionPath, "recovery completion");
|
|
109
|
+
if (completion.schema_version !== 1 ||
|
|
110
|
+
completion.operation_id !== entry ||
|
|
111
|
+
completion.intent_sha256 !== stableDigest(intent) ||
|
|
112
|
+
completion.outcome !== "completed")
|
|
113
|
+
throw new Error("invalid workflow recovery completion authority");
|
|
114
|
+
return { intent, outcome: "completed" };
|
|
115
|
+
});
|
|
116
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RepoSnapshot } from "../context/index.js";
|
|
2
2
|
import { type NormalizedPolicy, type PolicyIsolation, type PolicyNetworkAccess } from "../policy/index.js";
|
|
3
|
+
import { type WorkflowRecoveryAuthorization } from "./recovery-audit.js";
|
|
3
4
|
import type { WorkflowAttemptContext, WorkflowDiagnosticAdmissionConfig, WorkflowSpecialistProfile, WorkflowWorkContext } from "./types.js";
|
|
4
5
|
import type { WorkspaceBinding, WorkspaceCompatibilityExecutionEvidence } from "./workspaces/index.js";
|
|
5
6
|
export declare const WORKFLOW_RUN_MANIFEST_SCHEMA_VERSION: 2;
|
|
@@ -47,6 +48,24 @@ export declare function assertWorkflowRunResumable(coordRoot: string, runId: str
|
|
|
47
48
|
};
|
|
48
49
|
export declare function assertWorkflowScriptUnchanged(manifest: WorkflowRunManifest): void;
|
|
49
50
|
export declare function workflowRunManifestPath(coordRoot: string, runId: string): string;
|
|
50
|
-
/** Acquire an exclusive
|
|
51
|
+
/** Acquire an exclusive lease shared by resume and reclaim. Existing locks
|
|
52
|
+
* always refuse; explicit audited recovery is a separate operation. */
|
|
51
53
|
export declare function acquireWorkflowResumeLease(coordRoot: string, runId: string): () => void;
|
|
54
|
+
export interface WorkflowResumeRecoveryOptions extends Partial<WorkflowRecoveryAuthorization> {
|
|
55
|
+
yes?: boolean;
|
|
56
|
+
lockSha256?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface WorkflowResumeRecoveryResult {
|
|
59
|
+
action: "preview" | "unlocked";
|
|
60
|
+
run_id: string;
|
|
61
|
+
lock_sha256: string | null;
|
|
62
|
+
owner_state: "dead" | "live" | "unknown" | "absent";
|
|
63
|
+
owner: {
|
|
64
|
+
pid: number;
|
|
65
|
+
host: string;
|
|
66
|
+
created_at: string;
|
|
67
|
+
} | null;
|
|
68
|
+
recovery_id?: string;
|
|
69
|
+
}
|
|
70
|
+
export declare function recoverWorkflowResumeLease(coordRoot: string, runId: string, options: WorkflowResumeRecoveryOptions): WorkflowResumeRecoveryResult;
|
|
52
71
|
//# sourceMappingURL=run-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/run-state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-state.d.ts","sourceRoot":"","sources":["../../../src/core/workflow/run-state.ts"],"names":[],"mappings":"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"}
|