harnery 0.30.0 → 0.31.1
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 +185 -74
- 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/grep.d.ts +1 -1
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +19 -2
- 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 +213 -27
- 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.map +1 -1
- package/dist/commands/work.js +38 -22
- 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 +23 -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 +9 -14
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +15 -44
- 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-bin.d.ts +33 -0
- package/dist/core/agents/coord-bin.d.ts.map +1 -0
- package/dist/core/agents/coord-bin.js +89 -0
- package/dist/core/agents/coord-client.d.ts +78 -8
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +303 -75
- 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/paths.d.ts +5 -2
- package/dist/core/agents/paths.d.ts.map +1 -1
- package/dist/core/agents/paths.js +7 -13
- 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 +66 -52
- package/dist/core/{supervisor → governor}/plan-types.d.ts +57 -56
- 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 +125 -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 +228 -108
- 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 +187 -162
- 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 +19 -19
- 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 +16 -11
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
- package/dist/core/hooks/resolve/coord-root.js +18 -43
- 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/state.d.ts +12 -4
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +50 -17
- 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 +138 -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 +1 -1
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/proof.d.ts +11 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +45 -36
- 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 +9 -6
- 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 +9 -6
- 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 +9 -6
- package/dist/core/workflow/spawn-failure.d.ts +1 -1
- package/dist/core/workflow/spawn-failure.js +1 -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 +98 -51
- 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/context/index.js +9 -2
- 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/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 +200 -78
- 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/grep.ts +19 -2
- 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 +256 -38
- package/src/commands/web-fetch.ts +1 -1
- package/src/commands/web.ts +56 -1
- package/src/commands/work.ts +50 -35
- 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 +23 -23
- package/src/core/agents/canonical-emit.ts +16 -43
- 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-bin.ts +92 -0
- package/src/core/agents/coord-client.ts +302 -78
- package/src/core/agents/events/consume.ts +1 -1
- package/src/core/agents/events/emit.ts +7 -6
- package/src/core/agents/paths.ts +7 -11
- 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 +112 -97
- package/src/core/{supervisor → governor}/plan-types.ts +59 -56
- package/src/core/{supervisor → governor}/planning.ts +223 -192
- 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 +325 -167
- 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 +197 -173
- package/src/core/hooks/effects/image-capture.ts +6 -6
- package/src/core/hooks/effects/index.ts +19 -19
- 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 +18 -40
- 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/state.ts +65 -23
- 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 +155 -90
- package/src/core/workflow/evidence-preflight.ts +165 -0
- package/src/core/workflow/index.ts +3 -3
- package/src/core/workflow/proof.ts +60 -50
- 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 +13 -10
- package/src/core/workflow/spawn-codex.ts +13 -10
- package/src/core/workflow/spawn-cursor.ts +13 -10
- package/src/core/workflow/spawn-failure.ts +1 -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 +108 -51
- 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/context/index.ts +11 -1
- package/src/lib/council/index.ts +9 -9
- 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.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,7 @@ 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 });
|
|
914
961
|
// ADR 0046: an environment failure (the binary was absent) cannot be
|
|
915
962
|
// helped by retrying an unchanged environment, so stop the in-agent
|
|
916
963
|
// retry too — not just the outer attempt/replan budget. An upstream
|
|
@@ -924,7 +971,7 @@ async function executeWorkflow(
|
|
|
924
971
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
925
972
|
agentProof.session_id = last.sessionId;
|
|
926
973
|
agentProof.result = digestResult(last.text, "text");
|
|
927
|
-
|
|
974
|
+
transcriptAgentEnd(
|
|
928
975
|
{
|
|
929
976
|
id,
|
|
930
977
|
key,
|
|
@@ -951,7 +998,7 @@ async function executeWorkflow(
|
|
|
951
998
|
agentCostUsd > 0 || last.costUsd !== undefined ? agentCostUsd : undefined;
|
|
952
999
|
agentProof.session_id = last.sessionId;
|
|
953
1000
|
agentProof.result = digestResult(parsed.value, "json");
|
|
954
|
-
|
|
1001
|
+
transcriptAgentEnd(
|
|
955
1002
|
{
|
|
956
1003
|
id,
|
|
957
1004
|
key,
|
|
@@ -967,7 +1014,7 @@ async function executeWorkflow(
|
|
|
967
1014
|
return parsed.value;
|
|
968
1015
|
}
|
|
969
1016
|
|
|
970
|
-
|
|
1017
|
+
transcript("agent.schema_retry", { id, attempt, problems });
|
|
971
1018
|
// Keep the original cache identity while making the actual output
|
|
972
1019
|
// contract explicit. A full bounded copy of the rejected value lets the
|
|
973
1020
|
// child repair omissions instead of reconstructing an unseen object.
|
|
@@ -993,7 +1040,7 @@ async function executeWorkflow(
|
|
|
993
1040
|
// earlier attempt that transiently failed and then succeeded returned
|
|
994
1041
|
// above, so this only fires when the agent genuinely failed.
|
|
995
1042
|
if (last && !last.ok && last.class) agentProof.class = last.class;
|
|
996
|
-
|
|
1043
|
+
transcript("agent.failed", { id, error: reason });
|
|
997
1044
|
throw new Error(`agent ${proofLabel}: ${reason}`);
|
|
998
1045
|
} catch (error) {
|
|
999
1046
|
agentProof.error ??= (error as Error).message;
|
|
@@ -1011,7 +1058,7 @@ async function executeWorkflow(
|
|
|
1011
1058
|
return Promise.all(
|
|
1012
1059
|
thunks.map((t) =>
|
|
1013
1060
|
t().catch((err: unknown) => {
|
|
1014
|
-
|
|
1061
|
+
transcript("parallel.item_failed", { error: (err as Error).message });
|
|
1015
1062
|
return null;
|
|
1016
1063
|
}),
|
|
1017
1064
|
),
|
|
@@ -1020,7 +1067,7 @@ async function executeWorkflow(
|
|
|
1020
1067
|
|
|
1021
1068
|
const stage = (title: string): void => {
|
|
1022
1069
|
currentStage = title;
|
|
1023
|
-
|
|
1070
|
+
transcript("stage.start", { title });
|
|
1024
1071
|
log(`[${name}] ── stage: ${title}`);
|
|
1025
1072
|
};
|
|
1026
1073
|
|
|
@@ -1033,7 +1080,7 @@ async function executeWorkflow(
|
|
|
1033
1080
|
});
|
|
1034
1081
|
evidenceSeq++;
|
|
1035
1082
|
evidenceRecords.push(record);
|
|
1036
|
-
|
|
1083
|
+
transcript("evidence.recorded", { ...record });
|
|
1037
1084
|
return record.id;
|
|
1038
1085
|
};
|
|
1039
1086
|
|
|
@@ -1054,6 +1101,16 @@ async function executeWorkflow(
|
|
|
1054
1101
|
});
|
|
1055
1102
|
};
|
|
1056
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
|
+
|
|
1057
1114
|
const ctx: WorkflowContext = {
|
|
1058
1115
|
work: workContext,
|
|
1059
1116
|
attempt: attemptContext,
|
|
@@ -1063,16 +1120,17 @@ async function executeWorkflow(
|
|
|
1063
1120
|
log,
|
|
1064
1121
|
evidence,
|
|
1065
1122
|
authorize,
|
|
1123
|
+
blocked,
|
|
1066
1124
|
};
|
|
1067
1125
|
try {
|
|
1068
1126
|
if (resumeState) {
|
|
1069
|
-
|
|
1127
|
+
transcript("run.resume", {
|
|
1070
1128
|
approval_id: resumeState.approvalId,
|
|
1071
1129
|
script: absScript,
|
|
1072
1130
|
resumed_at: new Date().toISOString(),
|
|
1073
1131
|
});
|
|
1074
1132
|
} else {
|
|
1075
|
-
|
|
1133
|
+
transcript("run.start", {
|
|
1076
1134
|
name,
|
|
1077
1135
|
work_item_id: opts.workItemId ?? null,
|
|
1078
1136
|
work_context: workContext ?? null,
|
|
@@ -1107,7 +1165,7 @@ async function executeWorkflow(
|
|
|
1107
1165
|
}`,
|
|
1108
1166
|
);
|
|
1109
1167
|
}
|
|
1110
|
-
|
|
1168
|
+
transcript("run.end", {
|
|
1111
1169
|
ok: true,
|
|
1112
1170
|
agents: agentsSpawned,
|
|
1113
1171
|
cached: agentsCached,
|
|
@@ -1126,13 +1184,13 @@ async function executeWorkflow(
|
|
|
1126
1184
|
startedAt,
|
|
1127
1185
|
endedAt,
|
|
1128
1186
|
durationMs,
|
|
1129
|
-
|
|
1187
|
+
transcriptPath,
|
|
1130
1188
|
before: executionRepoBefore,
|
|
1131
1189
|
after: snapshotRepo(executionCwd),
|
|
1132
1190
|
agents: Array.from(agentProofs.values()),
|
|
1133
1191
|
evidence: evidenceRecords,
|
|
1134
|
-
|
|
1135
|
-
|
|
1192
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1193
|
+
adapterAttestations: opts.adapterAttestations,
|
|
1136
1194
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
1137
1195
|
policy: policy
|
|
1138
1196
|
? {
|
|
@@ -1165,12 +1223,12 @@ async function executeWorkflow(
|
|
|
1165
1223
|
agentsCached,
|
|
1166
1224
|
costUsd: round4(costUsd),
|
|
1167
1225
|
durationMs,
|
|
1168
|
-
|
|
1226
|
+
transcriptPath,
|
|
1169
1227
|
proofPath,
|
|
1170
1228
|
acceptance: proof.acceptance.summary,
|
|
1171
1229
|
contextTokensPerChildEstimate,
|
|
1172
1230
|
billing: Array.from(billingProbed.values()).map((p) => ({
|
|
1173
|
-
|
|
1231
|
+
adapter: p.adapter,
|
|
1174
1232
|
mode: subscriptionOnly ? "subscription" : p.mode,
|
|
1175
1233
|
})),
|
|
1176
1234
|
policy: proof.policy?.summary,
|
|
@@ -1184,7 +1242,7 @@ async function executeWorkflow(
|
|
|
1184
1242
|
if (err instanceof WorkflowRunError) throw err;
|
|
1185
1243
|
const endedAt = new Date().toISOString();
|
|
1186
1244
|
const durationMs = Date.now() - t0;
|
|
1187
|
-
|
|
1245
|
+
transcript("run.end", {
|
|
1188
1246
|
ok: false,
|
|
1189
1247
|
error: (err as Error).message,
|
|
1190
1248
|
agents: agentsSpawned,
|
|
@@ -1207,13 +1265,13 @@ async function executeWorkflow(
|
|
|
1207
1265
|
startedAt,
|
|
1208
1266
|
endedAt,
|
|
1209
1267
|
durationMs,
|
|
1210
|
-
|
|
1268
|
+
transcriptPath,
|
|
1211
1269
|
before: executionRepoBefore,
|
|
1212
1270
|
after: snapshotRepo(executionCwd),
|
|
1213
1271
|
agents: Array.from(agentProofs.values()),
|
|
1214
1272
|
evidence: evidenceRecords,
|
|
1215
|
-
|
|
1216
|
-
|
|
1273
|
+
adapterEvidence: opts.adapterEvidence,
|
|
1274
|
+
adapterAttestations: opts.adapterAttestations,
|
|
1217
1275
|
sandboxProjection: sandboxProjectionEvidence(filesystemPolicy, gitWrite),
|
|
1218
1276
|
policy: policy
|
|
1219
1277
|
? {
|
|
@@ -1227,6 +1285,13 @@ async function executeWorkflow(
|
|
|
1227
1285
|
workspaceAttestation,
|
|
1228
1286
|
workspaceFallback,
|
|
1229
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,
|
|
1230
1295
|
});
|
|
1231
1296
|
writeWorkflowProof(proofPath, proof);
|
|
1232
1297
|
} catch (proofError) {
|
|
@@ -1260,13 +1325,13 @@ function boundedSchemaReply(value: string): string {
|
|
|
1260
1325
|
* prompt (never a retry-mutated one) plus everything that changes behavior. */
|
|
1261
1326
|
function agentCallKey(
|
|
1262
1327
|
stage: string,
|
|
1263
|
-
|
|
1328
|
+
adapter: string,
|
|
1264
1329
|
agentOpts: AgentOpts,
|
|
1265
1330
|
prompt: string,
|
|
1266
1331
|
): string {
|
|
1267
1332
|
const parts: unknown[] = [
|
|
1268
1333
|
stage,
|
|
1269
|
-
|
|
1334
|
+
adapter,
|
|
1270
1335
|
agentOpts.model ?? null,
|
|
1271
1336
|
agentOpts.effort ?? null,
|
|
1272
1337
|
agentOpts.maxTurns ?? DEFAULT_MAX_TURNS,
|
|
@@ -1295,17 +1360,17 @@ function estimateInstructionTokens(cwd: string): number {
|
|
|
1295
1360
|
return 0;
|
|
1296
1361
|
}
|
|
1297
1362
|
|
|
1298
|
-
/** Load a prior run's
|
|
1363
|
+
/** Load a prior run's transcript into a key → result map. Only `agent.end`
|
|
1299
1364
|
* entries (completed, validated) are resumable; failed or retried-out agents
|
|
1300
|
-
* re-run live. Unreadable
|
|
1365
|
+
* re-run live. Unreadable transcript → error (a typo'd run id should fail loud,
|
|
1301
1366
|
* not silently run everything fresh). */
|
|
1302
1367
|
function loadResumeCache(
|
|
1303
1368
|
coordRoot: string,
|
|
1304
1369
|
resumeFrom: string,
|
|
1305
1370
|
): Map<string, { kind: "json" | "text"; value: unknown }> {
|
|
1306
|
-
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "
|
|
1371
|
+
const path = join(coordRoot, ".harnery", "workflows", resumeFrom, "transcript.jsonl");
|
|
1307
1372
|
if (!existsSync(path)) {
|
|
1308
|
-
throw new Error(`--resume-from ${resumeFrom}: no
|
|
1373
|
+
throw new Error(`--resume-from ${resumeFrom}: no transcript at ${path}`);
|
|
1309
1374
|
}
|
|
1310
1375
|
const cache = new Map<string, { kind: "json" | "text"; value: unknown }>();
|
|
1311
1376
|
for (const line of readFileSync(path, "utf8").split("\n")) {
|