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
|
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
@@ -34,11 +34,12 @@ import { assertWorkflowRunId, createWorkflowApproval } from "./approvals.js";
|
|
|
34
34
|
import { freezeWorkflowAttemptContext } from "./attempt-context.js";
|
|
35
35
|
import { probeBilling } from "./billing.js";
|
|
36
36
|
import { stableDigest } from "./durable-record.js";
|
|
37
|
-
import {
|
|
37
|
+
import { evidencePreflightError } from "./evidence-preflight.js";
|
|
38
38
|
import { buildWorkflowProof, createEvidenceRecord, digestResult, normalizeWorkflowMeta, writeWorkflowProof, } from "./proof.js";
|
|
39
39
|
import { acquireWorkflowResumeLease, assertWorkflowRunResumable, assertWorkflowScriptUnchanged, workflowScriptDigest, writeWorkflowRunManifest, } from "./run-state.js";
|
|
40
40
|
import { assertProjectionWithinWorkspace, resolveGitGrantRoots } from "./sandbox-projection.js";
|
|
41
41
|
import { normalizeWorkflowSpecialists, resolveSpecialistAssignment } from "./specialists.js";
|
|
42
|
+
import { appendWorkflowTranscriptEvent } from "./transcript.js";
|
|
42
43
|
import { parseStageOutput, validateAgainstSchema } from "./validate.js";
|
|
43
44
|
import { freezeWorkflowWorkContext } from "./work-context.js";
|
|
44
45
|
import { attestTerminal, attestWorkspaceFailure, resolveWorkspaceBinding, } from "./workspaces/execution.js";
|
|
@@ -75,13 +76,30 @@ export class WorkflowRunError extends Error {
|
|
|
75
76
|
export class WorkflowParkedError extends Error {
|
|
76
77
|
runId;
|
|
77
78
|
approvalId;
|
|
78
|
-
|
|
79
|
-
constructor(message, runId, approvalId,
|
|
79
|
+
transcriptPath;
|
|
80
|
+
constructor(message, runId, approvalId, transcriptPath) {
|
|
80
81
|
super(message);
|
|
81
82
|
this.name = "WorkflowParkedError";
|
|
82
83
|
this.runId = runId;
|
|
83
84
|
this.approvalId = approvalId;
|
|
84
|
-
this.
|
|
85
|
+
this.transcriptPath = transcriptPath;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** Thrown by ctx.blocked(). Carries the run out of the script and into the
|
|
89
|
+
* failure path, where its presence — not its message — is what stamps the proof
|
|
90
|
+
* with class "decision". A script cannot fake this by throwing an ordinary
|
|
91
|
+
* Error with a suggestive message, which is the point: the class has to mean
|
|
92
|
+
* "the script deliberately declared this", not "the text looked like it". */
|
|
93
|
+
export class WorkflowBlockedError extends Error {
|
|
94
|
+
reason;
|
|
95
|
+
decisionId;
|
|
96
|
+
constructor(reason, decisionId) {
|
|
97
|
+
super(decisionId
|
|
98
|
+
? `blocked on decision ${decisionId}: ${reason}`
|
|
99
|
+
: `blocked pending a human decision: ${reason}`);
|
|
100
|
+
this.name = "WorkflowBlockedError";
|
|
101
|
+
this.reason = reason;
|
|
102
|
+
this.decisionId = decisionId;
|
|
85
103
|
}
|
|
86
104
|
}
|
|
87
105
|
export async function runWorkflow(scriptPath, opts) {
|
|
@@ -151,9 +169,28 @@ export async function runWorkflow(scriptPath, opts) {
|
|
|
151
169
|
releaseResumeLease?.();
|
|
152
170
|
}
|
|
153
171
|
}
|
|
172
|
+
/** Throws when the script names an evidence kind the proof layer will refuse.
|
|
173
|
+
* Silent when the file cannot be read: the import a moment later will produce a
|
|
174
|
+
* better error than a guess from here would. */
|
|
175
|
+
function assertEvidenceKindsAreUsable(scriptPath, absScript) {
|
|
176
|
+
let source;
|
|
177
|
+
try {
|
|
178
|
+
source = readFileSync(absScript, "utf8");
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const message = evidencePreflightError(source, scriptPath);
|
|
184
|
+
if (message)
|
|
185
|
+
throw new Error(message);
|
|
186
|
+
}
|
|
154
187
|
async function executeWorkflow(scriptPath, absScript, opts, resumeState, workContext, attemptContext) {
|
|
155
188
|
const frozen = resumeState?.manifest.execution;
|
|
156
189
|
const isolation = frozen?.isolation ?? opts.isolation ?? "shared";
|
|
190
|
+
// Before anything is spawned, and before either import path below: an evidence
|
|
191
|
+
// kind the proof will reject is fatal at the END of a workflow, which is the
|
|
192
|
+
// most expensive place to learn it. Reading the file is the cheapest moment.
|
|
193
|
+
assertEvidenceKindsAreUsable(scriptPath, absScript);
|
|
157
194
|
let sharedWorkflow;
|
|
158
195
|
let sharedMeta;
|
|
159
196
|
if (isolation === "shared") {
|
|
@@ -170,7 +207,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
170
207
|
`wf-${new Date().toISOString().replace(/[:.]/g, "-")}-${randomBytes(3).toString("hex")}`;
|
|
171
208
|
const runDir = join(opts.coordRoot, ".harnery", "workflows", runId);
|
|
172
209
|
mkdirSync(runDir, { recursive: true });
|
|
173
|
-
const
|
|
210
|
+
const transcriptPath = join(runDir, "transcript.jsonl");
|
|
174
211
|
const proofPath = join(runDir, "proof.json");
|
|
175
212
|
const maxAgents = frozen?.max_agents ?? opts.maxAgents ?? DEFAULT_MAX_AGENTS;
|
|
176
213
|
const concurrency = frozen?.concurrency ?? opts.concurrency ?? DEFAULT_CONCURRENCY;
|
|
@@ -178,7 +215,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
178
215
|
assertPositiveWorkflowBound(concurrency, "concurrency");
|
|
179
216
|
const cwd = frozen?.cwd ?? opts.cwd ?? opts.coordRoot;
|
|
180
217
|
const log = opts.onLog ?? ((line) => process.stderr.write(`${line}\n`));
|
|
181
|
-
const
|
|
218
|
+
const defaultAdapter = frozen?.default_adapter ?? opts.defaultAdapter ?? "claude-code";
|
|
182
219
|
const specialists = frozen?.specialists ?? (resumeState ? {} : normalizeWorkflowSpecialists(opts.specialists));
|
|
183
220
|
const networkAccess = frozen?.network_access ?? opts.networkAccess ?? "unknown";
|
|
184
221
|
const policy = frozen?.policy ?? (opts.policy ? normalizePolicy(opts.policy, { baseDir: cwd }) : undefined);
|
|
@@ -220,19 +257,19 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
220
257
|
const endedAt = new Date().toISOString();
|
|
221
258
|
const durationMs = Date.now() - t0;
|
|
222
259
|
const failedAttestation = await attestWorkspaceFailure(workspaceProvider, frozenBinding, error);
|
|
223
|
-
|
|
260
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "run.resume", {
|
|
224
261
|
approval_id: resumeState.approvalId,
|
|
225
262
|
script: absScript,
|
|
226
263
|
resumed_at: new Date().toISOString(),
|
|
227
264
|
});
|
|
228
|
-
|
|
265
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.failed", {
|
|
229
266
|
binding_id: frozenBinding.binding_id,
|
|
230
267
|
provider_id: frozenBinding.provider.id,
|
|
231
268
|
status: failedAttestation.status,
|
|
232
269
|
reason: failure.message,
|
|
233
270
|
attestation_sha256: stableDigest(failedAttestation),
|
|
234
271
|
});
|
|
235
|
-
|
|
272
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "run.end", {
|
|
236
273
|
ok: false,
|
|
237
274
|
error: failure.message,
|
|
238
275
|
agents: 0,
|
|
@@ -251,13 +288,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
251
288
|
startedAt,
|
|
252
289
|
endedAt,
|
|
253
290
|
durationMs,
|
|
254
|
-
|
|
291
|
+
transcriptPath,
|
|
255
292
|
before: resumeState.manifest.repository_before,
|
|
256
293
|
after: resumeState.manifest.repository_before,
|
|
257
294
|
agents: [],
|
|
258
295
|
evidence: [],
|
|
259
|
-
|
|
260
|
-
|
|
296
|
+
adapterEvidence: opts.adapterEvidence,
|
|
297
|
+
adapterAttestations: opts.adapterAttestations,
|
|
261
298
|
sandboxProjection: sandboxProjectionEvidence(opts.filesystemPolicy, opts.gitWrite ?? "none"),
|
|
262
299
|
policy: policy
|
|
263
300
|
? {
|
|
@@ -320,7 +357,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
320
357
|
repository_before: executionRepoBefore,
|
|
321
358
|
execution: {
|
|
322
359
|
cwd: executionCwd,
|
|
323
|
-
|
|
360
|
+
default_adapter: defaultAdapter,
|
|
324
361
|
max_agents: maxAgents,
|
|
325
362
|
concurrency,
|
|
326
363
|
subscription_only: subscriptionOnly,
|
|
@@ -363,7 +400,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
363
400
|
: undefined;
|
|
364
401
|
throw new Error("workspace authority changed during workflow module initialization");
|
|
365
402
|
}
|
|
366
|
-
|
|
403
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.module_initialized", {
|
|
367
404
|
binding_id: workspaceBinding.binding_id,
|
|
368
405
|
provider_id: workspaceBinding.provider.id,
|
|
369
406
|
attestation_sha256: stableDigest(postImport),
|
|
@@ -377,7 +414,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
377
414
|
cause: reattachmentError,
|
|
378
415
|
})
|
|
379
416
|
: reattachmentError;
|
|
380
|
-
|
|
417
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, "workspace.reattach.module_initialization_failed", {
|
|
381
418
|
binding_id: workspaceBinding.binding_id,
|
|
382
419
|
provider_id: workspaceBinding.provider.id,
|
|
383
420
|
status: initializationAttestation.status,
|
|
@@ -396,12 +433,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
396
433
|
log(`[context] each child cache-writes ~${Math.round(contextTokensPerChildEstimate / 1000)}K tokens of repo ` +
|
|
397
434
|
`instructions from ${executionCwd}; a fan-out multiplies this per agent`);
|
|
398
435
|
}
|
|
399
|
-
// Resume:
|
|
436
|
+
// Resume: transcripted results of a prior run, keyed by agent-call identity.
|
|
400
437
|
const resumeSource = opts.resumeRunId ?? opts.resumeFrom;
|
|
401
438
|
const resumeCache = resumeSource
|
|
402
439
|
? loadResumeCache(opts.coordRoot, resumeSource)
|
|
403
440
|
: new Map();
|
|
404
|
-
const history = opts.resumeRunId ? loadRunHistory(
|
|
441
|
+
const history = opts.resumeRunId ? loadRunHistory(transcriptPath) : undefined;
|
|
405
442
|
let agentsSpawned = history?.agentsSpawned ?? 0;
|
|
406
443
|
let agentsCached = 0;
|
|
407
444
|
let costUsd = history?.costUsd ?? 0;
|
|
@@ -415,14 +452,14 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
415
452
|
const evidenceRecords = [];
|
|
416
453
|
const policyDecisions = new Map(history?.policyDecisions.map((decision) => [decision.id, decision]));
|
|
417
454
|
const acceptanceIds = new Set(meta.acceptance.map((criterion) => criterion.id));
|
|
418
|
-
const
|
|
419
|
-
|
|
455
|
+
const transcript = (event, data) => {
|
|
456
|
+
appendWorkflowTranscriptEvent(opts.coordRoot, runId, event, { stage: currentStage, ...data });
|
|
420
457
|
};
|
|
421
|
-
const
|
|
458
|
+
const transcriptAgentEnd = (data, resultKind, result) => {
|
|
422
459
|
// The writer shrinks an oversized record itself and names what it dropped,
|
|
423
460
|
// so no per-call fallback is needed here. A digest rides along regardless so
|
|
424
461
|
// a shrunk record can still be tied back to the exact result.
|
|
425
|
-
|
|
462
|
+
transcript("agent.end", {
|
|
426
463
|
...data,
|
|
427
464
|
result_kind: resultKind,
|
|
428
465
|
result_digest: digestResult(result, resultKind),
|
|
@@ -475,7 +512,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
475
512
|
const evaluation = evaluatePolicy(policy, request);
|
|
476
513
|
const id = `p${++policySeq}`;
|
|
477
514
|
const checkedAt = new Date().toISOString();
|
|
478
|
-
|
|
515
|
+
transcript("policy.check", {
|
|
479
516
|
id,
|
|
480
517
|
policy: policy.name,
|
|
481
518
|
policy_sha256: policyDigest(policy),
|
|
@@ -521,25 +558,25 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
521
558
|
});
|
|
522
559
|
if (stored.approval.status === "pending") {
|
|
523
560
|
if (stored.created) {
|
|
524
|
-
|
|
561
|
+
transcript("approval.requested", {
|
|
525
562
|
approval_id: stored.approval.request.id,
|
|
526
563
|
decision_id: id,
|
|
527
564
|
addressed_to: stored.approval.request.addressed_to,
|
|
528
565
|
request_sha256: stored.approval.request.request_sha256,
|
|
529
566
|
});
|
|
530
567
|
}
|
|
531
|
-
|
|
568
|
+
transcript("run.parked", {
|
|
532
569
|
approval_id: stored.approval.request.id,
|
|
533
570
|
decision_id: id,
|
|
534
571
|
phase: request.phase,
|
|
535
572
|
action: request.action,
|
|
536
573
|
});
|
|
537
|
-
throw new WorkflowParkedError(`workflow parked for approval ${stored.approval.request.id}: ${evaluation.reason}`, runId, stored.approval.request.id,
|
|
574
|
+
throw new WorkflowParkedError(`workflow parked for approval ${stored.approval.request.id}: ${evaluation.reason}`, runId, stored.approval.request.id, transcriptPath);
|
|
538
575
|
}
|
|
539
576
|
verdict = stored.approval.decision.verdict;
|
|
540
577
|
resolvedBy = "approval";
|
|
541
578
|
reason = boundedPolicyReason(stored.approval.decision.reason ?? evaluation.reason);
|
|
542
|
-
|
|
579
|
+
transcript("approval.consumed", {
|
|
543
580
|
approval_id: stored.approval.request.id,
|
|
544
581
|
decision_id: id,
|
|
545
582
|
verdict,
|
|
@@ -561,7 +598,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
561
598
|
request,
|
|
562
599
|
};
|
|
563
600
|
policyDecisions.set(decision.id, decision);
|
|
564
|
-
|
|
601
|
+
transcript("policy.resolve", { ...decision });
|
|
565
602
|
if (decision.verdict === "deny") {
|
|
566
603
|
throw new PolicyDeniedError(`policy ${JSON.stringify(policy.name)} denied ${request.phase} ${JSON.stringify(request.action)}: ${decision.reason}`, decision.id);
|
|
567
604
|
}
|
|
@@ -576,10 +613,10 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
576
613
|
: assignmentPrompt;
|
|
577
614
|
let reservedForDispatch = 0;
|
|
578
615
|
let spawnCountClaimed = false;
|
|
579
|
-
const
|
|
580
|
-
const spawner = opts.spawners[
|
|
616
|
+
const adapter = agentOpts.adapter ?? defaultAdapter;
|
|
617
|
+
const spawner = opts.spawners[adapter];
|
|
581
618
|
if (!spawner) {
|
|
582
|
-
throw new Error(`no spawner registered for
|
|
619
|
+
throw new Error(`no spawner registered for adapter "${adapter}" (registered: ${Object.keys(opts.spawners).join(", ") || "none"})`);
|
|
583
620
|
}
|
|
584
621
|
const id = `a${++agentSeq}`;
|
|
585
622
|
const label = agentOpts.label ?? `${prompt.slice(0, 60).replace(/\s+/g, " ")}…`;
|
|
@@ -590,16 +627,16 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
590
627
|
label: proofLabel,
|
|
591
628
|
stage: currentStage || undefined,
|
|
592
629
|
specialist: agentOpts.specialist,
|
|
593
|
-
|
|
630
|
+
adapter,
|
|
594
631
|
model: agentOpts.model,
|
|
595
632
|
status: "failed",
|
|
596
633
|
attempts: 0,
|
|
597
634
|
duration_ms: 0,
|
|
598
635
|
};
|
|
599
636
|
agentProofs.set(id, agentProof);
|
|
600
|
-
// Call identity for resume: same stage +
|
|
637
|
+
// Call identity for resume: same stage + adapter + model + effort + turns + schema
|
|
601
638
|
// + ORIGINAL prompt → same key. Retry-mutated prompts never enter the key.
|
|
602
|
-
const key = agentCallKey(currentStage,
|
|
639
|
+
const key = agentCallKey(currentStage, adapter, agentOpts, assignmentPrompt);
|
|
603
640
|
const cached = resumeCache.get(key);
|
|
604
641
|
if (cached) {
|
|
605
642
|
// Exact-run replay skips dispatch authorization because no dispatch
|
|
@@ -610,11 +647,11 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
610
647
|
agentsCached++;
|
|
611
648
|
agentProof.status = "cached";
|
|
612
649
|
agentProof.result = digestResult(cached.value, cached.kind);
|
|
613
|
-
|
|
650
|
+
transcript("agent.cached", {
|
|
614
651
|
id,
|
|
615
652
|
label,
|
|
616
653
|
key,
|
|
617
|
-
|
|
654
|
+
adapter,
|
|
618
655
|
specialist: agentOpts.specialist ?? null,
|
|
619
656
|
model: agentOpts.model ?? null,
|
|
620
657
|
kind: cached.kind,
|
|
@@ -627,7 +664,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
627
664
|
phase: "dispatch",
|
|
628
665
|
action: "spawn agent",
|
|
629
666
|
path: executionCwd,
|
|
630
|
-
|
|
667
|
+
adapter,
|
|
631
668
|
model: agentOpts.model,
|
|
632
669
|
effort: agentOpts.effort,
|
|
633
670
|
max_attempts: maxAttempts,
|
|
@@ -649,8 +686,8 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
649
686
|
projectedCost = candidate;
|
|
650
687
|
}
|
|
651
688
|
catch (error) {
|
|
652
|
-
|
|
653
|
-
|
|
689
|
+
transcript("policy.cost_estimate_failed", {
|
|
690
|
+
adapter,
|
|
654
691
|
model: agentOpts.model ?? null,
|
|
655
692
|
error: boundedPolicyReason(error.message),
|
|
656
693
|
});
|
|
@@ -688,17 +725,17 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
688
725
|
throw error;
|
|
689
726
|
}
|
|
690
727
|
}
|
|
691
|
-
// Billing safeguard: on a
|
|
728
|
+
// Billing safeguard: on a adapter's FIRST spawn this run, classify which
|
|
692
729
|
// auth its children will use and refuse the silent-override state (an
|
|
693
730
|
// exported API key shadowing a stored subscription login) unless the
|
|
694
731
|
// caller explicitly opted into API billing. Cached agents never reach
|
|
695
732
|
// this — no spawn, no billing.
|
|
696
733
|
try {
|
|
697
|
-
if (!billingProbed.has(
|
|
698
|
-
const probe = (opts.probeBilling ?? probeBilling)(
|
|
699
|
-
billingProbed.set(
|
|
700
|
-
|
|
701
|
-
|
|
734
|
+
if (!billingProbed.has(adapter)) {
|
|
735
|
+
const probe = (opts.probeBilling ?? probeBilling)(adapter);
|
|
736
|
+
billingProbed.set(adapter, probe);
|
|
737
|
+
transcript("billing.probe", {
|
|
738
|
+
adapter,
|
|
702
739
|
mode: subscriptionOnly ? "subscription" : probe.mode,
|
|
703
740
|
api_key_source: probe.apiKeySource,
|
|
704
741
|
login: probe.login,
|
|
@@ -706,26 +743,26 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
706
743
|
});
|
|
707
744
|
if (subscriptionOnly) {
|
|
708
745
|
if (probe.login === "absent") {
|
|
709
|
-
throw new Error(`subscription-only: no stored login detected for ${
|
|
710
|
-
`log the
|
|
746
|
+
throw new Error(`subscription-only: no stored login detected for ${adapter}; ` +
|
|
747
|
+
`log the adapter CLI in (or drop --subscription-only for a key-only host)`);
|
|
711
748
|
}
|
|
712
|
-
log(`[billing] ${
|
|
749
|
+
log(`[billing] ${adapter}: subscription-only (API-key vars scrubbed from child env)`);
|
|
713
750
|
}
|
|
714
751
|
else if (probe.mode === "api-key-override" && !allowApiBilling) {
|
|
715
|
-
throw new Error(`${probe.apiKeySource} is set AND a stored ${
|
|
752
|
+
throw new Error(`${probe.apiKeySource} is set AND a stored ${adapter} login exists — the key silently ` +
|
|
716
753
|
`overrides your subscription auth, so children would bill per-token API rates. ` +
|
|
717
754
|
`Either unset ${probe.apiKeySource}, run with --subscription-only to scrub it from ` +
|
|
718
755
|
`child envs, or pass --allow-api-billing if API billing is intended`);
|
|
719
756
|
}
|
|
720
757
|
else if (probe.mode === "api-key") {
|
|
721
|
-
log(`[billing] ${
|
|
758
|
+
log(`[billing] ${adapter}: API-key billing (${probe.apiKeySource}; no stored login detected) — ` +
|
|
722
759
|
`children bill per-token rates`);
|
|
723
760
|
}
|
|
724
761
|
else if (probe.mode === "api-key-override") {
|
|
725
|
-
log(`[billing] ${
|
|
762
|
+
log(`[billing] ${adapter}: API-key billing (--allow-api-billing; key overrides stored login)`);
|
|
726
763
|
}
|
|
727
764
|
else {
|
|
728
|
-
log(`[billing] ${
|
|
765
|
+
log(`[billing] ${adapter}: subscription login`);
|
|
729
766
|
}
|
|
730
767
|
}
|
|
731
768
|
}
|
|
@@ -743,16 +780,16 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
743
780
|
agentsSpawned++;
|
|
744
781
|
await acquire();
|
|
745
782
|
try {
|
|
746
|
-
|
|
783
|
+
transcript("agent.start", {
|
|
747
784
|
id,
|
|
748
785
|
label,
|
|
749
786
|
key,
|
|
750
|
-
|
|
787
|
+
adapter,
|
|
751
788
|
specialist: agentOpts.specialist ?? null,
|
|
752
789
|
model: agentOpts.model ?? null,
|
|
753
790
|
effort: agentOpts.effort ?? null,
|
|
754
791
|
});
|
|
755
|
-
log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${
|
|
792
|
+
log(`[${name}] ${currentStage || "(no stage)"} → ${id} [${adapter}] ${label}`);
|
|
756
793
|
let attemptPrompt = dispatchPrompt;
|
|
757
794
|
let last = null;
|
|
758
795
|
let agentCostUsd = 0;
|
|
@@ -765,6 +802,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
765
802
|
maxTurns: agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
766
803
|
cwd: executionCwd,
|
|
767
804
|
runId,
|
|
805
|
+
agentId: id,
|
|
768
806
|
subscriptionOnly,
|
|
769
807
|
filesystemPolicy,
|
|
770
808
|
});
|
|
@@ -773,7 +811,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
773
811
|
agentCostUsd += last.costUsd ?? 0;
|
|
774
812
|
costUsd += last.costUsd ?? 0;
|
|
775
813
|
if (!last.ok) {
|
|
776
|
-
|
|
814
|
+
transcript("agent.attempt_failed", { id, attempt, error: last.error });
|
|
815
|
+
// ADR 0046: an environment failure (the binary was absent) cannot be
|
|
816
|
+
// helped by retrying an unchanged environment, so stop the in-agent
|
|
817
|
+
// retry too — not just the outer attempt/replan budget. An upstream
|
|
818
|
+
// refusal keeps retrying here: the vendor may recover mid-loop.
|
|
819
|
+
if (last.class === "environment")
|
|
820
|
+
break;
|
|
777
821
|
continue; // spawn-level failure: retry with the original prompt
|
|
778
822
|
}
|
|
779
823
|
if (!agentOpts.schema) {
|
|
@@ -782,7 +826,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
782
826
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
783
827
|
agentProof.session_id = last.sessionId;
|
|
784
828
|
agentProof.result = digestResult(last.text, "text");
|
|
785
|
-
|
|
829
|
+
transcriptAgentEnd({
|
|
786
830
|
id,
|
|
787
831
|
key,
|
|
788
832
|
attempts: attempt,
|
|
@@ -803,7 +847,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
803
847
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
804
848
|
agentProof.session_id = last.sessionId;
|
|
805
849
|
agentProof.result = digestResult(parsed.value, "json");
|
|
806
|
-
|
|
850
|
+
transcriptAgentEnd({
|
|
807
851
|
id,
|
|
808
852
|
key,
|
|
809
853
|
attempts: attempt,
|
|
@@ -814,7 +858,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
814
858
|
}, "json", parsed.value);
|
|
815
859
|
return parsed.value;
|
|
816
860
|
}
|
|
817
|
-
|
|
861
|
+
transcript("agent.schema_retry", { id, attempt, problems });
|
|
818
862
|
// Keep the original cache identity while making the actual output
|
|
819
863
|
// contract explicit. A full bounded copy of the rejected value lets the
|
|
820
864
|
// child repair omissions instead of reconstructing an unseen object.
|
|
@@ -833,7 +877,14 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
833
877
|
agentCostUsd > 0 || last?.costUsd !== undefined ? agentCostUsd : undefined;
|
|
834
878
|
agentProof.session_id = last?.sessionId;
|
|
835
879
|
agentProof.error = reason;
|
|
836
|
-
|
|
880
|
+
// Carry the spawn class (environment/upstream) onto the proof only when the
|
|
881
|
+
// final outcome was a spawn failure. A schema failure after a spawn that
|
|
882
|
+
// reached the model is a work failure — left unclassed (charged). An
|
|
883
|
+
// earlier attempt that transiently failed and then succeeded returned
|
|
884
|
+
// above, so this only fires when the agent genuinely failed.
|
|
885
|
+
if (last && !last.ok && last.class)
|
|
886
|
+
agentProof.class = last.class;
|
|
887
|
+
transcript("agent.failed", { id, error: reason });
|
|
837
888
|
throw new Error(`agent ${proofLabel}: ${reason}`);
|
|
838
889
|
}
|
|
839
890
|
catch (error) {
|
|
@@ -850,13 +901,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
850
901
|
// concurrency. A rejected thunk lands as null so one bad item can't kill
|
|
851
902
|
// the batch — the script filters and routes.
|
|
852
903
|
return Promise.all(thunks.map((t) => t().catch((err) => {
|
|
853
|
-
|
|
904
|
+
transcript("parallel.item_failed", { error: err.message });
|
|
854
905
|
return null;
|
|
855
906
|
})));
|
|
856
907
|
};
|
|
857
908
|
const stage = (title) => {
|
|
858
909
|
currentStage = title;
|
|
859
|
-
|
|
910
|
+
transcript("stage.start", { title });
|
|
860
911
|
log(`[${name}] ── stage: ${title}`);
|
|
861
912
|
};
|
|
862
913
|
const evidence = (input) => {
|
|
@@ -868,7 +919,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
868
919
|
});
|
|
869
920
|
evidenceSeq++;
|
|
870
921
|
evidenceRecords.push(record);
|
|
871
|
-
|
|
922
|
+
transcript("evidence.recorded", { ...record });
|
|
872
923
|
return record.id;
|
|
873
924
|
};
|
|
874
925
|
const authorize = async (input) => {
|
|
@@ -886,6 +937,16 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
886
937
|
current_cost_usd: round4(costUsd),
|
|
887
938
|
});
|
|
888
939
|
};
|
|
940
|
+
const blocked = (input) => {
|
|
941
|
+
const reason = input.reason.trim();
|
|
942
|
+
if (!reason)
|
|
943
|
+
throw new Error("ctx.blocked() requires a reason");
|
|
944
|
+
transcript("run.blocked", {
|
|
945
|
+
reason,
|
|
946
|
+
...(input.decision ? { decision_id: input.decision } : {}),
|
|
947
|
+
});
|
|
948
|
+
throw new WorkflowBlockedError(reason, input.decision);
|
|
949
|
+
};
|
|
889
950
|
const ctx = {
|
|
890
951
|
work: workContext,
|
|
891
952
|
attempt: attemptContext,
|
|
@@ -895,17 +956,18 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
895
956
|
log,
|
|
896
957
|
evidence,
|
|
897
958
|
authorize,
|
|
959
|
+
blocked,
|
|
898
960
|
};
|
|
899
961
|
try {
|
|
900
962
|
if (resumeState) {
|
|
901
|
-
|
|
963
|
+
transcript("run.resume", {
|
|
902
964
|
approval_id: resumeState.approvalId,
|
|
903
965
|
script: absScript,
|
|
904
966
|
resumed_at: new Date().toISOString(),
|
|
905
967
|
});
|
|
906
968
|
}
|
|
907
969
|
else {
|
|
908
|
-
|
|
970
|
+
transcript("run.start", {
|
|
909
971
|
name,
|
|
910
972
|
work_item_id: opts.workItemId ?? null,
|
|
911
973
|
work_context: workContext ?? null,
|
|
@@ -938,7 +1000,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
938
1000
|
if (workspaceAttestation && workspaceAttestation.status !== "ok") {
|
|
939
1001
|
throw new Error(`terminal workspace attestation ${workspaceAttestation.status}: ${workspaceAttestation.provider_drift.join("; ") || "provider could not prove the workspace"}`);
|
|
940
1002
|
}
|
|
941
|
-
|
|
1003
|
+
transcript("run.end", {
|
|
942
1004
|
ok: true,
|
|
943
1005
|
agents: agentsSpawned,
|
|
944
1006
|
cached: agentsCached,
|
|
@@ -957,13 +1019,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
957
1019
|
startedAt,
|
|
958
1020
|
endedAt,
|
|
959
1021
|
durationMs,
|
|
960
|
-
|
|
1022
|
+
transcriptPath,
|
|
961
1023
|
before: executionRepoBefore,
|
|
962
1024
|
after: snapshotRepo(executionCwd),
|
|
963
1025
|
agents: Array.from(agentProofs.values()),
|
|
964
1026
|
evidence: evidenceRecords,
|
|
965
|
-
|
|
966
|
-
|
|
1027
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1028
|
+
adapterAttestations: opts.adapterAttestations,
|
|
967
1029
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
968
1030
|
policy: policy
|
|
969
1031
|
? {
|
|
@@ -992,12 +1054,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
992
1054
|
agentsCached,
|
|
993
1055
|
costUsd: round4(costUsd),
|
|
994
1056
|
durationMs,
|
|
995
|
-
|
|
1057
|
+
transcriptPath,
|
|
996
1058
|
proofPath,
|
|
997
1059
|
acceptance: proof.acceptance.summary,
|
|
998
1060
|
contextTokensPerChildEstimate,
|
|
999
1061
|
billing: Array.from(billingProbed.values()).map((p) => ({
|
|
1000
|
-
|
|
1062
|
+
adapter: p.adapter,
|
|
1001
1063
|
mode: subscriptionOnly ? "subscription" : p.mode,
|
|
1002
1064
|
})),
|
|
1003
1065
|
policy: proof.policy?.summary,
|
|
@@ -1013,7 +1075,7 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1013
1075
|
throw err;
|
|
1014
1076
|
const endedAt = new Date().toISOString();
|
|
1015
1077
|
const durationMs = Date.now() - t0;
|
|
1016
|
-
|
|
1078
|
+
transcript("run.end", {
|
|
1017
1079
|
ok: false,
|
|
1018
1080
|
error: err.message,
|
|
1019
1081
|
agents: agentsSpawned,
|
|
@@ -1036,13 +1098,13 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1036
1098
|
startedAt,
|
|
1037
1099
|
endedAt,
|
|
1038
1100
|
durationMs,
|
|
1039
|
-
|
|
1101
|
+
transcriptPath,
|
|
1040
1102
|
before: executionRepoBefore,
|
|
1041
1103
|
after: snapshotRepo(executionCwd),
|
|
1042
1104
|
agents: Array.from(agentProofs.values()),
|
|
1043
1105
|
evidence: evidenceRecords,
|
|
1044
|
-
|
|
1045
|
-
|
|
1106
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1107
|
+
adapterAttestations: opts.adapterAttestations,
|
|
1046
1108
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
1047
1109
|
policy: policy
|
|
1048
1110
|
? {
|
|
@@ -1056,6 +1118,12 @@ async function executeWorkflow(scriptPath, absScript, opts, resumeState, workCon
|
|
|
1056
1118
|
workspaceAttestation,
|
|
1057
1119
|
workspaceFallback,
|
|
1058
1120
|
error: err.message,
|
|
1121
|
+
// A deliberate stop-on-human, not a work failure. Overrides whatever the
|
|
1122
|
+
// agents' own classes would have derived: the script's determination is
|
|
1123
|
+
// the more specific fact about why this run ended.
|
|
1124
|
+
blocked: err instanceof WorkflowBlockedError
|
|
1125
|
+
? { reason: err.reason, decisionId: err.decisionId }
|
|
1126
|
+
: undefined,
|
|
1059
1127
|
});
|
|
1060
1128
|
writeWorkflowProof(proofPath, proof);
|
|
1061
1129
|
}
|
|
@@ -1078,10 +1146,10 @@ function boundedSchemaReply(value) {
|
|
|
1078
1146
|
}
|
|
1079
1147
|
/** Stable identity for one agent() call, for the resume cache. The ORIGINAL
|
|
1080
1148
|
* prompt (never a retry-mutated one) plus everything that changes behavior. */
|
|
1081
|
-
function agentCallKey(stage,
|
|
1149
|
+
function agentCallKey(stage, adapter, agentOpts, prompt) {
|
|
1082
1150
|
const parts = [
|
|
1083
1151
|
stage,
|
|
1084
|
-
|
|
1152
|
+
adapter,
|
|
1085
1153
|
agentOpts.model ?? null,
|
|
1086
1154
|
agentOpts.effort ?? null,
|
|
1087
1155
|
agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
@@ -1110,14 +1178,14 @@ function estimateInstructionTokens(cwd) {
|
|
|
1110
1178
|
}
|
|
1111
1179
|
return 0;
|
|
1112
1180
|
}
|
|
1113
|
-
/** Load a prior run's
|
|
1181
|
+
/** Load a prior run's transcript into a key → result map. Only `agent.end`
|
|
1114
1182
|
* entries (completed, validated) are resumable; failed or retried-out agents
|
|
1115
|
-
* re-run live. Unreadable
|
|
1183
|
+
* re-run live. Unreadable transcript → error (a typo'd run id should fail loud,
|
|
1116
1184
|
* not silently run everything fresh). */
|
|
1117
1185
|
function loadResumeCache(coordRoot, resumeFrom) {
|
|
1118
|
-
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "
|
|
1186
|
+
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "transcript.jsonl");
|
|
1119
1187
|
if (!existsSync(path)) {
|
|
1120
|
-
throw new Error(`--resume-from ${resumeFrom}: no
|
|
1188
|
+
throw new Error(`--resume-from ${resumeFrom}: no transcript at ${path}`);
|
|
1121
1189
|
}
|
|
1122
1190
|
const cache = new Map();
|
|
1123
1191
|
for (const line of readFileSync(path, "utf8").split("\n")) {
|