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
package/src/commands/workflow.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { existsSync } from "node:fs";
|
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import type { Command } from "commander";
|
|
4
4
|
import type { EmitContext } from "../commander.ts";
|
|
5
|
-
import { resolveBinName, workflowSubscriptionOnly } from "../core/config.ts";
|
|
6
5
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
adapterProofInputs,
|
|
7
|
+
createBuiltinAdapterRegistry,
|
|
9
8
|
probeBinaryVersion,
|
|
10
|
-
} from "../core/
|
|
9
|
+
} from "../core/adapters/index.ts";
|
|
10
|
+
import { resolveBinName, workflowSubscriptionOnly } from "../core/config.ts";
|
|
11
11
|
import { findCoordRoot } from "../core/hooks/resolve/coord-root.ts";
|
|
12
12
|
import type { PolicyIsolation } from "../core/policy/index.ts";
|
|
13
13
|
import { loadPolicyFile } from "../core/policy/index.ts";
|
|
@@ -17,7 +17,7 @@ import type { WorkspaceProvider } from "../core/workflow/index.ts";
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* `workflow run <script>`: execute a workflow script — bounded, schema-gated,
|
|
20
|
-
* conditionally-routed stages fanning out to headless
|
|
20
|
+
* conditionally-routed stages fanning out to headless adapter-CLI subagents.
|
|
21
21
|
* The script (deterministic code), not a model, decides routing between
|
|
22
22
|
* stages, and the run terminates when the script returns.
|
|
23
23
|
*
|
|
@@ -29,7 +29,7 @@ interface WorkflowRunOpts {
|
|
|
29
29
|
maxAgents?: string;
|
|
30
30
|
concurrency?: string;
|
|
31
31
|
cwd?: string;
|
|
32
|
-
|
|
32
|
+
adapter?: string;
|
|
33
33
|
resumeFrom?: string;
|
|
34
34
|
subscriptionOnly?: boolean;
|
|
35
35
|
allowApiBilling?: boolean;
|
|
@@ -75,33 +75,42 @@ interface WorkflowReclaimOpts extends WorkflowConfirmedMutationOpts {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export function registerWorkflowCommand(program: Command, emit: EmitContext): void {
|
|
78
|
-
const registry =
|
|
79
|
-
const
|
|
78
|
+
const registry = createBuiltinAdapterRegistry();
|
|
79
|
+
const adapters = registry.ids();
|
|
80
80
|
const workflow = program
|
|
81
|
-
.command("
|
|
82
|
-
.description(
|
|
81
|
+
.command("run")
|
|
82
|
+
.description(
|
|
83
|
+
"Execute one bounded, schema-gated multi-subagent script. Subagents spawn as headless " +
|
|
84
|
+
"adapter-CLI subprocesses, born coordination-registered.",
|
|
85
|
+
)
|
|
86
|
+
// An option has to bind to whichever command name precedes it, so that a
|
|
87
|
+
// subcommand's own --policy / --json reach the subcommand and not `run`.
|
|
88
|
+
.enablePositionalOptions();
|
|
83
89
|
|
|
90
|
+
// Executing a script is `run`'s default, so `harn run ./wf.js` works with no
|
|
91
|
+
// second verb. It has to be a real (hidden) subcommand rather than an action
|
|
92
|
+
// on `run` itself: `run` and several of its subcommands declare the same
|
|
93
|
+
// option names, and a parent-level declaration swallows the child's copy.
|
|
84
94
|
workflow
|
|
85
|
-
.command("
|
|
95
|
+
.command("script <script>", { isDefault: true, hidden: true })
|
|
86
96
|
.description(
|
|
87
|
-
"
|
|
88
|
-
"Subagents spawn as headless harness-CLI subprocesses, coordination-registered.",
|
|
97
|
+
"Workflow script (plain JS: `export default async ({agent, parallel, stage, log, evidence, authorize}) => …`)",
|
|
89
98
|
)
|
|
90
99
|
.option("--max-agents <n>", "Total-agent ceiling for the run (default 50)")
|
|
91
100
|
.option("--concurrency <n>", "Concurrent-subagent cap (default 4)")
|
|
92
101
|
.option("--cwd <dir>", "Working directory children spawn in (default: coord root)")
|
|
93
102
|
.option(
|
|
94
|
-
"--
|
|
95
|
-
`Default
|
|
103
|
+
"--adapter <name>",
|
|
104
|
+
`Default adapter for agent() calls: ${adapters.join(" | ")} (default claude-code); scripts can override per agent via opts.adapter`,
|
|
96
105
|
)
|
|
97
106
|
.option(
|
|
98
107
|
"--resume-from <run-id>",
|
|
99
|
-
"Reuse completed agent results from a prior run's
|
|
108
|
+
"Reuse completed agent results from a prior run's transcript; only changed/failed calls re-run",
|
|
100
109
|
)
|
|
101
110
|
.option(
|
|
102
111
|
"--subscription-only",
|
|
103
112
|
"Guarantee subscription billing: scrub API-key vars from child envs; fail loud when a " +
|
|
104
|
-
"
|
|
113
|
+
"adapter has no stored login (repo default via config.jsonc workflow.subscriptionOnly)",
|
|
105
114
|
)
|
|
106
115
|
.option(
|
|
107
116
|
"--allow-api-billing",
|
|
@@ -131,10 +140,10 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
131
140
|
});
|
|
132
141
|
process.exit(1);
|
|
133
142
|
}
|
|
134
|
-
if (opts.
|
|
143
|
+
if (opts.adapter && !registry.get(opts.adapter)) {
|
|
135
144
|
emit.error({
|
|
136
|
-
code: "
|
|
137
|
-
message: `unknown
|
|
145
|
+
code: "bad_adapter",
|
|
146
|
+
message: `unknown adapter "${opts.adapter}" (expected: ${adapters.join(" | ")})`,
|
|
138
147
|
});
|
|
139
148
|
process.exit(1);
|
|
140
149
|
}
|
|
@@ -179,14 +188,14 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
179
188
|
const report = await runWorkflow(script, {
|
|
180
189
|
coordRoot,
|
|
181
190
|
spawners: registry.spawners(),
|
|
182
|
-
|
|
191
|
+
defaultAdapter: opts.adapter,
|
|
183
192
|
resumeFrom: opts.resumeFrom,
|
|
184
193
|
subscriptionOnly,
|
|
185
194
|
allowApiBilling: opts.allowApiBilling,
|
|
186
195
|
maxAgents: opts.maxAgents ? Number.parseInt(opts.maxAgents, 10) : undefined,
|
|
187
196
|
concurrency: opts.concurrency ? Number.parseInt(opts.concurrency, 10) : undefined,
|
|
188
197
|
cwd: opts.cwd,
|
|
189
|
-
...
|
|
198
|
+
...adapterProofInputs(
|
|
190
199
|
registry.list().map((adapter) => adapter.profile),
|
|
191
200
|
{ versionProbe: probeBinaryVersion },
|
|
192
201
|
),
|
|
@@ -195,7 +204,7 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
195
204
|
approvalAddressee: opts.approvalTo,
|
|
196
205
|
isolation: opts.isolation,
|
|
197
206
|
workspace,
|
|
198
|
-
// CLI
|
|
207
|
+
// CLI adapter subprocesses inherit the host network. A policy that
|
|
199
208
|
// forbids network must therefore deny dispatch unless a future host
|
|
200
209
|
// adapter creates and declares a network-disabled boundary.
|
|
201
210
|
networkAccess: "enabled",
|
|
@@ -207,14 +216,14 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
207
216
|
}
|
|
208
217
|
const cachedPart = report.agentsCached > 0 ? ` (+${report.agentsCached} cached)` : "";
|
|
209
218
|
const billingPart = report.billing.length
|
|
210
|
-
? `billing: ${report.billing.map((b) => `${b.
|
|
219
|
+
? `billing: ${report.billing.map((b) => `${b.adapter}=${b.mode}`).join(", ")}\n`
|
|
211
220
|
: "";
|
|
212
221
|
emit.text(
|
|
213
222
|
`run ${report.runId} (${report.name}) finished: ${report.agentsSpawned} agent(s)${cachedPart}, ` +
|
|
214
223
|
`$${report.costUsd.toFixed(4)}, ${Math.round(report.durationMs / 1000)}s\n${billingPart}` +
|
|
215
224
|
`acceptance: ${report.acceptance.satisfied} satisfied, ${report.acceptance.unsatisfied} unsatisfied, ` +
|
|
216
225
|
`${report.acceptance.unknown} unknown\n` +
|
|
217
|
-
`
|
|
226
|
+
`transcript: ${report.transcriptPath}\n` +
|
|
218
227
|
`proof: ${report.proofPath}\n` +
|
|
219
228
|
`result: ${typeof report.result === "string" ? report.result : JSON.stringify(report.result, null, 2)}\n`,
|
|
220
229
|
);
|
|
@@ -226,12 +235,12 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
226
235
|
status: "parked",
|
|
227
236
|
runId: err.runId,
|
|
228
237
|
approvalId: err.approvalId,
|
|
229
|
-
|
|
238
|
+
transcriptPath: err.transcriptPath,
|
|
230
239
|
});
|
|
231
240
|
} else {
|
|
232
241
|
emit.text(
|
|
233
242
|
`run ${err.runId} parked\napproval: ${err.approvalId}\n` +
|
|
234
|
-
`
|
|
243
|
+
`transcript: ${err.transcriptPath}\n` +
|
|
235
244
|
`resume after resolution: ${resolveBinName()} workflow resume ${err.runId}\n`,
|
|
236
245
|
);
|
|
237
246
|
}
|
|
@@ -282,7 +291,7 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
282
291
|
writableRoots: [binding.writable_root.configured],
|
|
283
292
|
}
|
|
284
293
|
: undefined,
|
|
285
|
-
...
|
|
294
|
+
...adapterProofInputs(
|
|
286
295
|
registry.list().map((adapter) => adapter.profile),
|
|
287
296
|
{ versionProbe: probeBinaryVersion },
|
|
288
297
|
),
|
|
@@ -298,7 +307,7 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
298
307
|
`$${report.costUsd.toFixed(4)}, ${Math.round(report.durationMs / 1000)}s\n` +
|
|
299
308
|
`acceptance: ${report.acceptance.satisfied} satisfied, ${report.acceptance.unsatisfied} unsatisfied, ` +
|
|
300
309
|
`${report.acceptance.unknown} unknown\n` +
|
|
301
|
-
`
|
|
310
|
+
`transcript: ${report.transcriptPath}\nproof: ${report.proofPath}\n` +
|
|
302
311
|
`result: ${typeof report.result === "string" ? report.result : JSON.stringify(report.result, null, 2)}\n`,
|
|
303
312
|
);
|
|
304
313
|
} catch (err) {
|
|
@@ -309,12 +318,12 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
309
318
|
status: "parked",
|
|
310
319
|
runId: err.runId,
|
|
311
320
|
approvalId: err.approvalId,
|
|
312
|
-
|
|
321
|
+
transcriptPath: err.transcriptPath,
|
|
313
322
|
});
|
|
314
323
|
} else {
|
|
315
324
|
emit.text(
|
|
316
325
|
`run ${err.runId} parked again\napproval: ${err.approvalId}\n` +
|
|
317
|
-
`
|
|
326
|
+
`transcript: ${err.transcriptPath}\n`,
|
|
318
327
|
);
|
|
319
328
|
}
|
|
320
329
|
return;
|
|
@@ -668,9 +677,9 @@ export function registerWorkflowCommand(program: Command, emit: EmitContext): vo
|
|
|
668
677
|
}
|
|
669
678
|
});
|
|
670
679
|
|
|
671
|
-
const approvals =
|
|
672
|
-
.command("
|
|
673
|
-
.description("Inspect and resolve durable
|
|
680
|
+
const approvals = program
|
|
681
|
+
.command("approval")
|
|
682
|
+
.description("Inspect and resolve durable run-policy approvals.");
|
|
674
683
|
|
|
675
684
|
approvals
|
|
676
685
|
.command("list")
|
|
@@ -21,7 +21,7 @@ import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
|
21
21
|
import { tmpdir } from "node:os";
|
|
22
22
|
import { join } from "node:path";
|
|
23
23
|
import type { SpawnRequest, SpawnResult } from "../workflow/types.ts";
|
|
24
|
-
import type {
|
|
24
|
+
import type { Adapter } from "./types.ts";
|
|
25
25
|
|
|
26
26
|
/** Distinct names so a control artifact can never be mistaken for a treatment
|
|
27
27
|
* one, even if a child writes both or the directory is reused. */
|
|
@@ -61,7 +61,7 @@ export interface ProjectionProbeOptions {
|
|
|
61
61
|
* failing the whole attestation sweep.
|
|
62
62
|
*/
|
|
63
63
|
export async function probeFilesystemProjection(
|
|
64
|
-
adapter:
|
|
64
|
+
adapter: Adapter,
|
|
65
65
|
opts: ProjectionProbeOptions,
|
|
66
66
|
): Promise<ProjectionProbeResult> {
|
|
67
67
|
if (!adapter.profile.sandboxProjection) {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The opt-in live probe that produces an attestation (ADR 0038).
|
|
3
3
|
*
|
|
4
|
-
* One bounded turn per
|
|
4
|
+
* One bounded turn per adapter, through the same `spawn` the workflow engine
|
|
5
5
|
* uses, so what gets attested is the path production takes rather than a
|
|
6
6
|
* parallel test rig.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { SpawnResult } from "../workflow/types.ts";
|
|
10
10
|
import { probeFilesystemProjection } from "./attest-projection.ts";
|
|
11
|
-
import type {
|
|
11
|
+
import type { AdapterAttestation, AttestableDimension } from "./attestation.ts";
|
|
12
12
|
import {
|
|
13
13
|
ATTESTATION_SCHEMA_VERSION,
|
|
14
14
|
profileDigest,
|
|
@@ -16,8 +16,8 @@ import {
|
|
|
16
16
|
writeAttestation,
|
|
17
17
|
} from "./attestation.ts";
|
|
18
18
|
import { probeBinaryVersion } from "./bench.ts";
|
|
19
|
-
import type {
|
|
20
|
-
import type {
|
|
19
|
+
import type { AdapterRegistry } from "./registry.ts";
|
|
20
|
+
import type { AdapterId, CapabilitySupport } from "./types.ts";
|
|
21
21
|
|
|
22
22
|
/** Fixed and content-free, so nothing user-supplied can reach the record and
|
|
23
23
|
* the turn stays as cheap as a turn can be. */
|
|
@@ -46,8 +46,8 @@ function boundedReason(reason: string | undefined): string {
|
|
|
46
46
|
|
|
47
47
|
export type AttestationOutcome = "recorded" | "skipped" | "unreachable" | "failed";
|
|
48
48
|
|
|
49
|
-
export interface
|
|
50
|
-
|
|
49
|
+
export interface AdapterAttestationResult {
|
|
50
|
+
adapter: AdapterId;
|
|
51
51
|
outcome: AttestationOutcome;
|
|
52
52
|
binaryVersion?: string;
|
|
53
53
|
observations?: Partial<Record<AttestableDimension, CapabilitySupport>>;
|
|
@@ -55,18 +55,18 @@ export interface HarnessAttestationResult {
|
|
|
55
55
|
note: string;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
export interface
|
|
58
|
+
export interface AdapterAttestationReport {
|
|
59
59
|
generatedAt: string;
|
|
60
|
-
|
|
61
|
-
results:
|
|
60
|
+
adapters: AdapterId[];
|
|
61
|
+
results: AdapterAttestationResult[];
|
|
62
62
|
recorded: number;
|
|
63
|
-
/** True when at least one selected
|
|
63
|
+
/** True when at least one selected adapter could not be attested, so a
|
|
64
64
|
* caller can tell a partial sweep from a complete one. */
|
|
65
65
|
incomplete: boolean;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
export interface
|
|
69
|
-
|
|
68
|
+
export interface RunAdapterAttestationOptions {
|
|
69
|
+
adapters?: readonly string[];
|
|
70
70
|
timeoutMs?: number;
|
|
71
71
|
cwd?: string;
|
|
72
72
|
coordRoot?: string;
|
|
@@ -78,12 +78,12 @@ export interface RunHarnessAttestationOptions {
|
|
|
78
78
|
/** Test seam and alternate host probe. A null version means unavailable. */
|
|
79
79
|
versionProbe?: (binary: string) => string | null;
|
|
80
80
|
/** Test seam. Defaults to the adapter's production spawner. */
|
|
81
|
-
spawn?: (
|
|
81
|
+
spawn?: (adapter: AdapterId, prompt: string, timeoutMs: number) => Promise<SpawnResult>;
|
|
82
82
|
/** Test seam. Defaults to writing under the coord root. */
|
|
83
|
-
persist?: (record:
|
|
83
|
+
persist?: (record: AdapterAttestation) => void;
|
|
84
84
|
/**
|
|
85
85
|
* Also probe `filesystemPolicyProjection` (ADR 0041). Off by default because
|
|
86
|
-
* it costs two extra turns per capable
|
|
86
|
+
* it costs two extra turns per capable adapter, against one for everything
|
|
87
87
|
* else: the observation needs a control run to be readable at all.
|
|
88
88
|
*/
|
|
89
89
|
projection?: boolean;
|
|
@@ -92,24 +92,24 @@ export interface RunHarnessAttestationOptions {
|
|
|
92
92
|
now?: () => Date;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
export async function
|
|
96
|
-
registry:
|
|
97
|
-
opts:
|
|
98
|
-
): Promise<
|
|
99
|
-
const ids = opts.
|
|
95
|
+
export async function runAdapterAttestation(
|
|
96
|
+
registry: AdapterRegistry,
|
|
97
|
+
opts: RunAdapterAttestationOptions = {},
|
|
98
|
+
): Promise<AdapterAttestationReport> {
|
|
99
|
+
const ids = opts.adapters?.length ? [...opts.adapters] : registry.ids();
|
|
100
100
|
const timeoutMs = opts.timeoutMs ?? DEFAULT_ATTESTATION_TIMEOUT_MS;
|
|
101
101
|
const cwd = opts.cwd ?? process.cwd();
|
|
102
102
|
const subscriptionOnly = opts.subscriptionOnly === true;
|
|
103
103
|
const versionProbe = opts.versionProbe ?? probeBinaryVersion;
|
|
104
104
|
const now = opts.now ?? (() => new Date());
|
|
105
|
-
const results:
|
|
105
|
+
const results: AdapterAttestationResult[] = [];
|
|
106
106
|
|
|
107
107
|
for (const id of ids) {
|
|
108
108
|
const adapter = registry.require(id);
|
|
109
109
|
const binaryVersion = versionProbe(adapter.profile.binary);
|
|
110
110
|
if (!binaryVersion) {
|
|
111
111
|
results.push({
|
|
112
|
-
|
|
112
|
+
adapter: id,
|
|
113
113
|
outcome: "skipped",
|
|
114
114
|
note: `${adapter.profile.binary} not found on PATH`,
|
|
115
115
|
});
|
|
@@ -129,7 +129,7 @@ export async function runHarnessAttestation(
|
|
|
129
129
|
});
|
|
130
130
|
} catch (error) {
|
|
131
131
|
results.push({
|
|
132
|
-
|
|
132
|
+
adapter: id,
|
|
133
133
|
outcome: "failed",
|
|
134
134
|
binaryVersion,
|
|
135
135
|
note: `probe threw: ${boundedReason((error as Error).message)}`,
|
|
@@ -141,7 +141,7 @@ export async function runHarnessAttestation(
|
|
|
141
141
|
// failed turn records nothing at all rather than a page of `unsupported`.
|
|
142
142
|
if (!result.ok) {
|
|
143
143
|
results.push({
|
|
144
|
-
|
|
144
|
+
adapter: id,
|
|
145
145
|
outcome: "unreachable",
|
|
146
146
|
binaryVersion,
|
|
147
147
|
durationMs: result.durationMs,
|
|
@@ -172,7 +172,7 @@ export async function runHarnessAttestation(
|
|
|
172
172
|
|
|
173
173
|
const record = sealAttestation({
|
|
174
174
|
schema_version: ATTESTATION_SCHEMA_VERSION,
|
|
175
|
-
|
|
175
|
+
adapter: id,
|
|
176
176
|
binary_version: binaryVersion,
|
|
177
177
|
profile_digest: profileDigest(adapter.profile),
|
|
178
178
|
subscription_only: subscriptionOnly,
|
|
@@ -184,7 +184,7 @@ export async function runHarnessAttestation(
|
|
|
184
184
|
else writeAttestation(record, { coordRoot: opts.coordRoot });
|
|
185
185
|
|
|
186
186
|
results.push({
|
|
187
|
-
|
|
187
|
+
adapter: id,
|
|
188
188
|
outcome: "recorded",
|
|
189
189
|
binaryVersion,
|
|
190
190
|
observations,
|
|
@@ -195,7 +195,7 @@ export async function runHarnessAttestation(
|
|
|
195
195
|
|
|
196
196
|
return {
|
|
197
197
|
generatedAt: now().toISOString(),
|
|
198
|
-
|
|
198
|
+
adapters: ids,
|
|
199
199
|
results,
|
|
200
200
|
recorded: results.filter((row) => row.outcome === "recorded").length,
|
|
201
201
|
incomplete: results.some((row) => row.outcome !== "recorded"),
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
import { resolve } from "node:path";
|
|
24
24
|
import { monorepoRoot } from "../agents/coord-client.ts";
|
|
25
25
|
import { stableDigest } from "../workflow/durable-record.ts";
|
|
26
|
-
import type {
|
|
26
|
+
import type { AdapterId, AdapterProfile, CapabilitySupport } from "./types.ts";
|
|
27
27
|
|
|
28
28
|
export const ATTESTATION_SCHEMA_VERSION = 2;
|
|
29
29
|
|
|
@@ -40,9 +40,9 @@ export const ATTESTABLE_DIMENSIONS = [
|
|
|
40
40
|
|
|
41
41
|
export type AttestableDimension = (typeof ATTESTABLE_DIMENSIONS)[number];
|
|
42
42
|
|
|
43
|
-
export interface
|
|
43
|
+
export interface AdapterAttestation {
|
|
44
44
|
schema_version: number;
|
|
45
|
-
|
|
45
|
+
adapter: AdapterId;
|
|
46
46
|
/** What the vendor binary reported when this was recorded. Staleness is
|
|
47
47
|
* keyed on this, so a vendor upgrade invalidates the record automatically. */
|
|
48
48
|
binary_version: string;
|
|
@@ -69,12 +69,12 @@ export interface AttestationStoreOptions {
|
|
|
69
69
|
export function attestationsDir(opts: AttestationStoreOptions = {}): string {
|
|
70
70
|
const root = opts.coordRoot ?? monorepoRoot();
|
|
71
71
|
if (!root) throw new Error("Not in a coord-aware repo (coord root resolved to null).");
|
|
72
|
-
return resolve(root, ".harnery", "
|
|
72
|
+
return resolve(root, ".harnery", "adapters", "attestations");
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
/** Stable identity of a declaration, so editing a claim invalidates the
|
|
76
76
|
* attestation that was recorded against the old one. */
|
|
77
|
-
export function profileDigest(profile:
|
|
77
|
+
export function profileDigest(profile: AdapterProfile): string {
|
|
78
78
|
return stableDigest({
|
|
79
79
|
id: profile.id,
|
|
80
80
|
binary: profile.binary,
|
|
@@ -82,31 +82,31 @@ export function profileDigest(profile: HarnessProfile): string {
|
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
function digestOf(record: Omit<
|
|
85
|
+
function digestOf(record: Omit<AdapterAttestation, "record_digest">): string {
|
|
86
86
|
return stableDigest(record);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
export function sealAttestation(
|
|
90
|
-
record: Omit<
|
|
91
|
-
):
|
|
90
|
+
record: Omit<AdapterAttestation, "record_digest">,
|
|
91
|
+
): AdapterAttestation {
|
|
92
92
|
return { ...record, record_digest: digestOf(record) };
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
function attestationPath(
|
|
96
|
-
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(
|
|
97
|
-
throw new Error(`unsafe
|
|
95
|
+
function attestationPath(adapter: AdapterId, opts: AttestationStoreOptions): string {
|
|
96
|
+
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(adapter)) {
|
|
97
|
+
throw new Error(`unsafe adapter id for an attestation path: ${adapter}`);
|
|
98
98
|
}
|
|
99
|
-
return resolve(attestationsDir(opts), `${
|
|
99
|
+
return resolve(attestationsDir(opts), `${adapter}.json`);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/** Replace-in-place write. Unlike a workflow record an attestation is meant to
|
|
103
103
|
* be re-recorded, so this is a mutable atomic swap rather than an immutable
|
|
104
104
|
* create. */
|
|
105
105
|
export function writeAttestation(
|
|
106
|
-
record:
|
|
106
|
+
record: AdapterAttestation,
|
|
107
107
|
opts: AttestationStoreOptions = {},
|
|
108
108
|
): string {
|
|
109
|
-
const path = attestationPath(record.
|
|
109
|
+
const path = attestationPath(record.adapter, opts);
|
|
110
110
|
mkdirSync(attestationsDir(opts), { recursive: true, mode: 0o700 });
|
|
111
111
|
const temporary = `${path}.tmp-${process.pid}`;
|
|
112
112
|
try {
|
|
@@ -130,12 +130,12 @@ export function writeAttestation(
|
|
|
130
130
|
* A record that fails its own digest is discarded rather than trusted, because
|
|
131
131
|
* the whole point of the file is that it was not hand-written. */
|
|
132
132
|
export function readAttestation(
|
|
133
|
-
|
|
133
|
+
adapter: AdapterId,
|
|
134
134
|
opts: AttestationStoreOptions = {},
|
|
135
|
-
):
|
|
135
|
+
): AdapterAttestation | null {
|
|
136
136
|
let raw: string;
|
|
137
137
|
try {
|
|
138
|
-
raw = readFileSync(attestationPath(
|
|
138
|
+
raw = readFileSync(attestationPath(adapter, opts), "utf8");
|
|
139
139
|
} catch {
|
|
140
140
|
return null;
|
|
141
141
|
}
|
|
@@ -145,17 +145,17 @@ export function readAttestation(
|
|
|
145
145
|
} catch {
|
|
146
146
|
return null;
|
|
147
147
|
}
|
|
148
|
-
return validateAttestation(parsed,
|
|
148
|
+
return validateAttestation(parsed, adapter);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
export function validateAttestation(
|
|
152
152
|
value: unknown,
|
|
153
|
-
|
|
154
|
-
):
|
|
153
|
+
adapter?: AdapterId,
|
|
154
|
+
): AdapterAttestation | null {
|
|
155
155
|
if (!value || typeof value !== "object") return null;
|
|
156
|
-
const record = value as
|
|
156
|
+
const record = value as AdapterAttestation;
|
|
157
157
|
if (record.schema_version !== ATTESTATION_SCHEMA_VERSION) return null;
|
|
158
|
-
if (typeof record.
|
|
158
|
+
if (typeof record.adapter !== "string" || (adapter && record.adapter !== adapter)) return null;
|
|
159
159
|
if (typeof record.binary_version !== "string" || typeof record.profile_digest !== "string") {
|
|
160
160
|
return null;
|
|
161
161
|
}
|
|
@@ -171,39 +171,39 @@ export function validateAttestation(
|
|
|
171
171
|
/** An attestation speaks only for the vendor version and declaration it was
|
|
172
172
|
* recorded against. */
|
|
173
173
|
export function isAttestationCurrent(
|
|
174
|
-
record:
|
|
174
|
+
record: AdapterAttestation | null,
|
|
175
175
|
binaryVersion: string | null,
|
|
176
|
-
profile:
|
|
176
|
+
profile: AdapterProfile,
|
|
177
177
|
subscriptionOnly?: boolean,
|
|
178
|
-
): record is
|
|
178
|
+
): record is AdapterAttestation {
|
|
179
179
|
if (!record || !binaryVersion) return false;
|
|
180
180
|
if (record.binary_version !== binaryVersion) return false;
|
|
181
181
|
if (subscriptionOnly !== undefined && record.subscription_only !== subscriptionOnly) return false;
|
|
182
182
|
return record.profile_digest === profileDigest(profile);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
export function listAttestations(opts: AttestationStoreOptions = {}):
|
|
185
|
+
export function listAttestations(opts: AttestationStoreOptions = {}): AdapterAttestation[] {
|
|
186
186
|
let names: string[];
|
|
187
187
|
try {
|
|
188
188
|
names = readdirSync(attestationsDir(opts));
|
|
189
189
|
} catch {
|
|
190
190
|
return [];
|
|
191
191
|
}
|
|
192
|
-
const records:
|
|
192
|
+
const records: AdapterAttestation[] = [];
|
|
193
193
|
for (const name of names) {
|
|
194
194
|
if (!name.endsWith(".json")) continue;
|
|
195
195
|
const record = readAttestation(name.slice(0, -".json".length), opts);
|
|
196
196
|
if (record) records.push(record);
|
|
197
197
|
}
|
|
198
|
-
return records.sort((a, b) => a.
|
|
198
|
+
return records.sort((a, b) => a.adapter.localeCompare(b.adapter));
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
/** Both
|
|
201
|
+
/** Both adapter-derived proof inputs, read once, for a workflow run
|
|
202
202
|
* (ADR 0038). Callers inject the result so the engine performs no capability
|
|
203
|
-
* lookups of its own. A
|
|
203
|
+
* lookups of its own. A adapter with no current attestation simply has no
|
|
204
204
|
* citation; that absence is not a proof unknown. */
|
|
205
|
-
export function
|
|
206
|
-
profiles: readonly
|
|
205
|
+
export function adapterProofInputs(
|
|
206
|
+
profiles: readonly AdapterProfile[],
|
|
207
207
|
opts: AttestationStoreOptions & {
|
|
208
208
|
versionProbe: (binary: string) => string | null;
|
|
209
209
|
/** Billing policy this run will use, so a record made under the other mode
|
|
@@ -211,24 +211,24 @@ export function harnessProofInputs(
|
|
|
211
211
|
subscriptionOnly?: boolean;
|
|
212
212
|
},
|
|
213
213
|
): {
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
adapterEvidence: Record<string, { toolEvidence: AdapterProfile["capabilities"]["toolEvidence"] }>;
|
|
215
|
+
adapterAttestations: Record<
|
|
216
216
|
string,
|
|
217
217
|
{ binary_version: string; observed_at: string; record_digest: string }
|
|
218
218
|
>;
|
|
219
219
|
} {
|
|
220
|
-
const
|
|
220
|
+
const adapterEvidence: Record<
|
|
221
221
|
string,
|
|
222
|
-
{ toolEvidence:
|
|
222
|
+
{ toolEvidence: AdapterProfile["capabilities"]["toolEvidence"] }
|
|
223
223
|
> = {};
|
|
224
|
-
const
|
|
224
|
+
const adapterAttestations: Record<
|
|
225
225
|
string,
|
|
226
226
|
{ binary_version: string; observed_at: string; record_digest: string }
|
|
227
227
|
> = {};
|
|
228
228
|
|
|
229
229
|
for (const profile of profiles) {
|
|
230
|
-
|
|
231
|
-
let record:
|
|
230
|
+
adapterEvidence[profile.id] = { toolEvidence: profile.capabilities.toolEvidence };
|
|
231
|
+
let record: AdapterAttestation | null = null;
|
|
232
232
|
try {
|
|
233
233
|
record = readAttestation(profile.id, opts);
|
|
234
234
|
} catch {
|
|
@@ -245,11 +245,11 @@ export function harnessProofInputs(
|
|
|
245
245
|
) {
|
|
246
246
|
continue;
|
|
247
247
|
}
|
|
248
|
-
|
|
248
|
+
adapterAttestations[profile.id] = {
|
|
249
249
|
binary_version: record.binary_version,
|
|
250
250
|
observed_at: record.observed_at,
|
|
251
251
|
record_digest: record.record_digest,
|
|
252
252
|
};
|
|
253
253
|
}
|
|
254
|
-
return {
|
|
254
|
+
return { adapterEvidence, adapterAttestations };
|
|
255
255
|
}
|