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
|
@@ -3,22 +3,22 @@ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { readWorkItem } from "../work/read.ts";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type
|
|
10
|
-
type
|
|
11
|
-
type
|
|
12
|
-
type
|
|
13
|
-
type
|
|
14
|
-
type
|
|
15
|
-
type
|
|
16
|
-
type
|
|
17
|
-
type
|
|
18
|
-
type
|
|
19
|
-
type
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
GOVERNOR_PLAN_SCHEMA_VERSION,
|
|
7
|
+
type GovernorPlanEvent,
|
|
8
|
+
type GovernorPlanEventType,
|
|
9
|
+
type GovernorPlanHistory,
|
|
10
|
+
type GovernorPlanProposal,
|
|
11
|
+
type GovernorPlanRecord,
|
|
12
|
+
type GovernorPlanRequest,
|
|
13
|
+
type GovernorPlanReviewFinding,
|
|
14
|
+
type GovernorPlanReviewReceipt,
|
|
15
|
+
type GovernorPlanReviewReviewer,
|
|
16
|
+
type GovernorPlanReviewRound,
|
|
17
|
+
type GovernorPlanReviewSummary,
|
|
18
|
+
type GovernorPlanReviewVerdict,
|
|
19
|
+
type GovernorReplanningPolicy,
|
|
20
|
+
MAX_GOVERNOR_PLAN_REVIEWERS,
|
|
21
|
+
MAX_GOVERNOR_PLAN_REVISION_ROUNDS,
|
|
22
22
|
} from "./plan-types.ts";
|
|
23
23
|
|
|
24
24
|
const PLAN_ID = /^plan-[0-9]{4}-[a-f0-9]{8}$/;
|
|
@@ -31,7 +31,7 @@ const MAX_PLANS = 100;
|
|
|
31
31
|
const MAX_RECORD_BYTES = 256 * 1024;
|
|
32
32
|
const MAX_EVENTS_BYTES = 512 * 1024;
|
|
33
33
|
const MAX_EVENTS = 100;
|
|
34
|
-
const EVENT_TYPES = new Set<
|
|
34
|
+
const EVENT_TYPES = new Set<GovernorPlanEventType>([
|
|
35
35
|
"plan.awaiting_approval",
|
|
36
36
|
"plan.resumed",
|
|
37
37
|
"plan.reviewed",
|
|
@@ -42,14 +42,15 @@ const EVENT_TYPES = new Set<SupervisorPlanEventType>([
|
|
|
42
42
|
"plan.retry_requested",
|
|
43
43
|
"plan.attention",
|
|
44
44
|
"plan.failed",
|
|
45
|
+
"plan.reopened",
|
|
45
46
|
]);
|
|
46
47
|
|
|
47
|
-
export function
|
|
48
|
+
export function readGovernorPlans(
|
|
48
49
|
coordRootRaw: string,
|
|
49
50
|
goalId: string,
|
|
50
51
|
originalRootWorkId: string,
|
|
51
|
-
):
|
|
52
|
-
assertId(goalId, GOAL_ID, "
|
|
52
|
+
): GovernorPlanHistory {
|
|
53
|
+
assertId(goalId, GOAL_ID, "governor id");
|
|
53
54
|
assertId(originalRootWorkId, WORK_ID, "work id");
|
|
54
55
|
const coordRoot = resolve(coordRootRaw);
|
|
55
56
|
const root = plansRoot(coordRoot, goalId);
|
|
@@ -67,14 +68,14 @@ export function readSupervisorPlans(
|
|
|
67
68
|
const entries = readdirSync(root, { withFileTypes: true })
|
|
68
69
|
.filter((entry) => entry.isDirectory() && PLAN_ID.test(entry.name))
|
|
69
70
|
.map((entry) => entry.name);
|
|
70
|
-
if (entries.length > MAX_PLANS) throw new Error(`
|
|
71
|
+
if (entries.length > MAX_PLANS) throw new Error(`governor plan history exceeds ${MAX_PLANS}`);
|
|
71
72
|
const plans = entries
|
|
72
|
-
.map((planId) =>
|
|
73
|
+
.map((planId) => readGovernorPlan(coordRootRaw, goalId, planId))
|
|
73
74
|
.sort((left, right) => left.request.sequence - right.request.sequence);
|
|
74
75
|
const sequences = new Set<number>();
|
|
75
76
|
for (const plan of plans) {
|
|
76
77
|
if (sequences.has(plan.request.sequence)) {
|
|
77
|
-
throw new Error(`
|
|
78
|
+
throw new Error(`governor ${goalId} has duplicate plan sequence ${plan.request.sequence}`);
|
|
78
79
|
}
|
|
79
80
|
sequences.add(plan.request.sequence);
|
|
80
81
|
}
|
|
@@ -107,7 +108,7 @@ export function readSupervisorPlans(
|
|
|
107
108
|
completedPlans.length > 1 ||
|
|
108
109
|
(completedPlans.length === 1 && completedPlans[0] !== plans.at(-1))
|
|
109
110
|
) {
|
|
110
|
-
throw new Error(`
|
|
111
|
+
throw new Error(`governor ${goalId} has invalid completion history`);
|
|
111
112
|
}
|
|
112
113
|
completed = completedPlans.length === 1;
|
|
113
114
|
return {
|
|
@@ -122,23 +123,23 @@ export function readSupervisorPlans(
|
|
|
122
123
|
};
|
|
123
124
|
}
|
|
124
125
|
|
|
125
|
-
export function
|
|
126
|
+
export function readGovernorPlan(
|
|
126
127
|
coordRootRaw: string,
|
|
127
128
|
goalId: string,
|
|
128
129
|
planId: string,
|
|
129
|
-
):
|
|
130
|
-
assertId(goalId, GOAL_ID, "
|
|
131
|
-
assertId(planId, PLAN_ID, "
|
|
130
|
+
): GovernorPlanRecord {
|
|
131
|
+
assertId(goalId, GOAL_ID, "governor id");
|
|
132
|
+
assertId(planId, PLAN_ID, "governor plan id");
|
|
132
133
|
const coordRoot = resolve(coordRootRaw);
|
|
133
134
|
const dir = planDir(coordRoot, goalId, planId);
|
|
134
|
-
const request = readJson<
|
|
135
|
+
const request = readJson<GovernorPlanRequest>(join(dir, "request.json"), "plan request");
|
|
135
136
|
validateRequest(request, goalId, planId);
|
|
136
137
|
const proposalPath = join(dir, "proposal.json");
|
|
137
138
|
const proposal = existsSync(proposalPath)
|
|
138
|
-
? readJson<
|
|
139
|
+
? readJson<GovernorPlanProposal>(proposalPath, "plan proposal")
|
|
139
140
|
: undefined;
|
|
140
141
|
if (proposal) validateProposalEnvelope(proposal, planId);
|
|
141
|
-
const review =
|
|
142
|
+
const review = readGovernorPlanReviewReceipt(coordRootRaw, goalId, planId);
|
|
142
143
|
const events = readEvents(join(dir, "events.jsonl"), planId);
|
|
143
144
|
const derived = deriveStatus(coordRoot, events, proposal);
|
|
144
145
|
return {
|
|
@@ -150,17 +151,17 @@ export function readSupervisorPlan(
|
|
|
150
151
|
};
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
export function
|
|
154
|
+
export function readGovernorPlanReviewReceipt(
|
|
154
155
|
coordRootRaw: string,
|
|
155
156
|
goalId: string,
|
|
156
157
|
planId: string,
|
|
157
|
-
):
|
|
158
|
-
assertId(goalId, GOAL_ID, "
|
|
159
|
-
assertId(planId, PLAN_ID, "
|
|
158
|
+
): GovernorPlanReviewReceipt | undefined {
|
|
159
|
+
assertId(goalId, GOAL_ID, "governor id");
|
|
160
|
+
assertId(planId, PLAN_ID, "governor plan id");
|
|
160
161
|
const coordRoot = resolve(coordRootRaw);
|
|
161
162
|
const path = join(planDir(coordRoot, goalId, planId), "review.json");
|
|
162
163
|
if (!existsSync(path)) return undefined;
|
|
163
|
-
const receipt = readJson<
|
|
164
|
+
const receipt = readJson<GovernorPlanReviewReceipt>(path, "plan review receipt");
|
|
164
165
|
validateReviewReceipt(receipt, planId);
|
|
165
166
|
const reviewPolicy = readFrozenReviewPolicy(coordRoot, goalId);
|
|
166
167
|
if (reviewPolicy) validateReviewReceiptMatchesPolicy(receipt, planId, reviewPolicy);
|
|
@@ -169,12 +170,25 @@ export function readSupervisorPlanReviewReceipt(
|
|
|
169
170
|
|
|
170
171
|
function deriveStatus(
|
|
171
172
|
coordRoot: string,
|
|
172
|
-
events:
|
|
173
|
-
proposal:
|
|
174
|
-
): Pick<
|
|
173
|
+
events: GovernorPlanEvent[],
|
|
174
|
+
proposal: GovernorPlanProposal | undefined,
|
|
175
|
+
): Pick<
|
|
176
|
+
GovernorPlanRecord,
|
|
177
|
+
"status" | "approval_id" | "root_work_id" | "work_ids" | "reason" | "class"
|
|
178
|
+
> {
|
|
175
179
|
const latest = events.at(-1);
|
|
176
180
|
const completed = [...events].reverse().find((event) => event.event === "plan.completed");
|
|
177
181
|
if (completed) {
|
|
182
|
+
// ADR 0050: an operator finding on work beneath a completed mission reopens
|
|
183
|
+
// the mission by APPENDING, never by rewriting. The accepted completion stays
|
|
184
|
+
// in the log verbatim; a later `plan.reopened` supersedes it, which is what
|
|
185
|
+
// drops `plans.completed` and lets the projection dispatch again.
|
|
186
|
+
const reopened = [...events]
|
|
187
|
+
.reverse()
|
|
188
|
+
.find((event) => event.event === "plan.reopened" && event.seq > completed.seq);
|
|
189
|
+
if (reopened) {
|
|
190
|
+
return { status: "reopened", work_ids: [], reason: reopened.reason };
|
|
191
|
+
}
|
|
178
192
|
return { status: "completed", work_ids: [], reason: completed.reason };
|
|
179
193
|
}
|
|
180
194
|
const applied = [...events].reverse().find((event) => event.event === "plan.applied");
|
|
@@ -196,7 +210,10 @@ function deriveStatus(
|
|
|
196
210
|
return { status: "attention", work_ids: [], reason: latest.reason };
|
|
197
211
|
}
|
|
198
212
|
if (latest?.event === "plan.failed") {
|
|
199
|
-
|
|
213
|
+
// ADR 0046: carry the planner run's failure class so the projection can stop
|
|
214
|
+
// an environment failure and bound consecutive upstream ones, rather than
|
|
215
|
+
// replanning an unchanged environment to budget exhaustion.
|
|
216
|
+
return { status: "failed", work_ids: [], reason: latest.reason, class: latest.class };
|
|
200
217
|
}
|
|
201
218
|
const parked = [...events].reverse().find((event) => event.event === "plan.awaiting_approval");
|
|
202
219
|
const resumedAfterPark =
|
|
@@ -214,22 +231,21 @@ function deriveStatus(
|
|
|
214
231
|
return { status: "interrupted", work_ids: [], reason: latest?.reason };
|
|
215
232
|
}
|
|
216
233
|
|
|
217
|
-
function readEvents(path: string, planId: string):
|
|
234
|
+
function readEvents(path: string, planId: string): GovernorPlanEvent[] {
|
|
218
235
|
if (!existsSync(path)) return [];
|
|
219
236
|
const size = statSync(path).size;
|
|
220
|
-
if (size > MAX_EVENTS_BYTES) throw new Error("
|
|
237
|
+
if (size > MAX_EVENTS_BYTES) throw new Error("governor plan events exceed their byte limit");
|
|
221
238
|
const body = readFileSync(path, "utf8");
|
|
222
|
-
if (body && !body.endsWith("\n"))
|
|
223
|
-
throw new Error(`supervisor plan ${planId} has a partial event`);
|
|
239
|
+
if (body && !body.endsWith("\n")) throw new Error(`governor plan ${planId} has a partial event`);
|
|
224
240
|
const lines = body.split("\n").filter(Boolean);
|
|
225
|
-
if (lines.length > MAX_EVENTS) throw new Error(`
|
|
241
|
+
if (lines.length > MAX_EVENTS) throw new Error(`governor plan exceeds ${MAX_EVENTS} events`);
|
|
226
242
|
return lines.map((line, index) => {
|
|
227
|
-
let event:
|
|
243
|
+
let event: GovernorPlanEvent;
|
|
228
244
|
try {
|
|
229
|
-
event = JSON.parse(line) as
|
|
245
|
+
event = JSON.parse(line) as GovernorPlanEvent;
|
|
230
246
|
} catch (error) {
|
|
231
247
|
throw new Error(
|
|
232
|
-
`cannot parse
|
|
248
|
+
`cannot parse governor plan ${planId} event ${index + 1}: ${(error as Error).message}`,
|
|
233
249
|
);
|
|
234
250
|
}
|
|
235
251
|
validateEvent(event, planId, index + 1);
|
|
@@ -237,9 +253,9 @@ function readEvents(path: string, planId: string): SupervisorPlanEvent[] {
|
|
|
237
253
|
});
|
|
238
254
|
}
|
|
239
255
|
|
|
240
|
-
function validateRequest(request:
|
|
256
|
+
function validateRequest(request: GovernorPlanRequest, goalId: string, planId: string): void {
|
|
241
257
|
if (
|
|
242
|
-
request.schema_version !==
|
|
258
|
+
request.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
243
259
|
request.id !== planId ||
|
|
244
260
|
request.goal_id !== goalId ||
|
|
245
261
|
!Number.isSafeInteger(request.sequence) ||
|
|
@@ -254,13 +270,13 @@ function validateRequest(request: SupervisorPlanRequest, goalId: string, planId:
|
|
|
254
270
|
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(request.workflow_run_id) ||
|
|
255
271
|
!validTimestamp(request.created_at)
|
|
256
272
|
) {
|
|
257
|
-
throw new Error(`
|
|
273
|
+
throw new Error(`governor plan request ${planId} has an unsupported schema`);
|
|
258
274
|
}
|
|
259
275
|
}
|
|
260
276
|
|
|
261
|
-
function validateProposalEnvelope(proposal:
|
|
277
|
+
function validateProposalEnvelope(proposal: GovernorPlanProposal, planId: string): void {
|
|
262
278
|
if (
|
|
263
|
-
proposal.schema_version !==
|
|
279
|
+
proposal.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
264
280
|
proposal.plan_id !== planId ||
|
|
265
281
|
!["apply", "complete", "attention"].includes(proposal.decision) ||
|
|
266
282
|
typeof proposal.rationale !== "string" ||
|
|
@@ -272,7 +288,7 @@ function validateProposalEnvelope(proposal: SupervisorPlanProposal, planId: stri
|
|
|
272
288
|
proposal.root.length > 32 ||
|
|
273
289
|
!validTimestamp(proposal.proposed_at)
|
|
274
290
|
) {
|
|
275
|
-
throw new Error(`
|
|
291
|
+
throw new Error(`governor plan proposal ${planId} has an unsupported schema`);
|
|
276
292
|
}
|
|
277
293
|
if (proposal.milestone !== undefined) {
|
|
278
294
|
const milestone = proposal.milestone;
|
|
@@ -294,14 +310,14 @@ function validateProposalEnvelope(proposal: SupervisorPlanProposal, planId: stri
|
|
|
294
310
|
typeof criterion !== "string" || criterion.length < 1 || criterion.length > 500,
|
|
295
311
|
)
|
|
296
312
|
) {
|
|
297
|
-
throw new Error(`
|
|
313
|
+
throw new Error(`governor plan proposal ${planId} milestone is invalid`);
|
|
298
314
|
}
|
|
299
315
|
}
|
|
300
316
|
if (
|
|
301
317
|
(proposal.decision === "attention" || proposal.decision === "complete") &&
|
|
302
318
|
(proposal.root !== "" || proposal.work.length > 0 || proposal.milestone !== undefined)
|
|
303
319
|
) {
|
|
304
|
-
throw new Error(`
|
|
320
|
+
throw new Error(`governor plan proposal ${planId} terminal decision contains work`);
|
|
305
321
|
}
|
|
306
322
|
for (const [index, spec] of proposal.work.entries()) {
|
|
307
323
|
if (
|
|
@@ -322,88 +338,88 @@ function validateProposalEnvelope(proposal: SupervisorPlanProposal, planId: stri
|
|
|
322
338
|
spec.dependencies.some((value) => typeof value !== "string" || value.length > 100) ||
|
|
323
339
|
!TEMPLATE_ID.test(spec.template)
|
|
324
340
|
) {
|
|
325
|
-
throw new Error(`
|
|
341
|
+
throw new Error(`governor plan proposal ${planId} work[${index}] is invalid`);
|
|
326
342
|
}
|
|
327
343
|
}
|
|
328
344
|
}
|
|
329
345
|
|
|
330
|
-
function validateReviewReceipt(receipt:
|
|
346
|
+
function validateReviewReceipt(receipt: GovernorPlanReviewReceipt, planId: string): void {
|
|
331
347
|
if (
|
|
332
348
|
!receipt ||
|
|
333
349
|
typeof receipt !== "object" ||
|
|
334
|
-
receipt.schema_version !==
|
|
350
|
+
receipt.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
335
351
|
receipt.plan_id !== planId ||
|
|
336
352
|
!["passed", "revision_exhausted", "attention", "failed"].includes(receipt.status) ||
|
|
337
353
|
!/^[a-f0-9]{64}$/.test(receipt.candidate_sha256) ||
|
|
338
354
|
!Array.isArray(receipt.rounds) ||
|
|
339
355
|
receipt.rounds.length < 1 ||
|
|
340
|
-
receipt.rounds.length >
|
|
356
|
+
receipt.rounds.length > MAX_GOVERNOR_PLAN_REVISION_ROUNDS + 1
|
|
341
357
|
) {
|
|
342
|
-
throw new Error(`
|
|
358
|
+
throw new Error(`governor plan review ${planId} has an unsupported schema`);
|
|
343
359
|
}
|
|
344
360
|
validateProposalEnvelope(receipt.final_candidate, planId);
|
|
345
361
|
if (receipt.candidate_sha256 !== candidateDigest(receipt.final_candidate)) {
|
|
346
|
-
throw new Error(`
|
|
362
|
+
throw new Error(`governor plan review ${planId} has invalid candidate digest`);
|
|
347
363
|
}
|
|
348
364
|
receipt.rounds.forEach((round, index) => {
|
|
349
365
|
validateReviewRound(round, planId, index + 1);
|
|
350
366
|
});
|
|
351
367
|
const finalRound = receipt.rounds.at(-1);
|
|
352
368
|
if (finalRound?.candidate_sha256 !== receipt.candidate_sha256) {
|
|
353
|
-
throw new Error(`
|
|
369
|
+
throw new Error(`governor plan review ${planId} final round does not match its candidate`);
|
|
354
370
|
}
|
|
355
371
|
if (receipt.status === "passed" && finalRound?.outcome !== "approved") {
|
|
356
|
-
throw new Error(`
|
|
372
|
+
throw new Error(`governor plan review ${planId} passed without approval`);
|
|
357
373
|
}
|
|
358
374
|
if (receipt.status === "attention" && finalRound?.outcome === "approved") {
|
|
359
|
-
throw new Error(`
|
|
375
|
+
throw new Error(`governor plan review ${planId} attention conflicts with approval`);
|
|
360
376
|
}
|
|
361
377
|
}
|
|
362
378
|
|
|
363
379
|
function readFrozenReviewPolicy(
|
|
364
380
|
coordRoot: string,
|
|
365
381
|
goalId: string,
|
|
366
|
-
):
|
|
367
|
-
const path = join(coordRoot, ".harnery", "
|
|
382
|
+
): GovernorReplanningPolicy["review"] | undefined {
|
|
383
|
+
const path = join(coordRoot, ".harnery", "governors", goalId, "intent.json");
|
|
368
384
|
if (!existsSync(path)) return undefined;
|
|
369
|
-
const intent = readJson<{ replanning?:
|
|
385
|
+
const intent = readJson<{ replanning?: GovernorReplanningPolicy }>(path, "governor intent");
|
|
370
386
|
return intent.replanning?.review;
|
|
371
387
|
}
|
|
372
388
|
|
|
373
389
|
function validateReviewReceiptMatchesPolicy(
|
|
374
|
-
receipt:
|
|
390
|
+
receipt: GovernorPlanReviewReceipt,
|
|
375
391
|
planId: string,
|
|
376
|
-
review: NonNullable<
|
|
392
|
+
review: NonNullable<GovernorReplanningPolicy["review"]>,
|
|
377
393
|
): void {
|
|
378
394
|
if (receipt.rounds.length > review.max_revision_rounds + 1) {
|
|
379
|
-
throw new Error(`
|
|
395
|
+
throw new Error(`governor plan review ${planId} exceeds the frozen review policy`);
|
|
380
396
|
}
|
|
381
397
|
for (const round of receipt.rounds) {
|
|
382
398
|
if (round.reviewers.length !== review.reviewer_specialists.length) {
|
|
383
|
-
throw new Error(`
|
|
399
|
+
throw new Error(`governor plan review ${planId} does not match the frozen review policy`);
|
|
384
400
|
}
|
|
385
401
|
round.reviewers.forEach((reviewer, index) => {
|
|
386
402
|
if (reviewer.specialist !== review.reviewer_specialists[index]) {
|
|
387
|
-
throw new Error(`
|
|
403
|
+
throw new Error(`governor plan review ${planId} does not match the frozen review policy`);
|
|
388
404
|
}
|
|
389
405
|
});
|
|
390
406
|
const outcome = aggregateReviewers(round.reviewers);
|
|
391
407
|
if (round.outcome !== outcome) {
|
|
392
|
-
throw new Error(`
|
|
408
|
+
throw new Error(`governor plan review ${planId} has an invalid reviewer outcome`);
|
|
393
409
|
}
|
|
394
410
|
}
|
|
395
411
|
const finalRound = receipt.rounds.at(-1)!;
|
|
396
412
|
if (receipt.status === "passed" && finalRound.outcome !== "approved") {
|
|
397
|
-
throw new Error(`
|
|
413
|
+
throw new Error(`governor plan review ${planId} passed without policy approval`);
|
|
398
414
|
}
|
|
399
415
|
if (receipt.status === "revision_exhausted" && finalRound.round <= review.max_revision_rounds) {
|
|
400
|
-
throw new Error(`
|
|
416
|
+
throw new Error(`governor plan review ${planId} exhausted before the frozen review limit`);
|
|
401
417
|
}
|
|
402
418
|
}
|
|
403
419
|
|
|
404
420
|
function aggregateReviewers(
|
|
405
|
-
reviewers: readonly
|
|
406
|
-
):
|
|
421
|
+
reviewers: readonly GovernorPlanReviewReviewer[],
|
|
422
|
+
): GovernorPlanReviewRound["outcome"] {
|
|
407
423
|
if (reviewers.length < 1) return "failed";
|
|
408
424
|
if (reviewers.some((reviewer) => reviewer.verdict === "attention")) return "attention";
|
|
409
425
|
if (
|
|
@@ -418,13 +434,13 @@ function aggregateReviewers(
|
|
|
418
434
|
return "approved";
|
|
419
435
|
}
|
|
420
436
|
|
|
421
|
-
function candidateDigest(candidate:
|
|
437
|
+
function candidateDigest(candidate: GovernorPlanProposal): string {
|
|
422
438
|
return createHash("sha256")
|
|
423
439
|
.update(JSON.stringify(canonicalCandidate(candidate)))
|
|
424
440
|
.digest("hex");
|
|
425
441
|
}
|
|
426
442
|
|
|
427
|
-
function canonicalCandidate(candidate:
|
|
443
|
+
function canonicalCandidate(candidate: GovernorPlanProposal): unknown {
|
|
428
444
|
return {
|
|
429
445
|
schema_version: candidate.schema_version,
|
|
430
446
|
plan_id: candidate.plan_id,
|
|
@@ -437,7 +453,7 @@ function canonicalCandidate(candidate: SupervisorPlanProposal): unknown {
|
|
|
437
453
|
}
|
|
438
454
|
|
|
439
455
|
function validateReviewRound(
|
|
440
|
-
round:
|
|
456
|
+
round: GovernorPlanReviewRound,
|
|
441
457
|
planId: string,
|
|
442
458
|
sequence: number,
|
|
443
459
|
): void {
|
|
@@ -448,12 +464,12 @@ function validateReviewRound(
|
|
|
448
464
|
!/^[a-f0-9]{64}$/.test(round.candidate_sha256) ||
|
|
449
465
|
!Array.isArray(round.reviewers) ||
|
|
450
466
|
round.reviewers.length < 1 ||
|
|
451
|
-
round.reviewers.length >
|
|
467
|
+
round.reviewers.length > MAX_GOVERNOR_PLAN_REVIEWERS ||
|
|
452
468
|
!["approved", "revise", "attention", "failed"].includes(round.outcome) ||
|
|
453
469
|
(round.revision_workflow_run_id !== undefined &&
|
|
454
470
|
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(round.revision_workflow_run_id))
|
|
455
471
|
) {
|
|
456
|
-
throw new Error(`
|
|
472
|
+
throw new Error(`governor plan review ${planId} round ${sequence} is invalid`);
|
|
457
473
|
}
|
|
458
474
|
round.reviewers.forEach((reviewer, index) => {
|
|
459
475
|
validateReviewReviewer(reviewer, planId, sequence, index);
|
|
@@ -461,7 +477,7 @@ function validateReviewRound(
|
|
|
461
477
|
}
|
|
462
478
|
|
|
463
479
|
function validateReviewReviewer(
|
|
464
|
-
reviewer:
|
|
480
|
+
reviewer: GovernorPlanReviewReviewer,
|
|
465
481
|
planId: string,
|
|
466
482
|
round: number,
|
|
467
483
|
index: number,
|
|
@@ -472,14 +488,14 @@ function validateReviewReviewer(
|
|
|
472
488
|
typeof reviewer.specialist !== "string" ||
|
|
473
489
|
reviewer.specialist.length < 1 ||
|
|
474
490
|
reviewer.specialist.length > 100 ||
|
|
475
|
-
!["approve", "revise", "attention"].includes(reviewer.verdict as
|
|
491
|
+
!["approve", "revise", "attention"].includes(reviewer.verdict as GovernorPlanReviewVerdict) ||
|
|
476
492
|
typeof reviewer.rationale !== "string" ||
|
|
477
493
|
reviewer.rationale.length < 1 ||
|
|
478
494
|
reviewer.rationale.length > 2_000 ||
|
|
479
495
|
!Array.isArray(reviewer.findings) ||
|
|
480
496
|
reviewer.findings.length > 50
|
|
481
497
|
) {
|
|
482
|
-
throw new Error(`
|
|
498
|
+
throw new Error(`governor plan review ${planId} round ${round} reviewer ${index} is invalid`);
|
|
483
499
|
}
|
|
484
500
|
reviewer.findings.forEach((finding, findingIndex) => {
|
|
485
501
|
validateReviewFinding(finding, planId, round, index, findingIndex);
|
|
@@ -487,7 +503,7 @@ function validateReviewReviewer(
|
|
|
487
503
|
}
|
|
488
504
|
|
|
489
505
|
function validateReviewFinding(
|
|
490
|
-
finding:
|
|
506
|
+
finding: GovernorPlanReviewFinding,
|
|
491
507
|
planId: string,
|
|
492
508
|
round: number,
|
|
493
509
|
reviewerIndex: number,
|
|
@@ -507,12 +523,12 @@ function validateReviewFinding(
|
|
|
507
523
|
finding.recommendation.length > 1_000
|
|
508
524
|
) {
|
|
509
525
|
throw new Error(
|
|
510
|
-
`
|
|
526
|
+
`governor plan review ${planId} round ${round} reviewer ${reviewerIndex} finding ${findingIndex} is invalid`,
|
|
511
527
|
);
|
|
512
528
|
}
|
|
513
529
|
}
|
|
514
530
|
|
|
515
|
-
function summarizeReview(receipt:
|
|
531
|
+
function summarizeReview(receipt: GovernorPlanReviewReceipt): GovernorPlanReviewSummary {
|
|
516
532
|
const findings = receipt.rounds.flatMap((round) =>
|
|
517
533
|
round.reviewers.flatMap((reviewer) => reviewer.findings),
|
|
518
534
|
);
|
|
@@ -525,9 +541,9 @@ function summarizeReview(receipt: SupervisorPlanReviewReceipt): SupervisorPlanRe
|
|
|
525
541
|
};
|
|
526
542
|
}
|
|
527
543
|
|
|
528
|
-
function validateEvent(event:
|
|
544
|
+
function validateEvent(event: GovernorPlanEvent, planId: string, sequence: number): void {
|
|
529
545
|
if (
|
|
530
|
-
event.schema_version !==
|
|
546
|
+
event.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
531
547
|
event.plan_id !== planId ||
|
|
532
548
|
event.seq !== sequence ||
|
|
533
549
|
!EVENT_TYPES.has(event.event) ||
|
|
@@ -539,19 +555,27 @@ function validateEvent(event: SupervisorPlanEvent, planId: string, sequence: num
|
|
|
539
555
|
event.reason.length < 1 ||
|
|
540
556
|
event.reason.length > 2_000
|
|
541
557
|
) {
|
|
542
|
-
throw new Error(`
|
|
558
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an unsupported schema`);
|
|
543
559
|
}
|
|
544
560
|
if (event.approval_id !== undefined && !APPROVAL_ID.test(event.approval_id)) {
|
|
545
|
-
throw new Error(`
|
|
561
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an invalid approval id`);
|
|
546
562
|
}
|
|
547
563
|
if (event.root_work_id !== undefined && !WORK_ID.test(event.root_work_id)) {
|
|
548
|
-
throw new Error(`
|
|
564
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an invalid root work id`);
|
|
549
565
|
}
|
|
550
566
|
if (event.work_ids !== undefined) {
|
|
551
567
|
if (!Array.isArray(event.work_ids) || event.work_ids.some((id) => !WORK_ID.test(id))) {
|
|
552
|
-
throw new Error(`
|
|
568
|
+
throw new Error(`governor plan ${planId} event ${sequence} has invalid work ids`);
|
|
553
569
|
}
|
|
554
570
|
}
|
|
571
|
+
if (
|
|
572
|
+
event.class !== undefined &&
|
|
573
|
+
event.class !== "environment" &&
|
|
574
|
+
event.class !== "upstream" &&
|
|
575
|
+
event.class !== "decision"
|
|
576
|
+
) {
|
|
577
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an unknown failure class`);
|
|
578
|
+
}
|
|
555
579
|
}
|
|
556
580
|
|
|
557
581
|
function approvalIsResolved(coordRoot: string, approvalId: string): boolean {
|
|
@@ -577,7 +601,7 @@ function readJson<T>(path: string, label: string): T {
|
|
|
577
601
|
}
|
|
578
602
|
|
|
579
603
|
function plansRoot(coordRoot: string, goalId: string): string {
|
|
580
|
-
return join(coordRoot, ".harnery", "
|
|
604
|
+
return join(coordRoot, ".harnery", "governors", goalId, "plans");
|
|
581
605
|
}
|
|
582
606
|
|
|
583
607
|
function planDir(coordRoot: string, goalId: string, planId: string): string {
|