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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow engine: loads a workflow script (plain JS, `export default
|
|
3
|
-
* async (ctx) => …`), injects the ctx API, enforces the caps,
|
|
4
|
-
* step to `.harnery/workflows/<run-id>/
|
|
3
|
+
* async (ctx) => …`), injects the ctx API, enforces the caps, transcripts every
|
|
4
|
+
* step to `.harnery/workflows/<run-id>/transcript.jsonl`, and returns a RunReport.
|
|
5
5
|
*
|
|
6
6
|
* Guarantees the engine makes (the pitch, in code):
|
|
7
7
|
* - **Bounded**: hard total-agent ceiling + bounded parallel() concurrency.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* validate; failures re-prompt with the validation errors appended, up to
|
|
14
14
|
* `maxAttempts`, then throw. Routing decisions read validated fields, so
|
|
15
15
|
* the deterministic script — not a model — decides what runs next.
|
|
16
|
-
* - **
|
|
16
|
+
* - **Transcripted**: every stage/agent start+end lands in the run transcript with
|
|
17
17
|
* cost, duration, and child session id (the resume + web-UI substrate).
|
|
18
18
|
*/
|
|
19
19
|
|
|
@@ -39,7 +39,7 @@ import { assertWorkflowRunId, createWorkflowApproval } from "./approvals.ts";
|
|
|
39
39
|
import { freezeWorkflowAttemptContext } from "./attempt-context.ts";
|
|
40
40
|
import { type BillingProbe, probeBilling } from "./billing.ts";
|
|
41
41
|
import { stableDigest } from "./durable-record.ts";
|
|
42
|
-
import {
|
|
42
|
+
import { evidencePreflightError } from "./evidence-preflight.ts";
|
|
43
43
|
import {
|
|
44
44
|
buildWorkflowProof,
|
|
45
45
|
createEvidenceRecord,
|
|
@@ -56,11 +56,13 @@ import {
|
|
|
56
56
|
} from "./run-state.ts";
|
|
57
57
|
import { assertProjectionWithinWorkspace, resolveGitGrantRoots } from "./sandbox-projection.ts";
|
|
58
58
|
import { normalizeWorkflowSpecialists, resolveSpecialistAssignment } from "./specialists.ts";
|
|
59
|
+
import { appendWorkflowTranscriptEvent } from "./transcript.ts";
|
|
59
60
|
import type {
|
|
61
|
+
AdapterName,
|
|
60
62
|
AgentOpts,
|
|
63
|
+
BlockedInput,
|
|
61
64
|
EngineOpts,
|
|
62
65
|
GitAdministrativeGrant,
|
|
63
|
-
HarnessName,
|
|
64
66
|
RunReport,
|
|
65
67
|
SpawnFilesystemPolicy,
|
|
66
68
|
SpawnResult,
|
|
@@ -126,14 +128,35 @@ export class WorkflowRunError extends Error {
|
|
|
126
128
|
export class WorkflowParkedError extends Error {
|
|
127
129
|
readonly runId: string;
|
|
128
130
|
readonly approvalId: string;
|
|
129
|
-
readonly
|
|
131
|
+
readonly transcriptPath: string;
|
|
130
132
|
|
|
131
|
-
constructor(message: string, runId: string, approvalId: string,
|
|
133
|
+
constructor(message: string, runId: string, approvalId: string, transcriptPath: string) {
|
|
132
134
|
super(message);
|
|
133
135
|
this.name = "WorkflowParkedError";
|
|
134
136
|
this.runId = runId;
|
|
135
137
|
this.approvalId = approvalId;
|
|
136
|
-
this.
|
|
138
|
+
this.transcriptPath = transcriptPath;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Thrown by ctx.blocked(). Carries the run out of the script and into the
|
|
143
|
+
* failure path, where its presence — not its message — is what stamps the proof
|
|
144
|
+
* with class "decision". A script cannot fake this by throwing an ordinary
|
|
145
|
+
* Error with a suggestive message, which is the point: the class has to mean
|
|
146
|
+
* "the script deliberately declared this", not "the text looked like it". */
|
|
147
|
+
export class WorkflowBlockedError extends Error {
|
|
148
|
+
readonly reason: string;
|
|
149
|
+
readonly decisionId?: string;
|
|
150
|
+
|
|
151
|
+
constructor(reason: string, decisionId?: string) {
|
|
152
|
+
super(
|
|
153
|
+
decisionId
|
|
154
|
+
? `blocked on decision ${decisionId}: ${reason}`
|
|
155
|
+
: `blocked pending a human decision: ${reason}`,
|
|
156
|
+
);
|
|
157
|
+
this.name = "WorkflowBlockedError";
|
|
158
|
+
this.reason = reason;
|
|
159
|
+
this.decisionId = decisionId;
|
|
137
160
|
}
|
|
138
161
|
}
|
|
139
162
|
|
|
@@ -216,6 +239,20 @@ export async function runWorkflow(scriptPath: string, opts: EngineOpts): Promise
|
|
|
216
239
|
}
|
|
217
240
|
}
|
|
218
241
|
|
|
242
|
+
/** Throws when the script names an evidence kind the proof layer will refuse.
|
|
243
|
+
* Silent when the file cannot be read: the import a moment later will produce a
|
|
244
|
+
* better error than a guess from here would. */
|
|
245
|
+
function assertEvidenceKindsAreUsable(scriptPath: string, absScript: string): void {
|
|
246
|
+
let source: string;
|
|
247
|
+
try {
|
|
248
|
+
source = readFileSync(absScript, "utf8");
|
|
249
|
+
} catch {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const message = evidencePreflightError(source, scriptPath);
|
|
253
|
+
if (message) throw new Error(message);
|
|
254
|
+
}
|
|
255
|
+
|
|
219
256
|
async function executeWorkflow(
|
|
220
257
|
scriptPath: string,
|
|
221
258
|
absScript: string,
|
|
@@ -226,6 +263,10 @@ async function executeWorkflow(
|
|
|
226
263
|
): Promise<RunReport> {
|
|
227
264
|
const frozen = resumeState?.manifest.execution;
|
|
228
265
|
const isolation = frozen?.isolation ?? opts.isolation ?? "shared";
|
|
266
|
+
// Before anything is spawned, and before either import path below: an evidence
|
|
267
|
+
// kind the proof will reject is fatal at the END of a workflow, which is the
|
|
268
|
+
// most expensive place to learn it. Reading the file is the cheapest moment.
|
|
269
|
+
assertEvidenceKindsAreUsable(scriptPath, absScript);
|
|
229
270
|
let sharedWorkflow: WorkflowModule["default"] | undefined;
|
|
230
271
|
let sharedMeta: ReturnType<typeof normalizeWorkflowMeta> | undefined;
|
|
231
272
|
if (isolation === "shared") {
|
|
@@ -244,7 +285,7 @@ async function executeWorkflow(
|
|
|
244
285
|
`wf-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
|
|
245
286
|
const runDir = join(opts.coordRoot, ".harnery", "workflows", runId);
|
|
246
287
|
mkdirSync(runDir, { recursive: true });
|
|
247
|
-
const
|
|
288
|
+
const transcriptPath = join(runDir, "transcript.jsonl");
|
|
248
289
|
const proofPath = join(runDir, "proof.json");
|
|
249
290
|
|
|
250
291
|
const maxAgents = frozen?.max_agents ?? opts.maxAgents ?? DEFAULT_MAX_AGENTS;
|
|
@@ -253,8 +294,8 @@ async function executeWorkflow(
|
|
|
253
294
|
assertPositiveWorkflowBound(concurrency, "concurrency");
|
|
254
295
|
const cwd = frozen?.cwd ?? opts.cwd ?? opts.coordRoot;
|
|
255
296
|
const log = opts.onLog ?? ((line: string) => process.stderr.write(`${line}\n`));
|
|
256
|
-
const
|
|
257
|
-
frozen?.
|
|
297
|
+
const defaultAdapter: AdapterName =
|
|
298
|
+
frozen?.default_adapter ?? opts.defaultAdapter ?? "claude-code";
|
|
258
299
|
const specialists =
|
|
259
300
|
frozen?.specialists ?? (resumeState ? {} : normalizeWorkflowSpecialists(opts.specialists));
|
|
260
301
|
const networkAccess = frozen?.network_access ?? opts.networkAccess ?? "unknown";
|
|
@@ -297,19 +338,19 @@ async function executeWorkflow(
|
|
|
297
338
|
const endedAt = new Date().toISOString();
|
|
298
339
|
const durationMs = Date.now() - t0;
|
|
299
340
|
const failedAttestation = await attestWorkspaceFailure(workspaceProvider, frozenBinding, error);
|
|
300
|
-
|
|
341
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "run.resume", {
|
|
301
342
|
approval_id: resumeState.approvalId,
|
|
302
343
|
script: absScript,
|
|
303
344
|
resumed_at: new Date().toISOString(),
|
|
304
345
|
});
|
|
305
|
-
|
|
346
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.failed", {
|
|
306
347
|
binding_id: frozenBinding.binding_id,
|
|
307
348
|
provider_id: frozenBinding.provider.id,
|
|
308
349
|
status: failedAttestation.status,
|
|
309
350
|
reason: failure.message,
|
|
310
351
|
attestation_sha256: stableDigest(failedAttestation),
|
|
311
352
|
});
|
|
312
|
-
|
|
353
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "run.end", {
|
|
313
354
|
ok: false,
|
|
314
355
|
error: failure.message,
|
|
315
356
|
agents: 0,
|
|
@@ -328,13 +369,13 @@ async function executeWorkflow(
|
|
|
328
369
|
startedAt,
|
|
329
370
|
endedAt,
|
|
330
371
|
durationMs,
|
|
331
|
-
|
|
372
|
+
transcriptPath,
|
|
332
373
|
before: resumeState.manifest.repository_before,
|
|
333
374
|
after: resumeState.manifest.repository_before,
|
|
334
375
|
agents: [],
|
|
335
376
|
evidence: [],
|
|
336
|
-
|
|
337
|
-
|
|
377
|
+
adapterEvidence: opts.adapterEvidence,
|
|
378
|
+
adapterAttestations: opts.adapterAttestations,
|
|
338
379
|
sandboxProjection: sandboxProjectionEvidence(
|
|
339
380
|
opts.filesystemPolicy,
|
|
340
381
|
opts.gitWrite ?? "none",
|
|
@@ -412,7 +453,7 @@ async function executeWorkflow(
|
|
|
412
453
|
repository_before: executionRepoBefore,
|
|
413
454
|
execution: {
|
|
414
455
|
cwd: executionCwd,
|
|
415
|
-
|
|
456
|
+
default_adapter: defaultAdapter,
|
|
416
457
|
max_agents: maxAgents,
|
|
417
458
|
concurrency,
|
|
418
459
|
subscription_only: subscriptionOnly,
|
|
@@ -455,11 +496,16 @@ async function executeWorkflow(
|
|
|
455
496
|
: undefined;
|
|
456
497
|
throw new Error("workspace authority changed during workflow module initialization");
|
|
457
498
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
499
|
+
appendWorkflowTranscriptEvent(
|
|
500
|
+
opts.coordRoot,
|
|
501
|
+
runId,
|
|
502
|
+
"workspace.reattach.module_initialized",
|
|
503
|
+
{
|
|
504
|
+
binding_id: workspaceBinding.binding_id,
|
|
505
|
+
provider_id: workspaceBinding.provider.id,
|
|
506
|
+
attestation_sha256: stableDigest(postImport),
|
|
507
|
+
},
|
|
508
|
+
);
|
|
463
509
|
} catch (error) {
|
|
464
510
|
const reattachmentError = error instanceof Error ? error : new Error(String(error));
|
|
465
511
|
initializationAttestation ??= await attestWorkspaceFailure(
|
|
@@ -472,7 +518,7 @@ async function executeWorkflow(
|
|
|
472
518
|
cause: reattachmentError,
|
|
473
519
|
})
|
|
474
520
|
: reattachmentError;
|
|
475
|
-
|
|
521
|
+
appendWorkflowTranscriptEvent(
|
|
476
522
|
opts.coordRoot,
|
|
477
523
|
runId,
|
|
478
524
|
"workspace.reattach.module_initialization_failed",
|
|
@@ -500,13 +546,13 @@ async function executeWorkflow(
|
|
|
500
546
|
);
|
|
501
547
|
}
|
|
502
548
|
|
|
503
|
-
// Resume:
|
|
549
|
+
// Resume: transcripted results of a prior run, keyed by agent-call identity.
|
|
504
550
|
const resumeSource = opts.resumeRunId ?? opts.resumeFrom;
|
|
505
551
|
const resumeCache = resumeSource
|
|
506
552
|
? loadResumeCache(opts.coordRoot, resumeSource)
|
|
507
553
|
: new Map<string, { kind: "json" | "text"; value: unknown }>();
|
|
508
554
|
|
|
509
|
-
const history = opts.resumeRunId ? loadRunHistory(
|
|
555
|
+
const history = opts.resumeRunId ? loadRunHistory(transcriptPath) : undefined;
|
|
510
556
|
|
|
511
557
|
let agentsSpawned = history?.agentsSpawned ?? 0;
|
|
512
558
|
let agentsCached = 0;
|
|
@@ -516,7 +562,7 @@ async function executeWorkflow(
|
|
|
516
562
|
let agentSeq = 0;
|
|
517
563
|
let evidenceSeq = 0;
|
|
518
564
|
let policySeq = 0;
|
|
519
|
-
const billingProbed = new Map<
|
|
565
|
+
const billingProbed = new Map<AdapterName, BillingProbe>();
|
|
520
566
|
const agentProofs = new Map<string, WorkflowAgentProof>();
|
|
521
567
|
const evidenceRecords: WorkflowEvidenceRecord[] = [];
|
|
522
568
|
const policyDecisions = new Map<string, PolicyDecision>(
|
|
@@ -524,10 +570,10 @@ async function executeWorkflow(
|
|
|
524
570
|
);
|
|
525
571
|
const acceptanceIds = new Set(meta.acceptance.map((criterion) => criterion.id));
|
|
526
572
|
|
|
527
|
-
const
|
|
528
|
-
|
|
573
|
+
const transcript = (event: string, data: Record<string, unknown>): void => {
|
|
574
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, event, { stage: currentStage, ...data });
|
|
529
575
|
};
|
|
530
|
-
const
|
|
576
|
+
const transcriptAgentEnd = (
|
|
531
577
|
data: Record<string, unknown>,
|
|
532
578
|
resultKind: "text" | "json",
|
|
533
579
|
result: unknown,
|
|
@@ -535,7 +581,7 @@ async function executeWorkflow(
|
|
|
535
581
|
// The writer shrinks an oversized record itself and names what it dropped,
|
|
536
582
|
// so no per-call fallback is needed here. A digest rides along regardless so
|
|
537
583
|
// a shrunk record can still be tied back to the exact result.
|
|
538
|
-
|
|
584
|
+
transcript("agent.end", {
|
|
539
585
|
...data,
|
|
540
586
|
result_kind: resultKind,
|
|
541
587
|
result_digest: digestResult(result, resultKind),
|
|
@@ -592,7 +638,7 @@ async function executeWorkflow(
|
|
|
592
638
|
const evaluation = evaluatePolicy(policy, request);
|
|
593
639
|
const id = `p${++policySeq}`;
|
|
594
640
|
const checkedAt = new Date().toISOString();
|
|
595
|
-
|
|
641
|
+
transcript("policy.check", {
|
|
596
642
|
id,
|
|
597
643
|
policy: policy.name,
|
|
598
644
|
policy_sha256: policyDigest(policy),
|
|
@@ -640,14 +686,14 @@ async function executeWorkflow(
|
|
|
640
686
|
});
|
|
641
687
|
if (stored.approval.status === "pending") {
|
|
642
688
|
if (stored.created) {
|
|
643
|
-
|
|
689
|
+
transcript("approval.requested", {
|
|
644
690
|
approval_id: stored.approval.request.id,
|
|
645
691
|
decision_id: id,
|
|
646
692
|
addressed_to: stored.approval.request.addressed_to,
|
|
647
693
|
request_sha256: stored.approval.request.request_sha256,
|
|
648
694
|
});
|
|
649
695
|
}
|
|
650
|
-
|
|
696
|
+
transcript("run.parked", {
|
|
651
697
|
approval_id: stored.approval.request.id,
|
|
652
698
|
decision_id: id,
|
|
653
699
|
phase: request.phase,
|
|
@@ -657,13 +703,13 @@ async function executeWorkflow(
|
|
|
657
703
|
`workflow parked for approval ${stored.approval.request.id}: ${evaluation.reason}`,
|
|
658
704
|
runId,
|
|
659
705
|
stored.approval.request.id,
|
|
660
|
-
|
|
706
|
+
transcriptPath,
|
|
661
707
|
);
|
|
662
708
|
}
|
|
663
709
|
verdict = stored.approval.decision!.verdict;
|
|
664
710
|
resolvedBy = "approval";
|
|
665
711
|
reason = boundedPolicyReason(stored.approval.decision!.reason ?? evaluation.reason);
|
|
666
|
-
|
|
712
|
+
transcript("approval.consumed", {
|
|
667
713
|
approval_id: stored.approval.request.id,
|
|
668
714
|
decision_id: id,
|
|
669
715
|
verdict,
|
|
@@ -686,7 +732,7 @@ async function executeWorkflow(
|
|
|
686
732
|
request,
|
|
687
733
|
};
|
|
688
734
|
policyDecisions.set(decision.id, decision);
|
|
689
|
-
|
|
735
|
+
transcript("policy.resolve", { ...decision });
|
|
690
736
|
if (decision.verdict === "deny") {
|
|
691
737
|
throw new PolicyDeniedError(
|
|
692
738
|
`policy ${JSON.stringify(policy.name)} denied ${request.phase} ${JSON.stringify(request.action)}: ${decision.reason}`,
|
|
@@ -705,11 +751,11 @@ async function executeWorkflow(
|
|
|
705
751
|
: assignmentPrompt;
|
|
706
752
|
let reservedForDispatch = 0;
|
|
707
753
|
let spawnCountClaimed = false;
|
|
708
|
-
const
|
|
709
|
-
const spawner = opts.spawners[
|
|
754
|
+
const adapter = agentOpts.adapter ?? defaultAdapter;
|
|
755
|
+
const spawner = opts.spawners[adapter];
|
|
710
756
|
if (!spawner) {
|
|
711
757
|
throw new Error(
|
|
712
|
-
`no spawner registered for
|
|
758
|
+
`no spawner registered for adapter "${adapter}" (registered: ${Object.keys(opts.spawners).join(", ") || "none"})`,
|
|
713
759
|
);
|
|
714
760
|
}
|
|
715
761
|
const id = `a${++agentSeq}`;
|
|
@@ -721,7 +767,7 @@ async function executeWorkflow(
|
|
|
721
767
|
label: proofLabel,
|
|
722
768
|
stage: currentStage || undefined,
|
|
723
769
|
specialist: agentOpts.specialist,
|
|
724
|
-
|
|
770
|
+
adapter,
|
|
725
771
|
model: agentOpts.model,
|
|
726
772
|
status: "failed",
|
|
727
773
|
attempts: 0,
|
|
@@ -729,9 +775,9 @@ async function executeWorkflow(
|
|
|
729
775
|
};
|
|
730
776
|
agentProofs.set(id, agentProof);
|
|
731
777
|
|
|
732
|
-
// Call identity for resume: same stage +
|
|
778
|
+
// Call identity for resume: same stage + adapter + model + effort + turns + schema
|
|
733
779
|
// + ORIGINAL prompt → same key. Retry-mutated prompts never enter the key.
|
|
734
|
-
const key = agentCallKey(currentStage,
|
|
780
|
+
const key = agentCallKey(currentStage, adapter, agentOpts, assignmentPrompt);
|
|
735
781
|
const cached = resumeCache.get(key);
|
|
736
782
|
if (cached) {
|
|
737
783
|
// Exact-run replay skips dispatch authorization because no dispatch
|
|
@@ -741,11 +787,11 @@ async function executeWorkflow(
|
|
|
741
787
|
agentsCached++;
|
|
742
788
|
agentProof.status = "cached";
|
|
743
789
|
agentProof.result = digestResult(cached.value, cached.kind);
|
|
744
|
-
|
|
790
|
+
transcript("agent.cached", {
|
|
745
791
|
id,
|
|
746
792
|
label,
|
|
747
793
|
key,
|
|
748
|
-
|
|
794
|
+
adapter,
|
|
749
795
|
specialist: agentOpts.specialist ?? null,
|
|
750
796
|
model: agentOpts.model ?? null,
|
|
751
797
|
kind: cached.kind,
|
|
@@ -761,7 +807,7 @@ async function executeWorkflow(
|
|
|
761
807
|
phase: "dispatch",
|
|
762
808
|
action: "spawn agent",
|
|
763
809
|
path: executionCwd,
|
|
764
|
-
|
|
810
|
+
adapter,
|
|
765
811
|
model: agentOpts.model,
|
|
766
812
|
effort: agentOpts.effort,
|
|
767
813
|
max_attempts: maxAttempts,
|
|
@@ -782,8 +828,8 @@ async function executeWorkflow(
|
|
|
782
828
|
}
|
|
783
829
|
projectedCost = candidate;
|
|
784
830
|
} catch (error) {
|
|
785
|
-
|
|
786
|
-
|
|
831
|
+
transcript("policy.cost_estimate_failed", {
|
|
832
|
+
adapter,
|
|
787
833
|
model: agentOpts.model ?? null,
|
|
788
834
|
error: boundedPolicyReason((error as Error).message),
|
|
789
835
|
});
|
|
@@ -819,17 +865,17 @@ async function executeWorkflow(
|
|
|
819
865
|
}
|
|
820
866
|
}
|
|
821
867
|
|
|
822
|
-
// Billing safeguard: on a
|
|
868
|
+
// Billing safeguard: on a adapter's FIRST spawn this run, classify which
|
|
823
869
|
// auth its children will use and refuse the silent-override state (an
|
|
824
870
|
// exported API key shadowing a stored subscription login) unless the
|
|
825
871
|
// caller explicitly opted into API billing. Cached agents never reach
|
|
826
872
|
// this — no spawn, no billing.
|
|
827
873
|
try {
|
|
828
|
-
if (!billingProbed.has(
|
|
829
|
-
const probe = (opts.probeBilling ?? probeBilling)(
|
|
830
|
-
billingProbed.set(
|
|
831
|
-
|
|
832
|
-
|
|
874
|
+
if (!billingProbed.has(adapter)) {
|
|
875
|
+
const probe = (opts.probeBilling ?? probeBilling)(adapter);
|
|
876
|
+
billingProbed.set(adapter, probe);
|
|
877
|
+
transcript("billing.probe", {
|
|
878
|
+
adapter,
|
|
833
879
|
mode: subscriptionOnly ? "subscription" : probe.mode,
|
|
834
880
|
api_key_source: probe.apiKeySource,
|
|
835
881
|
login: probe.login,
|
|
@@ -838,29 +884,29 @@ async function executeWorkflow(
|
|
|
838
884
|
if (subscriptionOnly) {
|
|
839
885
|
if (probe.login === "absent") {
|
|
840
886
|
throw new Error(
|
|
841
|
-
`subscription-only: no stored login detected for ${
|
|
842
|
-
`log the
|
|
887
|
+
`subscription-only: no stored login detected for ${adapter}; ` +
|
|
888
|
+
`log the adapter CLI in (or drop --subscription-only for a key-only host)`,
|
|
843
889
|
);
|
|
844
890
|
}
|
|
845
|
-
log(`[billing] ${
|
|
891
|
+
log(`[billing] ${adapter}: subscription-only (API-key vars scrubbed from child env)`);
|
|
846
892
|
} else if (probe.mode === "api-key-override" && !allowApiBilling) {
|
|
847
893
|
throw new Error(
|
|
848
|
-
`${probe.apiKeySource} is set AND a stored ${
|
|
894
|
+
`${probe.apiKeySource} is set AND a stored ${adapter} login exists — the key silently ` +
|
|
849
895
|
`overrides your subscription auth, so children would bill per-token API rates. ` +
|
|
850
896
|
`Either unset ${probe.apiKeySource}, run with --subscription-only to scrub it from ` +
|
|
851
897
|
`child envs, or pass --allow-api-billing if API billing is intended`,
|
|
852
898
|
);
|
|
853
899
|
} else if (probe.mode === "api-key") {
|
|
854
900
|
log(
|
|
855
|
-
`[billing] ${
|
|
901
|
+
`[billing] ${adapter}: API-key billing (${probe.apiKeySource}; no stored login detected) — ` +
|
|
856
902
|
`children bill per-token rates`,
|
|
857
903
|
);
|
|
858
904
|
} else if (probe.mode === "api-key-override") {
|
|
859
905
|
log(
|
|
860
|
-
`[billing] ${
|
|
906
|
+
`[billing] ${adapter}: API-key billing (--allow-api-billing; key overrides stored login)`,
|
|
861
907
|
);
|
|
862
908
|
} else {
|
|
863
|
-
log(`[billing] ${
|
|
909
|
+
log(`[billing] ${adapter}: subscription login`);
|
|
864
910
|
}
|
|
865
911
|
}
|
|
866
912
|
} catch (error) {
|
|
@@ -878,16 +924,16 @@ async function executeWorkflow(
|
|
|
878
924
|
|
|
879
925
|
await acquire();
|
|
880
926
|
try {
|
|
881
|
-
|
|
927
|
+
transcript("agent.start", {
|
|
882
928
|
id,
|
|
883
929
|
label,
|
|
884
930
|
key,
|
|
885
|
-
|
|
931
|
+
adapter,
|
|
886
932
|
specialist: agentOpts.specialist ?? null,
|
|
887
933
|
model: agentOpts.model ?? null,
|
|
888
934
|
effort: agentOpts.effort ?? null,
|
|
889
935
|
});
|
|
890
|
-
log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${
|
|
936
|
+
log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${adapter}] ${label}`);
|
|
891
937
|
|
|
892
938
|
let attemptPrompt = dispatchPrompt;
|
|
893
939
|
let last: SpawnResult | null = null;
|
|
@@ -901,6 +947,7 @@ async function executeWorkflow(
|
|
|
901
947
|
maxTurns: agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
902
948
|
cwd: executionCwd,
|
|
903
949
|
runId,
|
|
950
|
+
agentId: id,
|
|
904
951
|
subscriptionOnly,
|
|
905
952
|
filesystemPolicy,
|
|
906
953
|
});
|
|
@@ -910,7 +957,12 @@ async function executeWorkflow(
|
|
|
910
957
|
costUsd += last.costUsd ?? 0;
|
|
911
958
|
|
|
912
959
|
if (!last.ok) {
|
|
913
|
-
|
|
960
|
+
transcript("agent.attempt_failed", { id, attempt, error: last.error });
|
|
961
|
+
// ADR 0046: an environment failure (the binary was absent) cannot be
|
|
962
|
+
// helped by retrying an unchanged environment, so stop the in-agent
|
|
963
|
+
// retry too — not just the outer attempt/replan budget. An upstream
|
|
964
|
+
// refusal keeps retrying here: the vendor may recover mid-loop.
|
|
965
|
+
if (last.class === "environment") break;
|
|
914
966
|
continue; // spawn-level failure: retry with the original prompt
|
|
915
967
|
}
|
|
916
968
|
if (!agentOpts.schema) {
|
|
@@ -919,7 +971,7 @@ async function executeWorkflow(
|
|
|
919
971
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
920
972
|
agentProof.session_id = last.sessionId;
|
|
921
973
|
agentProof.result = digestResult(last.text, "text");
|
|
922
|
-
|
|
974
|
+
transcriptAgentEnd(
|
|
923
975
|
{
|
|
924
976
|
id,
|
|
925
977
|
key,
|
|
@@ -946,7 +998,7 @@ async function executeWorkflow(
|
|
|
946
998
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
947
999
|
agentProof.session_id = last.sessionId;
|
|
948
1000
|
agentProof.result = digestResult(parsed.value, "json");
|
|
949
|
-
|
|
1001
|
+
transcriptAgentEnd(
|
|
950
1002
|
{
|
|
951
1003
|
id,
|
|
952
1004
|
key,
|
|
@@ -962,7 +1014,7 @@ async function executeWorkflow(
|
|
|
962
1014
|
return parsed.value;
|
|
963
1015
|
}
|
|
964
1016
|
|
|
965
|
-
|
|
1017
|
+
transcript("agent.schema_retry", { id, attempt, problems });
|
|
966
1018
|
// Keep the original cache identity while making the actual output
|
|
967
1019
|
// contract explicit. A full bounded copy of the rejected value lets the
|
|
968
1020
|
// child repair omissions instead of reconstructing an unseen object.
|
|
@@ -982,7 +1034,13 @@ async function executeWorkflow(
|
|
|
982
1034
|
agentCostUsd > 0 || last?.costUsd !== undefined ? agentCostUsd : undefined;
|
|
983
1035
|
agentProof.session_id = last?.sessionId;
|
|
984
1036
|
agentProof.error = reason;
|
|
985
|
-
|
|
1037
|
+
// Carry the spawn class (environment/upstream) onto the proof only when the
|
|
1038
|
+
// final outcome was a spawn failure. A schema failure after a spawn that
|
|
1039
|
+
// reached the model is a work failure — left unclassed (charged). An
|
|
1040
|
+
// earlier attempt that transiently failed and then succeeded returned
|
|
1041
|
+
// above, so this only fires when the agent genuinely failed.
|
|
1042
|
+
if (last && !last.ok && last.class) agentProof.class = last.class;
|
|
1043
|
+
transcript("agent.failed", { id, error: reason });
|
|
986
1044
|
throw new Error(`agent ${proofLabel}: ${reason}`);
|
|
987
1045
|
} catch (error) {
|
|
988
1046
|
agentProof.error ??= (error as Error).message;
|
|
@@ -1000,7 +1058,7 @@ async function executeWorkflow(
|
|
|
1000
1058
|
return Promise.all(
|
|
1001
1059
|
thunks.map((t) =>
|
|
1002
1060
|
t().catch((err: unknown) => {
|
|
1003
|
-
|
|
1061
|
+
transcript("parallel.item_failed", { error: (err as Error).message });
|
|
1004
1062
|
return null;
|
|
1005
1063
|
}),
|
|
1006
1064
|
),
|
|
@@ -1009,7 +1067,7 @@ async function executeWorkflow(
|
|
|
1009
1067
|
|
|
1010
1068
|
const stage = (title: string): void => {
|
|
1011
1069
|
currentStage = title;
|
|
1012
|
-
|
|
1070
|
+
transcript("stage.start", { title });
|
|
1013
1071
|
log(`[${name}] ── stage: ${title}`);
|
|
1014
1072
|
};
|
|
1015
1073
|
|
|
@@ -1022,7 +1080,7 @@ async function executeWorkflow(
|
|
|
1022
1080
|
});
|
|
1023
1081
|
evidenceSeq++;
|
|
1024
1082
|
evidenceRecords.push(record);
|
|
1025
|
-
|
|
1083
|
+
transcript("evidence.recorded", { ...record });
|
|
1026
1084
|
return record.id;
|
|
1027
1085
|
};
|
|
1028
1086
|
|
|
@@ -1043,6 +1101,16 @@ async function executeWorkflow(
|
|
|
1043
1101
|
});
|
|
1044
1102
|
};
|
|
1045
1103
|
|
|
1104
|
+
const blocked = (input: BlockedInput): never => {
|
|
1105
|
+
const reason = input.reason.trim();
|
|
1106
|
+
if (!reason) throw new Error("ctx.blocked() requires a reason");
|
|
1107
|
+
transcript("run.blocked", {
|
|
1108
|
+
reason,
|
|
1109
|
+
...(input.decision ? { decision_id: input.decision } : {}),
|
|
1110
|
+
});
|
|
1111
|
+
throw new WorkflowBlockedError(reason, input.decision);
|
|
1112
|
+
};
|
|
1113
|
+
|
|
1046
1114
|
const ctx: WorkflowContext = {
|
|
1047
1115
|
work: workContext,
|
|
1048
1116
|
attempt: attemptContext,
|
|
@@ -1052,16 +1120,17 @@ async function executeWorkflow(
|
|
|
1052
1120
|
log,
|
|
1053
1121
|
evidence,
|
|
1054
1122
|
authorize,
|
|
1123
|
+
blocked,
|
|
1055
1124
|
};
|
|
1056
1125
|
try {
|
|
1057
1126
|
if (resumeState) {
|
|
1058
|
-
|
|
1127
|
+
transcript("run.resume", {
|
|
1059
1128
|
approval_id: resumeState.approvalId,
|
|
1060
1129
|
script: absScript,
|
|
1061
1130
|
resumed_at: new Date().toISOString(),
|
|
1062
1131
|
});
|
|
1063
1132
|
} else {
|
|
1064
|
-
|
|
1133
|
+
transcript("run.start", {
|
|
1065
1134
|
name,
|
|
1066
1135
|
work_item_id: opts.workItemId ?? null,
|
|
1067
1136
|
work_context: workContext ?? null,
|
|
@@ -1096,7 +1165,7 @@ async function executeWorkflow(
|
|
|
1096
1165
|
}`,
|
|
1097
1166
|
);
|
|
1098
1167
|
}
|
|
1099
|
-
|
|
1168
|
+
transcript("run.end", {
|
|
1100
1169
|
ok: true,
|
|
1101
1170
|
agents: agentsSpawned,
|
|
1102
1171
|
cached: agentsCached,
|
|
@@ -1115,13 +1184,13 @@ async function executeWorkflow(
|
|
|
1115
1184
|
startedAt,
|
|
1116
1185
|
endedAt,
|
|
1117
1186
|
durationMs,
|
|
1118
|
-
|
|
1187
|
+
transcriptPath,
|
|
1119
1188
|
before: executionRepoBefore,
|
|
1120
1189
|
after: snapshotRepo(executionCwd),
|
|
1121
1190
|
agents: Array.from(agentProofs.values()),
|
|
1122
1191
|
evidence: evidenceRecords,
|
|
1123
|
-
|
|
1124
|
-
|
|
1192
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1193
|
+
adapterAttestations: opts.adapterAttestations,
|
|
1125
1194
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
1126
1195
|
policy: policy
|
|
1127
1196
|
? {
|
|
@@ -1154,12 +1223,12 @@ async function executeWorkflow(
|
|
|
1154
1223
|
agentsCached,
|
|
1155
1224
|
costUsd: round4(costUsd),
|
|
1156
1225
|
durationMs,
|
|
1157
|
-
|
|
1226
|
+
transcriptPath,
|
|
1158
1227
|
proofPath,
|
|
1159
1228
|
acceptance: proof.acceptance.summary,
|
|
1160
1229
|
contextTokensPerChildEstimate,
|
|
1161
1230
|
billing: Array.from(billingProbed.values()).map((p) => ({
|
|
1162
|
-
|
|
1231
|
+
adapter: p.adapter,
|
|
1163
1232
|
mode: subscriptionOnly ? "subscription" : p.mode,
|
|
1164
1233
|
})),
|
|
1165
1234
|
policy: proof.policy?.summary,
|
|
@@ -1173,7 +1242,7 @@ async function executeWorkflow(
|
|
|
1173
1242
|
if (err instanceof WorkflowRunError) throw err;
|
|
1174
1243
|
const endedAt = new Date().toISOString();
|
|
1175
1244
|
const durationMs = Date.now() - t0;
|
|
1176
|
-
|
|
1245
|
+
transcript("run.end", {
|
|
1177
1246
|
ok: false,
|
|
1178
1247
|
error: (err as Error).message,
|
|
1179
1248
|
agents: agentsSpawned,
|
|
@@ -1196,13 +1265,13 @@ async function executeWorkflow(
|
|
|
1196
1265
|
startedAt,
|
|
1197
1266
|
endedAt,
|
|
1198
1267
|
durationMs,
|
|
1199
|
-
|
|
1268
|
+
transcriptPath,
|
|
1200
1269
|
before: executionRepoBefore,
|
|
1201
1270
|
after: snapshotRepo(executionCwd),
|
|
1202
1271
|
agents: Array.from(agentProofs.values()),
|
|
1203
1272
|
evidence: evidenceRecords,
|
|
1204
|
-
|
|
1205
|
-
|
|
1273
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1274
|
+
adapterAttestations: opts.adapterAttestations,
|
|
1206
1275
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
1207
1276
|
policy: policy
|
|
1208
1277
|
? {
|
|
@@ -1216,6 +1285,13 @@ async function executeWorkflow(
|
|
|
1216
1285
|
workspaceAttestation,
|
|
1217
1286
|
workspaceFallback,
|
|
1218
1287
|
error: (err as Error).message,
|
|
1288
|
+
// A deliberate stop-on-human, not a work failure. Overrides whatever the
|
|
1289
|
+
// agents' own classes would have derived: the script's determination is
|
|
1290
|
+
// the more specific fact about why this run ended.
|
|
1291
|
+
blocked:
|
|
1292
|
+
err instanceof WorkflowBlockedError
|
|
1293
|
+
? { reason: err.reason, decisionId: err.decisionId }
|
|
1294
|
+
: undefined,
|
|
1219
1295
|
});
|
|
1220
1296
|
writeWorkflowProof(proofPath, proof);
|
|
1221
1297
|
} catch (proofError) {
|
|
@@ -1249,13 +1325,13 @@ function boundedSchemaReply(value: string): string {
|
|
|
1249
1325
|
* prompt (never a retry-mutated one) plus everything that changes behavior. */
|
|
1250
1326
|
function agentCallKey(
|
|
1251
1327
|
stage: string,
|
|
1252
|
-
|
|
1328
|
+
adapter: string,
|
|
1253
1329
|
agentOpts: AgentOpts,
|
|
1254
1330
|
prompt: string,
|
|
1255
1331
|
): string {
|
|
1256
1332
|
const parts: unknown[] = [
|
|
1257
1333
|
stage,
|
|
1258
|
-
|
|
1334
|
+
adapter,
|
|
1259
1335
|
agentOpts.model ?? null,
|
|
1260
1336
|
agentOpts.effort ?? null,
|
|
1261
1337
|
agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
@@ -1284,17 +1360,17 @@ function estimateInstructionTokens(cwd: string): number {
|
|
|
1284
1360
|
return 0;
|
|
1285
1361
|
}
|
|
1286
1362
|
|
|
1287
|
-
/** Load a prior run's
|
|
1363
|
+
/** Load a prior run's transcript into a key → result map. Only `agent.end`
|
|
1288
1364
|
* entries (completed, validated) are resumable; failed or retried-out agents
|
|
1289
|
-
* re-run live. Unreadable
|
|
1365
|
+
* re-run live. Unreadable transcript → error (a typo'd run id should fail loud,
|
|
1290
1366
|
* not silently run everything fresh). */
|
|
1291
1367
|
function loadResumeCache(
|
|
1292
1368
|
coordRoot: string,
|
|
1293
1369
|
resumeFrom: string,
|
|
1294
1370
|
): Map<string, { kind: "json" | "text"; value: unknown }> {
|
|
1295
|
-
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "
|
|
1371
|
+
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "transcript.jsonl");
|
|
1296
1372
|
if (!existsSync(path)) {
|
|
1297
|
-
throw new Error(`--resume-from ${resumeFrom}: no
|
|
1373
|
+
throw new Error(`--resume-from ${resumeFrom}: no transcript at ${path}`);
|
|
1298
1374
|
}
|
|
1299
1375
|
const cache = new Map<string, { kind: "json" | "text"; value: unknown }>();
|
|
1300
1376
|
for (const line of readFileSync(path, "utf8").split("\n")) {
|