harnery 0.29.0 → 0.31.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 +4 -4
- package/dist/commander.d.ts +8 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +14 -13
- package/dist/commands/adapter.d.ts +12 -0
- package/dist/commands/adapter.d.ts.map +1 -0
- package/dist/commands/{harness.js → adapter.js} +35 -35
- package/dist/commands/agents.d.ts +3 -2
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +61 -60
- package/dist/commands/artifacts.d.ts +4 -0
- package/dist/commands/artifacts.d.ts.map +1 -0
- package/dist/commands/artifacts.js +143 -0
- package/dist/commands/backup.d.ts +1 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +5 -2
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +310 -7
- package/dist/commands/checkpoint.d.ts +12 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +162 -0
- package/dist/commands/context.d.ts +2 -2
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +3 -151
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +31 -7
- package/dist/commands/deinit.d.ts +2 -2
- package/dist/commands/deinit.js +15 -15
- package/dist/commands/doctor.js +23 -23
- package/dist/commands/governor.d.ts +4 -0
- package/dist/commands/governor.d.ts.map +1 -0
- package/dist/commands/{supervisor.js → governor.js} +133 -108
- package/dist/commands/init.d.ts +12 -12
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +44 -30
- package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
- package/dist/commands/journal.d.ts.map +1 -0
- package/dist/commands/{scratch.js → journal.js} +47 -47
- package/dist/commands/policy.js +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +3 -3
- package/dist/commands/tunnel.d.ts +16 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +193 -23
- package/dist/commands/web-fetch.js +1 -1
- package/dist/commands/web.d.ts +19 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +51 -0
- package/dist/commands/work.d.ts +2 -1
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +55 -25
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +35 -28
- package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
- package/dist/core/adapters/attest-projection.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
- package/dist/core/adapters/attest.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.js +9 -9
- package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
- package/dist/core/adapters/attestation.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attestation.js +20 -20
- package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
- package/dist/core/adapters/bench.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/bench.js +12 -12
- package/dist/core/adapters/index.d.ts +13 -0
- package/dist/core/adapters/index.d.ts.map +1 -0
- package/dist/core/adapters/index.js +6 -0
- package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
- package/dist/core/adapters/profiles.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/profiles.js +11 -11
- package/dist/core/adapters/registry.d.ts +15 -0
- package/dist/core/adapters/registry.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/registry.js +11 -11
- package/dist/core/{harnesses → adapters}/types.d.ts +28 -23
- package/dist/core/adapters/types.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/types.js +1 -1
- package/dist/core/agents/canonical-emit.d.ts +4 -4
- package/dist/core/agents/canonical-emit.js +5 -5
- package/dist/core/agents/cli-emit.js +1 -1
- package/dist/core/agents/cli.js +30 -26
- package/dist/core/agents/codex-replay.d.ts +1 -1
- package/dist/core/agents/codex-replay.js +6 -6
- package/dist/core/agents/coord-client.d.ts +21 -2
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +122 -27
- package/dist/core/agents/events/consume.d.ts +1 -1
- package/dist/core/agents/events/emit.d.ts +5 -6
- package/dist/core/agents/events/emit.d.ts.map +1 -1
- package/dist/core/agents/events/emit.js +2 -2
- package/dist/core/agents/render/prompt-context.d.ts +21 -9
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +82 -30
- package/dist/core/agents/render/session-context.d.ts +1 -1
- package/dist/core/agents/render/session-context.js +5 -5
- package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +1 -1
- package/dist/core/agents/rules/commit-conflict.js +98 -22
- package/dist/core/agents/rules/stop-hook.d.ts +9 -9
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +23 -5
- package/dist/core/agents/rules/verdict.d.ts +14 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -0
- package/dist/core/agents/rules/verdict.js +1 -0
- package/dist/core/agents/session-events.js +3 -3
- package/dist/core/agents/state/council.d.ts +1 -1
- package/dist/core/agents/state/council.js +1 -1
- package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-projector.js +14 -10
- package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +12 -12
- package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
- package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
- package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
- package/dist/core/agents/state/pidmap.d.ts +28 -4
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +130 -15
- package/dist/core/agents/state/proc-start.d.ts +95 -0
- package/dist/core/agents/state/proc-start.d.ts.map +1 -0
- package/dist/core/agents/state/proc-start.js +199 -0
- package/dist/core/agents/state/shell-mutation.d.ts +1 -1
- package/dist/core/agents/state/shell-mutation.js +1 -1
- package/dist/core/agents/state/stale-sweep.js +7 -7
- package/dist/core/artifacts/index.d.ts +86 -0
- package/dist/core/artifacts/index.d.ts.map +1 -0
- package/dist/core/artifacts/index.js +421 -0
- package/dist/core/config.d.ts +9 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +26 -2
- package/dist/core/context/index.d.ts +12 -12
- package/dist/core/context/index.js +10 -10
- package/dist/core/governor/adapter-spread.d.ts +52 -0
- package/dist/core/governor/adapter-spread.d.ts.map +1 -0
- package/dist/core/governor/adapter-spread.js +52 -0
- package/dist/core/governor/index.d.ts +7 -0
- package/dist/core/governor/index.d.ts.map +1 -0
- package/dist/core/governor/index.js +6 -0
- package/dist/core/governor/plan-api.d.ts +38 -0
- package/dist/core/governor/plan-api.d.ts.map +1 -0
- package/dist/core/governor/plan-api.js +83 -0
- package/dist/core/governor/plan-read.d.ts +5 -0
- package/dist/core/governor/plan-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-read.js +71 -51
- package/dist/core/governor/plan-types.d.ts +181 -0
- package/dist/core/governor/plan-types.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-types.js +4 -4
- package/dist/core/governor/planning.d.ts +48 -0
- package/dist/core/governor/planning.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/planning.js +143 -94
- package/dist/core/governor/read.d.ts +6 -0
- package/dist/core/governor/read.d.ts.map +1 -0
- package/dist/core/governor/read.js +4 -0
- package/dist/core/governor/runner.d.ts +37 -0
- package/dist/core/governor/runner.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/runner.js +15 -15
- package/dist/core/governor/service-read.d.ts +6 -0
- package/dist/core/governor/service-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service-read.js +12 -12
- package/dist/core/governor/service.d.ts +114 -0
- package/dist/core/governor/service.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service.js +57 -57
- package/dist/core/governor/state.d.ts +116 -0
- package/dist/core/governor/state.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/state.js +290 -116
- package/dist/core/hooks/adapter/detect.d.ts +9 -0
- package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
- package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
- package/dist/core/hooks/adapter/events.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/events.js +5 -5
- package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/output.js +30 -22
- package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
- package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
- package/dist/core/hooks/cli.d.ts +3 -3
- package/dist/core/hooks/cli.js +175 -151
- package/dist/core/hooks/effects/image-capture.d.ts +5 -5
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +3 -3
- package/dist/core/hooks/effects/index.d.ts +12 -12
- package/dist/core/hooks/effects/index.d.ts.map +1 -1
- package/dist/core/hooks/effects/index.js +17 -17
- package/dist/core/hooks/events/emit.d.ts +2 -2
- package/dist/core/hooks/events/emit.d.ts.map +1 -1
- package/dist/core/hooks/events/emit.js +1 -1
- package/dist/core/hooks/events/rotate.js +1 -1
- package/dist/core/hooks/events/schema.d.ts +13 -5
- package/dist/core/hooks/events/schema.d.ts.map +1 -1
- package/dist/core/hooks/guard-path.d.ts +2 -2
- package/dist/core/hooks/guard-path.js +2 -2
- package/dist/core/hooks/index.d.ts +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.d.ts +14 -5
- package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.js +64 -7
- package/dist/core/hooks/resolve/coord-root.d.ts +3 -3
- package/dist/core/hooks/resolve/coord-root.js +4 -4
- package/dist/core/hooks/resolve/intent.js +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +1 -1
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +11 -5
- package/dist/core/{scratch → journal}/index.d.ts +25 -25
- package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
- package/dist/core/{scratch → journal}/index.js +38 -38
- package/dist/core/policy/evaluate.d.ts +1 -1
- package/dist/core/policy/evaluate.d.ts.map +1 -1
- package/dist/core/policy/evaluate.js +7 -7
- package/dist/core/policy/types.d.ts +3 -3
- package/dist/core/policy/types.d.ts.map +1 -1
- package/dist/core/work/runner.d.ts.map +1 -1
- package/dist/core/work/runner.js +11 -2
- package/dist/core/work/state.d.ts +28 -3
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +148 -16
- package/dist/core/workflow/adapters.d.ts +17 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -0
- package/dist/core/workflow/adapters.js +21 -0
- package/dist/core/workflow/approvals.js +6 -6
- package/dist/core/workflow/billing.d.ts +9 -9
- package/dist/core/workflow/billing.js +9 -9
- package/dist/core/workflow/child-env.d.ts +10 -2
- package/dist/core/workflow/child-env.d.ts.map +1 -1
- package/dist/core/workflow/child-env.js +12 -4
- package/dist/core/workflow/engine.d.ts +15 -5
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +151 -83
- package/dist/core/workflow/evidence-preflight.d.ts +24 -0
- package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
- package/dist/core/workflow/evidence-preflight.js +134 -0
- package/dist/core/workflow/index.d.ts +3 -2
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/index.js +2 -1
- package/dist/core/workflow/proof.d.ts +28 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +77 -34
- package/dist/core/workflow/run-state.d.ts +1 -1
- package/dist/core/workflow/run-state.js +7 -7
- package/dist/core/workflow/sandbox-projection.d.ts +6 -6
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +11 -11
- package/dist/core/workflow/spawn-claude.d.ts +3 -3
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +28 -8
- package/dist/core/workflow/spawn-codex.d.ts +4 -4
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +26 -8
- package/dist/core/workflow/spawn-cursor.d.ts +4 -4
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +27 -8
- package/dist/core/workflow/spawn-failure.d.ts +15 -1
- package/dist/core/workflow/spawn-failure.d.ts.map +1 -1
- package/dist/core/workflow/spawn-failure.js +35 -1
- package/dist/core/workflow/specialists.js +2 -2
- package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
- package/dist/core/workflow/transcript.d.ts.map +1 -0
- package/dist/core/workflow/{journal.js → transcript.js} +14 -14
- package/dist/core/workflow/types.d.ts +119 -46
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +11 -1
- package/dist/core/workflow/validate.d.ts +1 -1
- package/dist/core/workflow/validate.js +1 -1
- package/dist/core/workflow/workspaces/cancellation.js +2 -2
- package/dist/core/workflow/workspaces/cleanup.js +2 -2
- package/dist/core/workflow/workspaces/execution.js +6 -6
- package/dist/core/workflow/workspaces/inspect.js +9 -9
- package/dist/core/workflow/workspaces/integration.js +14 -14
- package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
- package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/lifecycle.js +9 -9
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +39 -5
- package/dist/core/workflow/workspaces/recovery.js +3 -3
- package/dist/core/workflow/workspaces/state.d.ts +1 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +3 -3
- package/dist/core/workflow/workspaces/types.d.ts +1 -1
- package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
- package/dist/lib/browser/asserts.d.ts +28 -0
- package/dist/lib/browser/asserts.d.ts.map +1 -0
- package/dist/lib/browser/asserts.js +152 -0
- package/dist/lib/browser/client.d.ts +49 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +155 -14
- package/dist/lib/browser/content-checks.d.ts +108 -0
- package/dist/lib/browser/content-checks.d.ts.map +1 -0
- package/dist/lib/browser/content-checks.js +474 -0
- package/dist/lib/browser/critique.d.ts +91 -0
- package/dist/lib/browser/critique.d.ts.map +1 -0
- package/dist/lib/browser/critique.js +167 -0
- package/dist/lib/browser/geometry.d.ts +32 -0
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +244 -1
- package/dist/lib/browser/index.d.ts +4 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/claude-desktop.d.ts.map +1 -1
- package/dist/lib/claude-desktop.js +4 -1
- package/dist/lib/council/index.d.ts +6 -6
- package/dist/lib/council/index.d.ts.map +1 -1
- package/dist/lib/council/index.js +8 -8
- package/dist/lib/exec.d.ts +7 -0
- package/dist/lib/exec.d.ts.map +1 -1
- package/dist/lib/exec.js +6 -3
- package/dist/lib/identities/assume.d.ts +2 -2
- package/dist/lib/identities/assume.js +7 -7
- package/dist/lib/instructions/apply.d.ts +3 -3
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +75 -27
- package/dist/lib/instructions/host-addendum.d.ts +54 -0
- package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
- package/dist/lib/instructions/host-addendum.js +107 -0
- package/dist/lib/instructions/templates.d.ts +10 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +41 -12
- package/dist/lib/machine.d.ts +2 -2
- package/dist/lib/machine.js +2 -2
- package/package.json +26 -21
- package/schemas/config.schema.json +26 -1
- package/src/commander.ts +22 -13
- package/src/commands/{harness.ts → adapter.ts} +46 -46
- package/src/commands/agents.ts +71 -64
- package/src/commands/artifacts.ts +168 -0
- package/src/commands/backup.ts +47 -33
- package/src/commands/browse.ts +438 -2
- package/src/commands/checkpoint.ts +196 -0
- package/src/commands/context.ts +3 -176
- package/src/commands/decision.ts +41 -7
- package/src/commands/deinit.ts +16 -16
- package/src/commands/doctor.ts +28 -28
- package/src/commands/{supervisor.ts → governor.ts} +184 -154
- package/src/commands/init.ts +50 -34
- package/src/commands/{scratch.ts → journal.ts} +60 -60
- package/src/commands/policy.ts +1 -1
- package/src/commands/presence.ts +2 -2
- package/src/commands/sync.ts +3 -3
- package/src/commands/tunnel.ts +237 -34
- package/src/commands/web-fetch.ts +1 -1
- package/src/commands/web.ts +56 -1
- package/src/commands/work.ts +72 -38
- package/src/commands/workflow.ts +43 -34
- package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
- package/src/core/{harnesses → adapters}/attest.ts +27 -27
- package/src/core/{harnesses → adapters}/attestation.ts +41 -41
- package/src/core/{harnesses → adapters}/bench.ts +34 -43
- package/src/core/adapters/index.ts +56 -0
- package/src/core/{harnesses → adapters}/profiles.ts +16 -16
- package/src/core/{harnesses → adapters}/registry.ts +23 -23
- package/src/core/{harnesses → adapters}/types.ts +28 -23
- package/src/core/agents/canonical-emit.ts +6 -6
- package/src/core/agents/cli-emit.ts +1 -1
- package/src/core/agents/cli.ts +30 -28
- package/src/core/agents/codex-replay.ts +6 -6
- package/src/core/agents/coord-client.ts +119 -28
- package/src/core/agents/events/consume.ts +1 -1
- package/src/core/agents/events/emit.ts +7 -6
- package/src/core/agents/render/prompt-context.ts +107 -31
- package/src/core/agents/render/session-context.ts +6 -6
- package/src/core/agents/rules/claim-conflict.ts +4 -7
- package/src/core/agents/rules/commit-conflict.ts +103 -22
- package/src/core/agents/rules/stop-hook.ts +33 -17
- package/src/core/agents/rules/verdict.ts +13 -0
- package/src/core/agents/session-events.ts +4 -4
- package/src/core/agents/state/council.ts +1 -1
- package/src/core/agents/state/heartbeat-projector.ts +16 -12
- package/src/core/agents/state/heartbeat-writer.ts +12 -12
- package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
- package/src/core/agents/state/pidmap.ts +130 -15
- package/src/core/agents/state/proc-start.ts +208 -0
- package/src/core/agents/state/shell-mutation.ts +1 -1
- package/src/core/agents/state/stale-sweep.ts +7 -7
- package/src/core/artifacts/index.ts +557 -0
- package/src/core/config.ts +30 -2
- package/src/core/context/index.ts +15 -15
- package/src/core/governor/adapter-spread.ts +82 -0
- package/src/core/governor/index.ts +91 -0
- package/src/core/governor/plan-api.ts +115 -0
- package/src/core/{supervisor → governor}/plan-read.ts +120 -96
- package/src/core/{supervisor → governor}/plan-types.ts +64 -50
- package/src/core/{supervisor → governor}/planning.ts +240 -188
- package/src/core/governor/read.ts +59 -0
- package/src/core/{supervisor → governor}/runner.ts +39 -39
- package/src/core/{supervisor → governor}/service-read.ts +22 -22
- package/src/core/{supervisor → governor}/service.ts +117 -119
- package/src/core/{supervisor → governor}/state.ts +389 -174
- package/src/core/hooks/adapter/detect.ts +30 -0
- package/src/core/hooks/{harness → adapter}/events.ts +16 -14
- package/src/core/hooks/{harness → adapter}/output.ts +31 -23
- package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
- package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
- package/src/core/hooks/cli.ts +185 -162
- package/src/core/hooks/effects/image-capture.ts +6 -6
- package/src/core/hooks/effects/index.ts +17 -17
- package/src/core/hooks/events/emit.ts +3 -3
- package/src/core/hooks/events/rotate.ts +1 -1
- package/src/core/hooks/events/schema.ts +15 -7
- package/src/core/hooks/guard-path.ts +2 -2
- package/src/core/hooks/index.ts +1 -1
- package/src/core/hooks/resolve/anchor.ts +63 -8
- package/src/core/hooks/resolve/coord-root.ts +4 -4
- package/src/core/hooks/resolve/intent.ts +1 -1
- package/src/core/hooks/resolve/owner.ts +11 -5
- package/src/core/{scratch → journal}/index.ts +53 -53
- package/src/core/policy/evaluate.ts +8 -8
- package/src/core/policy/types.ts +3 -3
- package/src/core/work/runner.ts +11 -2
- package/src/core/work/state.ts +185 -21
- package/src/core/workflow/adapters.ts +33 -0
- package/src/core/workflow/approvals.ts +7 -7
- package/src/core/workflow/billing.ts +12 -12
- package/src/core/workflow/child-env.ts +13 -4
- package/src/core/workflow/engine.ts +166 -90
- package/src/core/workflow/evidence-preflight.ts +165 -0
- package/src/core/workflow/index.ts +6 -3
- package/src/core/workflow/proof.ts +94 -48
- package/src/core/workflow/run-state.ts +7 -7
- package/src/core/workflow/sandbox-projection.ts +16 -16
- package/src/core/workflow/spawn-claude.ts +34 -12
- package/src/core/workflow/spawn-codex.ts +30 -12
- package/src/core/workflow/spawn-cursor.ts +31 -12
- package/src/core/workflow/spawn-failure.ts +41 -1
- package/src/core/workflow/specialists.ts +2 -2
- package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
- package/src/core/workflow/types.ts +130 -46
- package/src/core/workflow/validate.ts +1 -1
- package/src/core/workflow/workspaces/cancellation.ts +2 -2
- package/src/core/workflow/workspaces/cleanup.ts +2 -2
- package/src/core/workflow/workspaces/execution.ts +6 -6
- package/src/core/workflow/workspaces/inspect.ts +14 -11
- package/src/core/workflow/workspaces/integration.ts +18 -14
- package/src/core/workflow/workspaces/lifecycle.ts +10 -10
- package/src/core/workflow/workspaces/local-git.ts +47 -5
- package/src/core/workflow/workspaces/recovery.ts +3 -3
- package/src/core/workflow/workspaces/state.ts +4 -3
- package/src/core/workflow/workspaces/types.ts +1 -1
- package/src/lib/browser/asserts.ts +177 -0
- package/src/lib/browser/client.ts +189 -14
- package/src/lib/browser/content-checks.ts +571 -0
- package/src/lib/browser/critique.ts +231 -0
- package/src/lib/browser/geometry.ts +297 -1
- package/src/lib/browser/index.ts +34 -0
- package/src/lib/claude-desktop.ts +4 -1
- package/src/lib/council/index.ts +9 -9
- package/src/lib/exec.ts +13 -3
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +87 -25
- package/src/lib/instructions/host-addendum.ts +126 -0
- package/src/lib/instructions/templates.ts +44 -15
- package/src/lib/machine.ts +2 -2
- package/dist/commands/harness.d.ts +0 -12
- package/dist/commands/harness.d.ts.map +0 -1
- package/dist/commands/scratch.d.ts +0 -4
- package/dist/commands/scratch.d.ts.map +0 -1
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/session.js +0 -162
- package/dist/commands/supervisor.d.ts +0 -4
- package/dist/commands/supervisor.d.ts.map +0 -1
- package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
- package/dist/core/harnesses/attest.d.ts.map +0 -1
- package/dist/core/harnesses/attestation.d.ts.map +0 -1
- package/dist/core/harnesses/bench.d.ts.map +0 -1
- package/dist/core/harnesses/index.d.ts +0 -13
- package/dist/core/harnesses/index.d.ts.map +0 -1
- package/dist/core/harnesses/index.js +0 -6
- package/dist/core/harnesses/profiles.d.ts.map +0 -1
- package/dist/core/harnesses/registry.d.ts +0 -15
- package/dist/core/harnesses/registry.d.ts.map +0 -1
- package/dist/core/harnesses/types.d.ts.map +0 -1
- package/dist/core/hooks/harness/detect.d.ts +0 -9
- package/dist/core/hooks/harness/events.d.ts.map +0 -1
- package/dist/core/hooks/harness/output.d.ts.map +0 -1
- package/dist/core/supervisor/index.d.ts +0 -7
- package/dist/core/supervisor/index.d.ts.map +0 -1
- package/dist/core/supervisor/index.js +0 -6
- package/dist/core/supervisor/plan-api.d.ts +0 -23
- package/dist/core/supervisor/plan-api.d.ts.map +0 -1
- package/dist/core/supervisor/plan-api.js +0 -50
- package/dist/core/supervisor/plan-read.d.ts +0 -5
- package/dist/core/supervisor/plan-read.d.ts.map +0 -1
- package/dist/core/supervisor/plan-types.d.ts +0 -170
- package/dist/core/supervisor/plan-types.d.ts.map +0 -1
- package/dist/core/supervisor/planning.d.ts +0 -33
- package/dist/core/supervisor/planning.d.ts.map +0 -1
- package/dist/core/supervisor/read.d.ts +0 -6
- package/dist/core/supervisor/read.d.ts.map +0 -1
- package/dist/core/supervisor/read.js +0 -4
- package/dist/core/supervisor/runner.d.ts +0 -37
- package/dist/core/supervisor/runner.d.ts.map +0 -1
- package/dist/core/supervisor/service-read.d.ts +0 -6
- package/dist/core/supervisor/service-read.d.ts.map +0 -1
- package/dist/core/supervisor/service.d.ts +0 -114
- package/dist/core/supervisor/service.d.ts.map +0 -1
- package/dist/core/supervisor/state.d.ts +0 -95
- package/dist/core/supervisor/state.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.d.ts +0 -17
- package/dist/core/workflow/harnesses.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.js +0 -21
- package/dist/core/workflow/journal.d.ts.map +0 -1
- package/src/commands/session.ts +0 -187
- package/src/core/harnesses/index.ts +0 -56
- package/src/core/hooks/harness/detect.ts +0 -30
- package/src/core/supervisor/index.ts +0 -89
- package/src/core/supervisor/plan-api.ts +0 -73
- package/src/core/supervisor/read.ts +0 -59
- package/src/core/workflow/harnesses.ts +0 -33
- /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { EVIDENCE_KINDS } from "./types.ts";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Reject an unusable evidence kind before the first agent is spawned.
|
|
5
|
+
*
|
|
6
|
+
* `evidence()` is by construction near the end of a workflow, so an invalid
|
|
7
|
+
* kind throws after every agent has finished. Measured: a fifty-minute run with
|
|
8
|
+
* three completed agents died at its final line on `kind: "design"`, reported
|
|
9
|
+
* `work_failed`, and burned an attempt. The work survived only because it had
|
|
10
|
+
* already been written to the tree; nothing in the proof could recover it.
|
|
11
|
+
*
|
|
12
|
+
* A workflow's evidence kinds are usually written literally, and a literal is
|
|
13
|
+
* checkable by reading the file. Where a kind is computed the scan says nothing
|
|
14
|
+
* and the existing runtime validation still applies — a partial check that
|
|
15
|
+
* costs one file read is worth more than a complete one nobody can implement.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export interface EvidencePreflightProblem {
|
|
19
|
+
kind: string;
|
|
20
|
+
line: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Every literal `evidence({ kind: … })` in this source whose kind is not in the
|
|
24
|
+
* vocabulary. Computed kinds are invisible here, by design. */
|
|
25
|
+
export function findInvalidEvidenceKinds(source: string): EvidencePreflightProblem[] {
|
|
26
|
+
const { masked, literals } = maskSource(source);
|
|
27
|
+
const problems: EvidencePreflightProblem[] = [];
|
|
28
|
+
const valid = new Set<string>(EVIDENCE_KINDS);
|
|
29
|
+
|
|
30
|
+
for (const call of evidenceCallRanges(masked)) {
|
|
31
|
+
// `kind` as an object key, then the value's first character. A quote there
|
|
32
|
+
// means a literal we can read; anything else is computed, so skip it.
|
|
33
|
+
const property = /\bkind\s*:\s*/g;
|
|
34
|
+
property.lastIndex = 0;
|
|
35
|
+
const slice = masked.slice(call.start, call.end);
|
|
36
|
+
let match = property.exec(slice);
|
|
37
|
+
while (match !== null) {
|
|
38
|
+
const valueAt = call.start + match.index + match[0].length;
|
|
39
|
+
const literal = literals.get(valueAt);
|
|
40
|
+
if (literal !== undefined && !valid.has(literal)) {
|
|
41
|
+
problems.push({ kind: literal, line: lineOf(source, valueAt) });
|
|
42
|
+
}
|
|
43
|
+
match = property.exec(slice);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return problems;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The thrown message, or undefined when the script is clean or unreadable. */
|
|
50
|
+
export function evidencePreflightError(source: string, scriptPath: string): string | undefined {
|
|
51
|
+
const problems = findInvalidEvidenceKinds(source);
|
|
52
|
+
if (problems.length === 0) return undefined;
|
|
53
|
+
const listed = problems
|
|
54
|
+
.map((problem) => `line ${problem.line}: ${JSON.stringify(problem.kind)}`)
|
|
55
|
+
.join(", ");
|
|
56
|
+
return (
|
|
57
|
+
`${scriptPath}: evidence kind must be one of: ${EVIDENCE_KINDS.join(", ")} ` +
|
|
58
|
+
`(${listed}). Rejected before running, because an invalid kind would otherwise ` +
|
|
59
|
+
`throw at the end of the workflow and discard the work every agent had already done.`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
interface MaskedSource {
|
|
64
|
+
/** The source with comment bodies and string interiors blanked to spaces, so
|
|
65
|
+
* structural scanning cannot be fooled by a brace or paren inside either.
|
|
66
|
+
* Same length as the input, so every index still maps back. */
|
|
67
|
+
masked: string;
|
|
68
|
+
/** String-literal value, keyed by the index of its opening quote. Template
|
|
69
|
+
* literals are absent: one may interpolate, so its value is not static. */
|
|
70
|
+
literals: Map<number, string>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function maskSource(source: string): MaskedSource {
|
|
74
|
+
const out = source.split("");
|
|
75
|
+
const literals = new Map<number, string>();
|
|
76
|
+
let index = 0;
|
|
77
|
+
const blank = (from: number, to: number): void => {
|
|
78
|
+
for (let i = from; i < to && i < out.length; i++) {
|
|
79
|
+
if (out[i] !== "\n") out[i] = " ";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
while (index < source.length) {
|
|
84
|
+
const char = source[index];
|
|
85
|
+
const next = source[index + 1];
|
|
86
|
+
if (char === "/" && next === "/") {
|
|
87
|
+
const end = source.indexOf("\n", index);
|
|
88
|
+
blank(index, end === -1 ? source.length : end);
|
|
89
|
+
index = end === -1 ? source.length : end;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (char === "/" && next === "*") {
|
|
93
|
+
const end = source.indexOf("*/", index + 2);
|
|
94
|
+
const stop = end === -1 ? source.length : end + 2;
|
|
95
|
+
blank(index, stop);
|
|
96
|
+
index = stop;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
100
|
+
const start = index;
|
|
101
|
+
let cursor = index + 1;
|
|
102
|
+
let value = "";
|
|
103
|
+
while (cursor < source.length) {
|
|
104
|
+
const inner = source[cursor];
|
|
105
|
+
if (inner === "\\") {
|
|
106
|
+
value += source[cursor + 1] ?? "";
|
|
107
|
+
cursor += 2;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (inner === char) break;
|
|
111
|
+
// An unterminated single- or double-quoted string cannot span lines, so
|
|
112
|
+
// stop rather than swallowing the rest of the file on a syntax error.
|
|
113
|
+
if (inner === "\n" && char !== "`") break;
|
|
114
|
+
value += inner;
|
|
115
|
+
cursor++;
|
|
116
|
+
}
|
|
117
|
+
const closed = source[cursor] === char;
|
|
118
|
+
blank(start + 1, cursor);
|
|
119
|
+
if (closed && char !== "`") literals.set(start, value);
|
|
120
|
+
index = closed ? cursor + 1 : cursor;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
index++;
|
|
124
|
+
}
|
|
125
|
+
return { masked: out.join(""), literals };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** The argument list of every `evidence(` call, as index ranges into the masked
|
|
129
|
+
* source. A dotted receiver (`ctx.evidence(`) counts; a longer identifier that
|
|
130
|
+
* merely ends in "evidence" does not. */
|
|
131
|
+
function evidenceCallRanges(masked: string): { start: number; end: number }[] {
|
|
132
|
+
const ranges: { start: number; end: number }[] = [];
|
|
133
|
+
const call = /evidence\s*\(/g;
|
|
134
|
+
let match = call.exec(masked);
|
|
135
|
+
while (match !== null) {
|
|
136
|
+
const before = match.index > 0 ? masked[match.index - 1]! : "";
|
|
137
|
+
if (!/[A-Za-z0-9_$]/.test(before)) {
|
|
138
|
+
const open = match.index + match[0].length - 1;
|
|
139
|
+
const close = matchingParen(masked, open);
|
|
140
|
+
if (close > open) ranges.push({ start: open + 1, end: close });
|
|
141
|
+
}
|
|
142
|
+
match = call.exec(masked);
|
|
143
|
+
}
|
|
144
|
+
return ranges;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function matchingParen(masked: string, open: number): number {
|
|
148
|
+
let depth = 0;
|
|
149
|
+
for (let i = open; i < masked.length; i++) {
|
|
150
|
+
if (masked[i] === "(") depth++;
|
|
151
|
+
else if (masked[i] === ")") {
|
|
152
|
+
depth--;
|
|
153
|
+
if (depth === 0) return i;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return -1;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function lineOf(source: string, index: number): number {
|
|
160
|
+
let line = 1;
|
|
161
|
+
for (let i = 0; i < index && i < source.length; i++) {
|
|
162
|
+
if (source[i] === "\n") line++;
|
|
163
|
+
}
|
|
164
|
+
return line;
|
|
165
|
+
}
|
|
@@ -25,6 +25,7 @@ export { runWorkflow, WorkflowParkedError, WorkflowRunError } from "./engine.ts"
|
|
|
25
25
|
export {
|
|
26
26
|
buildWorkflowProof,
|
|
27
27
|
createEvidenceRecord,
|
|
28
|
+
deriveRunFailureClass,
|
|
28
29
|
digestResult,
|
|
29
30
|
normalizeWorkflowMeta,
|
|
30
31
|
readWorkflowProof,
|
|
@@ -43,22 +44,24 @@ export {
|
|
|
43
44
|
workflowScriptDigest,
|
|
44
45
|
writeWorkflowRunManifest,
|
|
45
46
|
} from "./run-state.ts";
|
|
47
|
+
export { isUpstreamFailureText, vendorFailureText } from "./spawn-failure.ts";
|
|
46
48
|
export type {
|
|
47
49
|
AcceptanceCriterion,
|
|
48
50
|
AcceptanceResult,
|
|
49
51
|
AcceptanceStatus,
|
|
50
52
|
AcceptanceSummary,
|
|
53
|
+
AdapterEvidenceCapability,
|
|
54
|
+
AdapterEvidenceCoverage,
|
|
55
|
+
AdapterName,
|
|
51
56
|
AgentOpts,
|
|
52
57
|
EngineOpts,
|
|
53
58
|
EvidenceKind,
|
|
54
59
|
EvidenceSource,
|
|
55
60
|
EvidenceStatus,
|
|
56
|
-
HarnessEvidenceCapability,
|
|
57
|
-
HarnessEvidenceCoverage,
|
|
58
|
-
HarnessName,
|
|
59
61
|
ResultDigest,
|
|
60
62
|
RunReport,
|
|
61
63
|
Spawner,
|
|
64
|
+
SpawnFailureClass,
|
|
62
65
|
SpawnRequest,
|
|
63
66
|
SpawnResult,
|
|
64
67
|
StageSchema,
|
|
@@ -16,10 +16,12 @@ import type {
|
|
|
16
16
|
AcceptanceCriterion,
|
|
17
17
|
AcceptanceResult,
|
|
18
18
|
AcceptanceSummary,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
AdapterAttestationCitation,
|
|
20
|
+
AdapterEvidenceCapability,
|
|
21
|
+
AdapterEvidenceCoverage,
|
|
22
22
|
ResultDigest,
|
|
23
|
+
RunFailureClass,
|
|
24
|
+
SpawnFailureClass,
|
|
23
25
|
WorkflowAgentProof,
|
|
24
26
|
WorkflowAttemptContext,
|
|
25
27
|
WorkflowEvidenceInput,
|
|
@@ -33,7 +35,7 @@ import type {
|
|
|
33
35
|
WorkflowSandboxProjectionEvidence,
|
|
34
36
|
WorkflowWorkContext,
|
|
35
37
|
} from "./types.ts";
|
|
36
|
-
import { WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.ts";
|
|
38
|
+
import { EVIDENCE_KINDS, WORKFLOW_PROOF_SCHEMA_VERSION } from "./types.ts";
|
|
37
39
|
import { isCanonicalWorkflowWorkContext } from "./work-context.ts";
|
|
38
40
|
import type {
|
|
39
41
|
WorkspaceAttestation,
|
|
@@ -77,23 +79,26 @@ export interface BuildWorkflowProofInput {
|
|
|
77
79
|
startedAt: string;
|
|
78
80
|
endedAt: string;
|
|
79
81
|
durationMs: number;
|
|
80
|
-
|
|
82
|
+
transcriptPath: string;
|
|
81
83
|
before: RepoSnapshot;
|
|
82
84
|
after: RepoSnapshot;
|
|
83
85
|
agents: WorkflowAgentProof[];
|
|
84
86
|
evidence: WorkflowEvidenceRecord[];
|
|
85
|
-
|
|
87
|
+
adapterEvidence?: Readonly<Record<string, AdapterEvidenceCapability | undefined>>;
|
|
86
88
|
/** Filesystem policy actually projected into children (ADR 0039). */
|
|
87
89
|
sandboxProjection?: WorkflowSandboxProjectionEvidence;
|
|
88
|
-
/** Live attestations backing each
|
|
90
|
+
/** Live attestations backing each adapter's claims (ADR 0038). Injected by
|
|
89
91
|
* the caller so proof stays free of filesystem lookups. */
|
|
90
|
-
|
|
92
|
+
adapterAttestations?: Readonly<Record<string, AdapterAttestationCitation | undefined>>;
|
|
91
93
|
policy?: {
|
|
92
94
|
config: Readonly<NormalizedPolicy>;
|
|
93
95
|
decisions: readonly PolicyDecision[];
|
|
94
96
|
isolation: PolicyIsolation;
|
|
95
97
|
networkAccess: PolicyNetworkAccess;
|
|
96
98
|
};
|
|
99
|
+
/** Set when the script called ctx.blocked(): the run stopped because a human
|
|
100
|
+
* must rule. Forces run class "decision" regardless of the agents' classes. */
|
|
101
|
+
blocked?: { reason: string; decisionId?: string };
|
|
97
102
|
workspaceBinding?: WorkspaceBinding;
|
|
98
103
|
workspaceAttestation?: WorkspaceAttestation;
|
|
99
104
|
workspaceFallback?: WorkspaceUnsupportedExecutionEvidence;
|
|
@@ -166,11 +171,7 @@ export function createEvidenceRecord(input: {
|
|
|
166
171
|
id: `e${input.sequence}`,
|
|
167
172
|
source: "workflow",
|
|
168
173
|
recorded_at: input.recordedAt ?? new Date().toISOString(),
|
|
169
|
-
kind: enumValue(
|
|
170
|
-
value.kind,
|
|
171
|
-
["test", "command", "artifact", "change", "review", "observation"],
|
|
172
|
-
"evidence kind",
|
|
173
|
-
),
|
|
174
|
+
kind: enumValue(value.kind, EVIDENCE_KINDS, "evidence kind"),
|
|
174
175
|
status: enumValue(value.status, ["passed", "failed", "observed", "unknown"], "evidence status"),
|
|
175
176
|
label: boundedRequired(value.label, "evidence label", MAX_LABEL_CHARS),
|
|
176
177
|
summary: boundedOptional(value.summary, "evidence summary", MAX_SUMMARY_CHARS),
|
|
@@ -218,6 +219,36 @@ export function digestResult(value: unknown, kind?: "text" | "json"): ResultDige
|
|
|
218
219
|
};
|
|
219
220
|
}
|
|
220
221
|
|
|
222
|
+
/**
|
|
223
|
+
* The run-level failure class (ADR 0046), derived from the agents rather than a
|
|
224
|
+
* single terminal throw so it survives a script's `parallel()` swallowing the
|
|
225
|
+
* rejection — a swallowed agent's proof is still recorded with its class.
|
|
226
|
+
*
|
|
227
|
+
* Rules, in order, all in service of "default to charging":
|
|
228
|
+
* 1. A succeeded run is never classed (there is nothing uncharged about it).
|
|
229
|
+
* 2. If ANY agent produced a result (succeeded or replayed from cache) the
|
|
230
|
+
* attempt was informative about the work — charge it. This also keeps a
|
|
231
|
+
* resumed run whose earlier segment did real work from being written off by
|
|
232
|
+
* a later environment failure.
|
|
233
|
+
* 3. Otherwise, among the failed agents, environment wins over upstream: a
|
|
234
|
+
* missing binary means nothing ran at all, and it is the operator-chosen
|
|
235
|
+
* hard stop.
|
|
236
|
+
* 4. Anything else is undefined ⇒ a charged work failure, exactly as today.
|
|
237
|
+
*/
|
|
238
|
+
export function deriveRunFailureClass(
|
|
239
|
+
status: "succeeded" | "failed",
|
|
240
|
+
agents: readonly Pick<WorkflowAgentProof, "status" | "class">[],
|
|
241
|
+
): SpawnFailureClass | undefined {
|
|
242
|
+
if (status !== "failed") return undefined;
|
|
243
|
+
if (agents.some((agent) => agent.status === "succeeded" || agent.status === "cached")) {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
const failed = agents.filter((agent) => agent.status === "failed");
|
|
247
|
+
if (failed.some((agent) => agent.class === "environment")) return "environment";
|
|
248
|
+
if (failed.some((agent) => agent.class === "upstream")) return "upstream";
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
|
|
221
252
|
export function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProof {
|
|
222
253
|
const acceptance = rollupAcceptance(input.meta.acceptance, input.evidence);
|
|
223
254
|
const repository = buildRepoEvidence(input.before, input.after);
|
|
@@ -229,9 +260,16 @@ export function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProo
|
|
|
229
260
|
session_id: clippedOptional(agent.session_id, MAX_REF_CHARS),
|
|
230
261
|
error: clippedOptional(agent.error, MAX_SUMMARY_CHARS),
|
|
231
262
|
}));
|
|
232
|
-
const
|
|
233
|
-
const unknowns = buildUnknowns(agents,
|
|
234
|
-
|
|
263
|
+
const adapters = buildAdapterCoverage(agents, input.adapterEvidence, input.adapterAttestations);
|
|
264
|
+
const unknowns = buildUnknowns(agents, adapters, repository);
|
|
265
|
+
// A declared stop-on-human beats a derived spawn class. If the script said a
|
|
266
|
+
// human must rule, that is the true reason the run ended, even when some agent
|
|
267
|
+
// also happened to hit a flaky vendor on the way there.
|
|
268
|
+
const runClass: RunFailureClass | undefined =
|
|
269
|
+
input.status === "failed" && input.blocked
|
|
270
|
+
? "decision"
|
|
271
|
+
: deriveRunFailureClass(input.status, agents);
|
|
272
|
+
const transcript = readFileSync(input.transcriptPath);
|
|
235
273
|
return {
|
|
236
274
|
schema_version: WORKFLOW_PROOF_SCHEMA_VERSION,
|
|
237
275
|
run: {
|
|
@@ -247,6 +285,10 @@ export function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProo
|
|
|
247
285
|
objective: input.meta.objective,
|
|
248
286
|
error: clippedOptional(input.error, MAX_SUMMARY_CHARS),
|
|
249
287
|
result: input.result === undefined ? undefined : digestResult(input.result),
|
|
288
|
+
...(runClass ? { class: runClass } : {}),
|
|
289
|
+
...(runClass === "decision" && input.blocked?.decisionId
|
|
290
|
+
? { decision_id: clipped(input.blocked.decisionId, MAX_REF_CHARS) }
|
|
291
|
+
: {}),
|
|
250
292
|
},
|
|
251
293
|
acceptance,
|
|
252
294
|
agents,
|
|
@@ -258,13 +300,13 @@ export function buildWorkflowProof(input: BuildWorkflowProofInput): WorkflowProo
|
|
|
258
300
|
: input.workspaceFallback,
|
|
259
301
|
repository,
|
|
260
302
|
...(input.sandboxProjection ? { sandbox_projection: input.sandboxProjection } : {}),
|
|
261
|
-
|
|
303
|
+
adapters,
|
|
262
304
|
unknowns,
|
|
263
305
|
integrity: {
|
|
264
|
-
|
|
265
|
-
path: "
|
|
266
|
-
sha256: createHash("sha256").update(
|
|
267
|
-
bytes:
|
|
306
|
+
transcript: {
|
|
307
|
+
path: "transcript.jsonl",
|
|
308
|
+
sha256: createHash("sha256").update(transcript).digest("hex"),
|
|
309
|
+
bytes: transcript.byteLength,
|
|
268
310
|
},
|
|
269
311
|
},
|
|
270
312
|
};
|
|
@@ -326,6 +368,10 @@ export function readWorkflowProof(coordRoot: string, runId: string): WorkflowPro
|
|
|
326
368
|
if (
|
|
327
369
|
proof.schema_version !== WORKFLOW_PROOF_SCHEMA_VERSION ||
|
|
328
370
|
proof.run?.id !== runId ||
|
|
371
|
+
(proof.run.class !== undefined &&
|
|
372
|
+
proof.run.class !== "environment" &&
|
|
373
|
+
proof.run.class !== "upstream" &&
|
|
374
|
+
proof.run.class !== "decision") ||
|
|
329
375
|
(proof.run.work_context !== undefined &&
|
|
330
376
|
(!proof.run.work_item_id ||
|
|
331
377
|
proof.run.work_context.id !== proof.run.work_item_id ||
|
|
@@ -418,7 +464,7 @@ export function renderWorkflowProof(proof: WorkflowProof): string {
|
|
|
418
464
|
lines.push(`unknowns: ${proof.unknowns.length}`);
|
|
419
465
|
for (const unknown of proof.unknowns) lines.push(` - ${unknown.message}`);
|
|
420
466
|
}
|
|
421
|
-
lines.push(`
|
|
467
|
+
lines.push(`transcript sha256: ${proof.integrity.transcript.sha256}`);
|
|
422
468
|
return `${lines.join("\n")}\n`;
|
|
423
469
|
}
|
|
424
470
|
|
|
@@ -460,47 +506,47 @@ function normalizeRepoSnapshot(snapshot: RepoSnapshot): WorkflowRepoSnapshot {
|
|
|
460
506
|
};
|
|
461
507
|
}
|
|
462
508
|
|
|
463
|
-
function
|
|
509
|
+
function buildAdapterCoverage(
|
|
464
510
|
agents: WorkflowAgentProof[],
|
|
465
|
-
claims: Readonly<Record<string,
|
|
466
|
-
attestations: Readonly<Record<string,
|
|
467
|
-
):
|
|
468
|
-
return [...new Set(agents.map((agent) => agent.
|
|
469
|
-
const
|
|
511
|
+
claims: Readonly<Record<string, AdapterEvidenceCapability | undefined>> | undefined,
|
|
512
|
+
attestations: Readonly<Record<string, AdapterAttestationCitation | undefined>> | undefined,
|
|
513
|
+
): AdapterEvidenceCoverage[] {
|
|
514
|
+
return [...new Set(agents.map((agent) => agent.adapter))].map((adapter) => {
|
|
515
|
+
const adapterAgents = agents.filter((agent) => agent.adapter === adapter);
|
|
470
516
|
return {
|
|
471
|
-
|
|
472
|
-
tool_evidence: claims?.[
|
|
517
|
+
adapter,
|
|
518
|
+
tool_evidence: claims?.[adapter]?.toolEvidence ?? {
|
|
473
519
|
support: "unknown",
|
|
474
|
-
note: "No
|
|
520
|
+
note: "No adapter capability claim was supplied to this workflow run.",
|
|
475
521
|
},
|
|
476
522
|
observed: {
|
|
477
|
-
final_results:
|
|
478
|
-
session_ids:
|
|
479
|
-
costs:
|
|
523
|
+
final_results: adapterAgents.filter((agent) => agent.result).length,
|
|
524
|
+
session_ids: adapterAgents.filter((agent) => agent.session_id).length,
|
|
525
|
+
costs: adapterAgents.filter((agent) => agent.cost_usd !== undefined).length,
|
|
480
526
|
},
|
|
481
|
-
...(attestations?.[
|
|
527
|
+
...(attestations?.[adapter] ? { attestation: attestations[adapter] } : {}),
|
|
482
528
|
};
|
|
483
529
|
});
|
|
484
530
|
}
|
|
485
531
|
|
|
486
532
|
function buildUnknowns(
|
|
487
533
|
agents: WorkflowAgentProof[],
|
|
488
|
-
|
|
534
|
+
adapters: AdapterEvidenceCoverage[],
|
|
489
535
|
repository: WorkflowRepoEvidence,
|
|
490
536
|
): WorkflowProofUnknown[] {
|
|
491
537
|
const unknowns: WorkflowProofUnknown[] = [];
|
|
492
|
-
for (const
|
|
493
|
-
if (
|
|
538
|
+
for (const adapter of adapters) {
|
|
539
|
+
if (adapter.tool_evidence.support === "unknown") {
|
|
494
540
|
unknowns.push({
|
|
495
|
-
code: "
|
|
496
|
-
|
|
497
|
-
message: `${
|
|
541
|
+
code: "adapter_capability_unregistered",
|
|
542
|
+
adapter: adapter.adapter,
|
|
543
|
+
message: `${adapter.adapter}: tool-evidence capability was not registered for this run.`,
|
|
498
544
|
});
|
|
499
|
-
} else if (
|
|
545
|
+
} else if (adapter.tool_evidence.support !== "supported") {
|
|
500
546
|
unknowns.push({
|
|
501
547
|
code: "tool_evidence_unavailable",
|
|
502
|
-
|
|
503
|
-
message: `${
|
|
548
|
+
adapter: adapter.adapter,
|
|
549
|
+
message: `${adapter.adapter}: adapter-native tool evidence is ${adapter.tool_evidence.support}.`,
|
|
504
550
|
});
|
|
505
551
|
}
|
|
506
552
|
}
|
|
@@ -508,17 +554,17 @@ function buildUnknowns(
|
|
|
508
554
|
if (agent.cost_usd === undefined) {
|
|
509
555
|
unknowns.push({
|
|
510
556
|
code: "agent_cost_unreported",
|
|
511
|
-
|
|
557
|
+
adapter: agent.adapter,
|
|
512
558
|
agent_id: agent.id,
|
|
513
|
-
message: `${agent.id}: ${agent.
|
|
559
|
+
message: `${agent.id}: ${agent.adapter} did not report per-run cost.`,
|
|
514
560
|
});
|
|
515
561
|
}
|
|
516
562
|
if (!agent.session_id) {
|
|
517
563
|
unknowns.push({
|
|
518
564
|
code: "agent_session_unreported",
|
|
519
|
-
|
|
565
|
+
adapter: agent.adapter,
|
|
520
566
|
agent_id: agent.id,
|
|
521
|
-
message: `${agent.id}: ${agent.
|
|
567
|
+
message: `${agent.id}: ${agent.adapter} did not report a child session id.`,
|
|
522
568
|
});
|
|
523
569
|
}
|
|
524
570
|
}
|
|
@@ -58,7 +58,7 @@ export interface WorkflowRunManifest {
|
|
|
58
58
|
repository_before: RepoSnapshot;
|
|
59
59
|
execution: {
|
|
60
60
|
cwd: string;
|
|
61
|
-
|
|
61
|
+
default_adapter: string;
|
|
62
62
|
max_agents: number;
|
|
63
63
|
concurrency: number;
|
|
64
64
|
subscription_only: boolean;
|
|
@@ -149,11 +149,11 @@ export function assertWorkflowRunResumable(
|
|
|
149
149
|
runId: string,
|
|
150
150
|
): { manifest: WorkflowRunManifest; approvalId: string } {
|
|
151
151
|
const manifest = readWorkflowRunManifest(coordRoot, runId);
|
|
152
|
-
const
|
|
153
|
-
if (!existsSync(
|
|
152
|
+
const transcriptPath = join(coordRoot, ".harnery", "workflows", runId, "transcript.jsonl");
|
|
153
|
+
if (!existsSync(transcriptPath)) throw new Error(`workflow run ${runId} has no transcript`);
|
|
154
154
|
let approvalId: string | undefined;
|
|
155
155
|
let terminal = false;
|
|
156
|
-
for (const line of readFileSync(
|
|
156
|
+
for (const line of readFileSync(transcriptPath, "utf8").split("\n")) {
|
|
157
157
|
if (!line.trim()) continue;
|
|
158
158
|
try {
|
|
159
159
|
const event = JSON.parse(line) as { event?: string; approval_id?: string };
|
|
@@ -162,7 +162,7 @@ export function assertWorkflowRunResumable(
|
|
|
162
162
|
}
|
|
163
163
|
if (event.event === "run.end") terminal = true;
|
|
164
164
|
} catch {
|
|
165
|
-
throw new Error(`workflow run ${runId} has a malformed
|
|
165
|
+
throw new Error(`workflow run ${runId} has a malformed transcript line`);
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
if (terminal) throw new Error(`workflow run ${runId} is already terminal`);
|
|
@@ -270,8 +270,8 @@ function validExecution(value: WorkflowRunManifest["execution"]): boolean {
|
|
|
270
270
|
if (!value || typeof value !== "object") return false;
|
|
271
271
|
return (
|
|
272
272
|
isAbsolute(value.cwd) &&
|
|
273
|
-
typeof value.
|
|
274
|
-
value.
|
|
273
|
+
typeof value.default_adapter === "string" &&
|
|
274
|
+
value.default_adapter.length > 0 &&
|
|
275
275
|
positiveSafeInteger(value.max_agents) &&
|
|
276
276
|
positiveSafeInteger(value.concurrency) &&
|
|
277
277
|
typeof value.subscription_only === "boolean" &&
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Project the host's filesystem policy into a
|
|
2
|
+
* Project the host's filesystem policy into a adapter's own vendor sandbox
|
|
3
3
|
* (ADR 0039).
|
|
4
4
|
*
|
|
5
5
|
* Harnery decides where a workflow child may write. Until this existed it never
|
|
@@ -14,12 +14,12 @@
|
|
|
14
14
|
* not, which is worse than refusing and worse than never offering the feature.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import type {
|
|
17
|
+
import type { AdapterSandboxProjection } from "../adapters/types.ts";
|
|
18
18
|
import type { GitAdministrativeGrant, SpawnFilesystemPolicy } from "./types.ts";
|
|
19
19
|
import type { WorkspaceBinding } from "./workspaces/types.ts";
|
|
20
20
|
|
|
21
21
|
export class SandboxProjectionError extends Error {
|
|
22
|
-
readonly
|
|
22
|
+
readonly adapter: string;
|
|
23
23
|
readonly reason:
|
|
24
24
|
| "mode_unrepresentable"
|
|
25
25
|
| "writable_roots_unrepresentable"
|
|
@@ -27,10 +27,10 @@ export class SandboxProjectionError extends Error {
|
|
|
27
27
|
| "writable_root_escapes_workspace"
|
|
28
28
|
| "git_grant_unavailable";
|
|
29
29
|
|
|
30
|
-
constructor(
|
|
30
|
+
constructor(adapter: string, reason: SandboxProjectionError["reason"], message: string) {
|
|
31
31
|
super(message);
|
|
32
32
|
this.name = "SandboxProjectionError";
|
|
33
|
-
this.
|
|
33
|
+
this.adapter = adapter;
|
|
34
34
|
this.reason = reason;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -46,31 +46,31 @@ export interface ResolvedSandboxProjection {
|
|
|
46
46
|
* Throws rather than degrading; see the module note.
|
|
47
47
|
*/
|
|
48
48
|
export function resolveSandboxProjection(
|
|
49
|
-
|
|
50
|
-
declaration:
|
|
49
|
+
adapter: string,
|
|
50
|
+
declaration: AdapterSandboxProjection | undefined,
|
|
51
51
|
policy: SpawnFilesystemPolicy,
|
|
52
52
|
): ResolvedSandboxProjection {
|
|
53
53
|
if (!declaration) {
|
|
54
54
|
throw new SandboxProjectionError(
|
|
55
|
-
|
|
55
|
+
adapter,
|
|
56
56
|
"no_projection",
|
|
57
|
-
`${
|
|
57
|
+
`${adapter} cannot project a filesystem policy into its sandbox; remove the policy or use a adapter that can`,
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
60
|
const nativeMode = declaration.modes[policy.mode];
|
|
61
61
|
if (!nativeMode) {
|
|
62
62
|
throw new SandboxProjectionError(
|
|
63
|
-
|
|
63
|
+
adapter,
|
|
64
64
|
"mode_unrepresentable",
|
|
65
|
-
`${
|
|
65
|
+
`${adapter} does not distinguish the "${policy.mode}" filesystem mode, so it cannot be enforced`,
|
|
66
66
|
);
|
|
67
67
|
}
|
|
68
68
|
const writableRoots = policy.writableRoots ?? [];
|
|
69
69
|
if (writableRoots.length > 0 && !declaration.writableRoots) {
|
|
70
70
|
throw new SandboxProjectionError(
|
|
71
|
-
|
|
71
|
+
adapter,
|
|
72
72
|
"writable_roots_unrepresentable",
|
|
73
|
-
`${
|
|
73
|
+
`${adapter} does not accept an explicit writable-root set, so ${writableRoots.length} declared path(s) could not be enforced`,
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
76
|
for (const root of writableRoots) {
|
|
@@ -78,7 +78,7 @@ export function resolveSandboxProjection(
|
|
|
78
78
|
// resolved differently by every vendor, so they are refused outright.
|
|
79
79
|
if (typeof root !== "string" || !root.startsWith("/")) {
|
|
80
80
|
throw new SandboxProjectionError(
|
|
81
|
-
|
|
81
|
+
adapter,
|
|
82
82
|
"writable_roots_unrepresentable",
|
|
83
83
|
`writable root ${JSON.stringify(root)} must be an absolute path`,
|
|
84
84
|
);
|
|
@@ -103,14 +103,14 @@ function isWithin(root: string, candidate: string): boolean {
|
|
|
103
103
|
* radius of a run that the workspace lifecycle believes it has contained.
|
|
104
104
|
*/
|
|
105
105
|
export function assertProjectionWithinWorkspace(
|
|
106
|
-
|
|
106
|
+
adapter: string,
|
|
107
107
|
allowedRootRealpath: string,
|
|
108
108
|
writableRoots: readonly string[],
|
|
109
109
|
): void {
|
|
110
110
|
for (const root of writableRoots) {
|
|
111
111
|
if (!isWithin(allowedRootRealpath, root)) {
|
|
112
112
|
throw new SandboxProjectionError(
|
|
113
|
-
|
|
113
|
+
adapter,
|
|
114
114
|
"writable_root_escapes_workspace",
|
|
115
115
|
`writable root ${JSON.stringify(root)} is outside the workspace root ${JSON.stringify(allowedRootRealpath)} the provider validated`,
|
|
116
116
|
);
|