harnery 0.30.0 → 0.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/commander.d.ts +8 -0
- package/dist/commander.d.ts.map +1 -1
- package/dist/commander.js +14 -13
- package/dist/commands/adapter.d.ts +12 -0
- package/dist/commands/adapter.d.ts.map +1 -0
- package/dist/commands/{harness.js → adapter.js} +35 -35
- package/dist/commands/agents.d.ts +3 -2
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +185 -74
- package/dist/commands/artifacts.d.ts +4 -0
- package/dist/commands/artifacts.d.ts.map +1 -0
- package/dist/commands/artifacts.js +143 -0
- package/dist/commands/backup.d.ts +1 -1
- package/dist/commands/backup.d.ts.map +1 -1
- package/dist/commands/backup.js +5 -2
- package/dist/commands/browse.d.ts.map +1 -1
- package/dist/commands/browse.js +310 -7
- package/dist/commands/checkpoint.d.ts +12 -0
- package/dist/commands/checkpoint.d.ts.map +1 -0
- package/dist/commands/checkpoint.js +162 -0
- package/dist/commands/context.d.ts +2 -2
- package/dist/commands/context.d.ts.map +1 -1
- package/dist/commands/context.js +3 -151
- package/dist/commands/decision.d.ts.map +1 -1
- package/dist/commands/decision.js +31 -7
- package/dist/commands/deinit.d.ts +2 -2
- package/dist/commands/deinit.js +15 -15
- package/dist/commands/doctor.js +23 -23
- package/dist/commands/governor.d.ts +4 -0
- package/dist/commands/governor.d.ts.map +1 -0
- package/dist/commands/{supervisor.js → governor.js} +133 -108
- package/dist/commands/grep.d.ts +1 -1
- package/dist/commands/grep.d.ts.map +1 -1
- package/dist/commands/grep.js +19 -2
- package/dist/commands/init.d.ts +12 -12
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +44 -30
- package/dist/commands/{session.d.ts → journal.d.ts} +2 -2
- package/dist/commands/journal.d.ts.map +1 -0
- package/dist/commands/{scratch.js → journal.js} +47 -47
- package/dist/commands/policy.js +1 -1
- package/dist/commands/presence.js +2 -2
- package/dist/commands/sync.d.ts +1 -1
- package/dist/commands/sync.js +3 -3
- package/dist/commands/tunnel.d.ts +16 -0
- package/dist/commands/tunnel.d.ts.map +1 -1
- package/dist/commands/tunnel.js +213 -27
- package/dist/commands/web-fetch.js +1 -1
- package/dist/commands/web.d.ts +19 -0
- package/dist/commands/web.d.ts.map +1 -1
- package/dist/commands/web.js +51 -0
- package/dist/commands/work.d.ts.map +1 -1
- package/dist/commands/work.js +38 -22
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +35 -28
- package/dist/core/{harnesses → adapters}/attest-projection.d.ts +2 -2
- package/dist/core/adapters/attest-projection.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.d.ts +16 -16
- package/dist/core/adapters/attest.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attest.js +9 -9
- package/dist/core/{harnesses → adapters}/attestation.d.ts +16 -16
- package/dist/core/adapters/attestation.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/attestation.js +20 -20
- package/dist/core/{harnesses → adapters}/bench.d.ts +12 -12
- package/dist/core/adapters/bench.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/bench.js +12 -12
- package/dist/core/adapters/index.d.ts +13 -0
- package/dist/core/adapters/index.d.ts.map +1 -0
- package/dist/core/adapters/index.js +6 -0
- package/dist/core/{harnesses → adapters}/profiles.d.ts +11 -11
- package/dist/core/adapters/profiles.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/profiles.js +11 -11
- package/dist/core/adapters/registry.d.ts +15 -0
- package/dist/core/adapters/registry.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/registry.js +11 -11
- package/dist/core/{harnesses → adapters}/types.d.ts +23 -23
- package/dist/core/adapters/types.d.ts.map +1 -0
- package/dist/core/{harnesses → adapters}/types.js +1 -1
- package/dist/core/agents/canonical-emit.d.ts +9 -14
- package/dist/core/agents/canonical-emit.d.ts.map +1 -1
- package/dist/core/agents/canonical-emit.js +15 -44
- package/dist/core/agents/cli-emit.js +1 -1
- package/dist/core/agents/cli.js +30 -26
- package/dist/core/agents/codex-replay.d.ts +1 -1
- package/dist/core/agents/codex-replay.js +6 -6
- package/dist/core/agents/coord-bin.d.ts +33 -0
- package/dist/core/agents/coord-bin.d.ts.map +1 -0
- package/dist/core/agents/coord-bin.js +89 -0
- package/dist/core/agents/coord-client.d.ts +78 -8
- package/dist/core/agents/coord-client.d.ts.map +1 -1
- package/dist/core/agents/coord-client.js +303 -75
- package/dist/core/agents/events/consume.d.ts +1 -1
- package/dist/core/agents/events/emit.d.ts +5 -6
- package/dist/core/agents/events/emit.d.ts.map +1 -1
- package/dist/core/agents/events/emit.js +2 -2
- package/dist/core/agents/paths.d.ts +5 -2
- package/dist/core/agents/paths.d.ts.map +1 -1
- package/dist/core/agents/paths.js +7 -13
- package/dist/core/agents/render/prompt-context.d.ts +21 -9
- package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
- package/dist/core/agents/render/prompt-context.js +82 -30
- package/dist/core/agents/render/session-context.d.ts +1 -1
- package/dist/core/agents/render/session-context.js +5 -5
- package/dist/core/agents/rules/claim-conflict.d.ts +2 -6
- package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
- package/dist/core/agents/rules/claim-conflict.js +1 -1
- package/dist/core/agents/rules/commit-conflict.js +98 -22
- package/dist/core/agents/rules/stop-hook.d.ts +9 -9
- package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
- package/dist/core/agents/rules/stop-hook.js +23 -5
- package/dist/core/agents/rules/verdict.d.ts +14 -0
- package/dist/core/agents/rules/verdict.d.ts.map +1 -0
- package/dist/core/agents/rules/verdict.js +1 -0
- package/dist/core/agents/session-events.js +3 -3
- package/dist/core/agents/state/council.d.ts +1 -1
- package/dist/core/agents/state/council.js +1 -1
- package/dist/core/agents/state/heartbeat-projector.d.ts +3 -2
- package/dist/core/agents/state/heartbeat-projector.d.ts.map +1 -1
- package/dist/core/agents/state/heartbeat-projector.js +14 -10
- package/dist/core/agents/state/heartbeat-writer.d.ts +1 -1
- package/dist/core/agents/state/heartbeat-writer.js +12 -12
- package/dist/core/agents/state/{scratch.d.ts → journal.d.ts} +7 -7
- package/dist/core/agents/state/{scratch.d.ts.map → journal.d.ts.map} +1 -1
- package/dist/core/agents/state/{scratch.js → journal.js} +12 -12
- package/dist/core/agents/state/pidmap.d.ts +28 -4
- package/dist/core/agents/state/pidmap.d.ts.map +1 -1
- package/dist/core/agents/state/pidmap.js +130 -15
- package/dist/core/agents/state/proc-start.d.ts +95 -0
- package/dist/core/agents/state/proc-start.d.ts.map +1 -0
- package/dist/core/agents/state/proc-start.js +199 -0
- package/dist/core/agents/state/shell-mutation.d.ts +1 -1
- package/dist/core/agents/state/shell-mutation.js +1 -1
- package/dist/core/agents/state/stale-sweep.js +7 -7
- package/dist/core/artifacts/index.d.ts +86 -0
- package/dist/core/artifacts/index.d.ts.map +1 -0
- package/dist/core/artifacts/index.js +421 -0
- package/dist/core/config.d.ts +9 -2
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +26 -2
- package/dist/core/context/index.d.ts +12 -12
- package/dist/core/context/index.js +10 -10
- package/dist/core/governor/adapter-spread.d.ts +52 -0
- package/dist/core/governor/adapter-spread.d.ts.map +1 -0
- package/dist/core/governor/adapter-spread.js +52 -0
- package/dist/core/governor/index.d.ts +7 -0
- package/dist/core/governor/index.d.ts.map +1 -0
- package/dist/core/governor/index.js +6 -0
- package/dist/core/governor/plan-api.d.ts +38 -0
- package/dist/core/governor/plan-api.d.ts.map +1 -0
- package/dist/core/governor/plan-api.js +83 -0
- package/dist/core/governor/plan-read.d.ts +5 -0
- package/dist/core/governor/plan-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-read.js +66 -52
- package/dist/core/{supervisor → governor}/plan-types.d.ts +57 -56
- package/dist/core/governor/plan-types.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/plan-types.js +4 -4
- package/dist/core/governor/planning.d.ts +48 -0
- package/dist/core/governor/planning.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/planning.js +125 -94
- package/dist/core/governor/read.d.ts +6 -0
- package/dist/core/governor/read.d.ts.map +1 -0
- package/dist/core/governor/read.js +4 -0
- package/dist/core/governor/runner.d.ts +37 -0
- package/dist/core/governor/runner.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/runner.js +15 -15
- package/dist/core/governor/service-read.d.ts +6 -0
- package/dist/core/governor/service-read.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service-read.js +12 -12
- package/dist/core/governor/service.d.ts +114 -0
- package/dist/core/governor/service.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/service.js +57 -57
- package/dist/core/governor/state.d.ts +116 -0
- package/dist/core/governor/state.d.ts.map +1 -0
- package/dist/core/{supervisor → governor}/state.js +228 -108
- package/dist/core/hooks/adapter/detect.d.ts +9 -0
- package/dist/core/hooks/{harness → adapter}/detect.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/detect.js +8 -8
- package/dist/core/hooks/{harness → adapter}/events.d.ts +15 -14
- package/dist/core/hooks/adapter/events.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/events.js +5 -5
- package/dist/core/hooks/{harness → adapter}/output.d.ts +20 -14
- package/dist/core/hooks/adapter/output.d.ts.map +1 -0
- package/dist/core/hooks/{harness → adapter}/output.js +30 -22
- package/dist/core/hooks/{harness → adapter}/parse.d.ts +5 -5
- package/dist/core/hooks/{harness → adapter}/parse.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/parse.js +4 -4
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts +15 -15
- package/dist/core/hooks/{harness → adapter}/wiring.d.ts.map +1 -1
- package/dist/core/hooks/{harness → adapter}/wiring.js +13 -13
- package/dist/core/hooks/cli.d.ts +3 -3
- package/dist/core/hooks/cli.js +187 -162
- package/dist/core/hooks/effects/image-capture.d.ts +5 -5
- package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
- package/dist/core/hooks/effects/image-capture.js +3 -3
- package/dist/core/hooks/effects/index.d.ts +12 -12
- package/dist/core/hooks/effects/index.d.ts.map +1 -1
- package/dist/core/hooks/effects/index.js +19 -19
- package/dist/core/hooks/events/emit.d.ts +2 -2
- package/dist/core/hooks/events/emit.d.ts.map +1 -1
- package/dist/core/hooks/events/emit.js +1 -1
- package/dist/core/hooks/events/rotate.js +1 -1
- package/dist/core/hooks/events/schema.d.ts +13 -5
- package/dist/core/hooks/events/schema.d.ts.map +1 -1
- package/dist/core/hooks/guard-path.d.ts +2 -2
- package/dist/core/hooks/guard-path.js +2 -2
- package/dist/core/hooks/index.d.ts +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.d.ts +14 -5
- package/dist/core/hooks/resolve/anchor.d.ts.map +1 -1
- package/dist/core/hooks/resolve/anchor.js +64 -7
- package/dist/core/hooks/resolve/coord-root.d.ts +16 -11
- package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
- package/dist/core/hooks/resolve/coord-root.js +18 -43
- package/dist/core/hooks/resolve/intent.js +1 -1
- package/dist/core/hooks/resolve/owner.d.ts +1 -1
- package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
- package/dist/core/hooks/resolve/owner.js +11 -5
- package/dist/core/{scratch → journal}/index.d.ts +25 -25
- package/dist/core/{scratch → journal}/index.d.ts.map +1 -1
- package/dist/core/{scratch → journal}/index.js +38 -38
- package/dist/core/policy/evaluate.d.ts +1 -1
- package/dist/core/policy/evaluate.d.ts.map +1 -1
- package/dist/core/policy/evaluate.js +7 -7
- package/dist/core/policy/types.d.ts +3 -3
- package/dist/core/policy/types.d.ts.map +1 -1
- package/dist/core/work/state.d.ts +12 -4
- package/dist/core/work/state.d.ts.map +1 -1
- package/dist/core/work/state.js +50 -17
- package/dist/core/workflow/adapters.d.ts +17 -0
- package/dist/core/workflow/adapters.d.ts.map +1 -0
- package/dist/core/workflow/adapters.js +21 -0
- package/dist/core/workflow/approvals.js +6 -6
- package/dist/core/workflow/billing.d.ts +9 -9
- package/dist/core/workflow/billing.js +9 -9
- package/dist/core/workflow/child-env.d.ts +10 -2
- package/dist/core/workflow/child-env.d.ts.map +1 -1
- package/dist/core/workflow/child-env.js +12 -4
- package/dist/core/workflow/engine.d.ts +15 -5
- package/dist/core/workflow/engine.d.ts.map +1 -1
- package/dist/core/workflow/engine.js +138 -83
- package/dist/core/workflow/evidence-preflight.d.ts +24 -0
- package/dist/core/workflow/evidence-preflight.d.ts.map +1 -0
- package/dist/core/workflow/evidence-preflight.js +134 -0
- package/dist/core/workflow/index.d.ts +1 -1
- package/dist/core/workflow/index.d.ts.map +1 -1
- package/dist/core/workflow/proof.d.ts +11 -5
- package/dist/core/workflow/proof.d.ts.map +1 -1
- package/dist/core/workflow/proof.js +45 -36
- package/dist/core/workflow/run-state.d.ts +1 -1
- package/dist/core/workflow/run-state.js +7 -7
- package/dist/core/workflow/sandbox-projection.d.ts +6 -6
- package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
- package/dist/core/workflow/sandbox-projection.js +11 -11
- package/dist/core/workflow/spawn-claude.d.ts +3 -3
- package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
- package/dist/core/workflow/spawn-claude.js +9 -6
- package/dist/core/workflow/spawn-codex.d.ts +4 -4
- package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
- package/dist/core/workflow/spawn-codex.js +9 -6
- package/dist/core/workflow/spawn-cursor.d.ts +4 -4
- package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
- package/dist/core/workflow/spawn-cursor.js +9 -6
- package/dist/core/workflow/spawn-failure.d.ts +1 -1
- package/dist/core/workflow/spawn-failure.js +1 -1
- package/dist/core/workflow/specialists.js +2 -2
- package/dist/core/workflow/{journal.d.ts → transcript.d.ts} +8 -8
- package/dist/core/workflow/transcript.d.ts.map +1 -0
- package/dist/core/workflow/{journal.js → transcript.js} +14 -14
- package/dist/core/workflow/types.d.ts +98 -51
- package/dist/core/workflow/types.d.ts.map +1 -1
- package/dist/core/workflow/types.js +11 -1
- package/dist/core/workflow/validate.d.ts +1 -1
- package/dist/core/workflow/validate.js +1 -1
- package/dist/core/workflow/workspaces/cancellation.js +2 -2
- package/dist/core/workflow/workspaces/cleanup.js +2 -2
- package/dist/core/workflow/workspaces/execution.js +6 -6
- package/dist/core/workflow/workspaces/inspect.js +9 -9
- package/dist/core/workflow/workspaces/integration.js +14 -14
- package/dist/core/workflow/workspaces/lifecycle.d.ts +1 -1
- package/dist/core/workflow/workspaces/lifecycle.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/lifecycle.js +9 -9
- package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/local-git.js +39 -5
- package/dist/core/workflow/workspaces/recovery.js +3 -3
- package/dist/core/workflow/workspaces/state.d.ts +1 -1
- package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
- package/dist/core/workflow/workspaces/state.js +3 -3
- package/dist/core/workflow/workspaces/types.d.ts +1 -1
- package/dist/core/workflow/workspaces/types.d.ts.map +1 -1
- package/dist/lib/browser/asserts.d.ts +28 -0
- package/dist/lib/browser/asserts.d.ts.map +1 -0
- package/dist/lib/browser/asserts.js +152 -0
- package/dist/lib/browser/client.d.ts +49 -0
- package/dist/lib/browser/client.d.ts.map +1 -1
- package/dist/lib/browser/client.js +155 -14
- package/dist/lib/browser/content-checks.d.ts +108 -0
- package/dist/lib/browser/content-checks.d.ts.map +1 -0
- package/dist/lib/browser/content-checks.js +474 -0
- package/dist/lib/browser/critique.d.ts +91 -0
- package/dist/lib/browser/critique.d.ts.map +1 -0
- package/dist/lib/browser/critique.js +167 -0
- package/dist/lib/browser/geometry.d.ts +32 -0
- package/dist/lib/browser/geometry.d.ts.map +1 -1
- package/dist/lib/browser/geometry.js +244 -1
- package/dist/lib/browser/index.d.ts +4 -1
- package/dist/lib/browser/index.d.ts.map +1 -1
- package/dist/lib/browser/index.js +2 -0
- package/dist/lib/claude-desktop.d.ts.map +1 -1
- package/dist/lib/claude-desktop.js +4 -1
- package/dist/lib/context/index.js +9 -2
- package/dist/lib/council/index.d.ts +6 -6
- package/dist/lib/council/index.d.ts.map +1 -1
- package/dist/lib/council/index.js +8 -8
- package/dist/lib/identities/assume.d.ts +2 -2
- package/dist/lib/identities/assume.js +7 -7
- package/dist/lib/instructions/apply.d.ts +3 -3
- package/dist/lib/instructions/apply.d.ts.map +1 -1
- package/dist/lib/instructions/apply.js +75 -27
- package/dist/lib/instructions/host-addendum.d.ts +54 -0
- package/dist/lib/instructions/host-addendum.d.ts.map +1 -0
- package/dist/lib/instructions/host-addendum.js +107 -0
- package/dist/lib/instructions/templates.d.ts +10 -3
- package/dist/lib/instructions/templates.d.ts.map +1 -1
- package/dist/lib/instructions/templates.js +41 -12
- package/dist/lib/machine.d.ts +2 -2
- package/dist/lib/machine.js +2 -2
- package/package.json +26 -21
- package/schemas/config.schema.json +26 -1
- package/src/commander.ts +22 -13
- package/src/commands/{harness.ts → adapter.ts} +46 -46
- package/src/commands/agents.ts +200 -78
- package/src/commands/artifacts.ts +168 -0
- package/src/commands/backup.ts +47 -33
- package/src/commands/browse.ts +438 -2
- package/src/commands/checkpoint.ts +196 -0
- package/src/commands/context.ts +3 -176
- package/src/commands/decision.ts +41 -7
- package/src/commands/deinit.ts +16 -16
- package/src/commands/doctor.ts +28 -28
- package/src/commands/{supervisor.ts → governor.ts} +184 -154
- package/src/commands/grep.ts +19 -2
- package/src/commands/init.ts +50 -34
- package/src/commands/{scratch.ts → journal.ts} +60 -60
- package/src/commands/policy.ts +1 -1
- package/src/commands/presence.ts +2 -2
- package/src/commands/sync.ts +3 -3
- package/src/commands/tunnel.ts +256 -38
- package/src/commands/web-fetch.ts +1 -1
- package/src/commands/web.ts +56 -1
- package/src/commands/work.ts +50 -35
- package/src/commands/workflow.ts +43 -34
- package/src/core/{harnesses → adapters}/attest-projection.ts +2 -2
- package/src/core/{harnesses → adapters}/attest.ts +27 -27
- package/src/core/{harnesses → adapters}/attestation.ts +41 -41
- package/src/core/{harnesses → adapters}/bench.ts +34 -43
- package/src/core/adapters/index.ts +56 -0
- package/src/core/{harnesses → adapters}/profiles.ts +16 -16
- package/src/core/{harnesses → adapters}/registry.ts +23 -23
- package/src/core/{harnesses → adapters}/types.ts +23 -23
- package/src/core/agents/canonical-emit.ts +16 -43
- package/src/core/agents/cli-emit.ts +1 -1
- package/src/core/agents/cli.ts +30 -28
- package/src/core/agents/codex-replay.ts +6 -6
- package/src/core/agents/coord-bin.ts +92 -0
- package/src/core/agents/coord-client.ts +302 -78
- package/src/core/agents/events/consume.ts +1 -1
- package/src/core/agents/events/emit.ts +7 -6
- package/src/core/agents/paths.ts +7 -11
- package/src/core/agents/render/prompt-context.ts +107 -31
- package/src/core/agents/render/session-context.ts +6 -6
- package/src/core/agents/rules/claim-conflict.ts +4 -7
- package/src/core/agents/rules/commit-conflict.ts +103 -22
- package/src/core/agents/rules/stop-hook.ts +33 -17
- package/src/core/agents/rules/verdict.ts +13 -0
- package/src/core/agents/session-events.ts +4 -4
- package/src/core/agents/state/council.ts +1 -1
- package/src/core/agents/state/heartbeat-projector.ts +16 -12
- package/src/core/agents/state/heartbeat-writer.ts +12 -12
- package/src/core/agents/state/{scratch.ts → journal.ts} +12 -12
- package/src/core/agents/state/pidmap.ts +130 -15
- package/src/core/agents/state/proc-start.ts +208 -0
- package/src/core/agents/state/shell-mutation.ts +1 -1
- package/src/core/agents/state/stale-sweep.ts +7 -7
- package/src/core/artifacts/index.ts +557 -0
- package/src/core/config.ts +30 -2
- package/src/core/context/index.ts +15 -15
- package/src/core/governor/adapter-spread.ts +82 -0
- package/src/core/governor/index.ts +91 -0
- package/src/core/governor/plan-api.ts +115 -0
- package/src/core/{supervisor → governor}/plan-read.ts +112 -97
- package/src/core/{supervisor → governor}/plan-types.ts +59 -56
- package/src/core/{supervisor → governor}/planning.ts +223 -192
- package/src/core/governor/read.ts +59 -0
- package/src/core/{supervisor → governor}/runner.ts +39 -39
- package/src/core/{supervisor → governor}/service-read.ts +22 -22
- package/src/core/{supervisor → governor}/service.ts +117 -119
- package/src/core/{supervisor → governor}/state.ts +325 -167
- package/src/core/hooks/adapter/detect.ts +30 -0
- package/src/core/hooks/{harness → adapter}/events.ts +16 -14
- package/src/core/hooks/{harness → adapter}/output.ts +31 -23
- package/src/core/hooks/{harness → adapter}/parse.ts +5 -5
- package/src/core/hooks/{harness → adapter}/wiring.ts +21 -21
- package/src/core/hooks/cli.ts +197 -173
- package/src/core/hooks/effects/image-capture.ts +6 -6
- package/src/core/hooks/effects/index.ts +19 -19
- package/src/core/hooks/events/emit.ts +3 -3
- package/src/core/hooks/events/rotate.ts +1 -1
- package/src/core/hooks/events/schema.ts +15 -7
- package/src/core/hooks/guard-path.ts +2 -2
- package/src/core/hooks/index.ts +1 -1
- package/src/core/hooks/resolve/anchor.ts +63 -8
- package/src/core/hooks/resolve/coord-root.ts +18 -40
- package/src/core/hooks/resolve/intent.ts +1 -1
- package/src/core/hooks/resolve/owner.ts +11 -5
- package/src/core/{scratch → journal}/index.ts +53 -53
- package/src/core/policy/evaluate.ts +8 -8
- package/src/core/policy/types.ts +3 -3
- package/src/core/work/state.ts +65 -23
- package/src/core/workflow/adapters.ts +33 -0
- package/src/core/workflow/approvals.ts +7 -7
- package/src/core/workflow/billing.ts +12 -12
- package/src/core/workflow/child-env.ts +13 -4
- package/src/core/workflow/engine.ts +155 -90
- package/src/core/workflow/evidence-preflight.ts +165 -0
- package/src/core/workflow/index.ts +3 -3
- package/src/core/workflow/proof.ts +60 -50
- package/src/core/workflow/run-state.ts +7 -7
- package/src/core/workflow/sandbox-projection.ts +16 -16
- package/src/core/workflow/spawn-claude.ts +13 -10
- package/src/core/workflow/spawn-codex.ts +13 -10
- package/src/core/workflow/spawn-cursor.ts +13 -10
- package/src/core/workflow/spawn-failure.ts +1 -1
- package/src/core/workflow/specialists.ts +2 -2
- package/src/core/workflow/{journal.ts → transcript.ts} +16 -16
- package/src/core/workflow/types.ts +108 -51
- package/src/core/workflow/validate.ts +1 -1
- package/src/core/workflow/workspaces/cancellation.ts +2 -2
- package/src/core/workflow/workspaces/cleanup.ts +2 -2
- package/src/core/workflow/workspaces/execution.ts +6 -6
- package/src/core/workflow/workspaces/inspect.ts +14 -11
- package/src/core/workflow/workspaces/integration.ts +18 -14
- package/src/core/workflow/workspaces/lifecycle.ts +10 -10
- package/src/core/workflow/workspaces/local-git.ts +47 -5
- package/src/core/workflow/workspaces/recovery.ts +3 -3
- package/src/core/workflow/workspaces/state.ts +4 -3
- package/src/core/workflow/workspaces/types.ts +1 -1
- package/src/lib/browser/asserts.ts +177 -0
- package/src/lib/browser/client.ts +189 -14
- package/src/lib/browser/content-checks.ts +571 -0
- package/src/lib/browser/critique.ts +231 -0
- package/src/lib/browser/geometry.ts +297 -1
- package/src/lib/browser/index.ts +34 -0
- package/src/lib/claude-desktop.ts +4 -1
- package/src/lib/context/index.ts +11 -1
- package/src/lib/council/index.ts +9 -9
- package/src/lib/identities/assume.ts +7 -7
- package/src/lib/instructions/apply.ts +87 -25
- package/src/lib/instructions/host-addendum.ts +126 -0
- package/src/lib/instructions/templates.ts +44 -15
- package/src/lib/machine.ts +2 -2
- package/dist/commands/harness.d.ts +0 -12
- package/dist/commands/harness.d.ts.map +0 -1
- package/dist/commands/scratch.d.ts +0 -4
- package/dist/commands/scratch.d.ts.map +0 -1
- package/dist/commands/session.d.ts.map +0 -1
- package/dist/commands/session.js +0 -162
- package/dist/commands/supervisor.d.ts +0 -4
- package/dist/commands/supervisor.d.ts.map +0 -1
- package/dist/core/harnesses/attest-projection.d.ts.map +0 -1
- package/dist/core/harnesses/attest.d.ts.map +0 -1
- package/dist/core/harnesses/attestation.d.ts.map +0 -1
- package/dist/core/harnesses/bench.d.ts.map +0 -1
- package/dist/core/harnesses/index.d.ts +0 -13
- package/dist/core/harnesses/index.d.ts.map +0 -1
- package/dist/core/harnesses/index.js +0 -6
- package/dist/core/harnesses/profiles.d.ts.map +0 -1
- package/dist/core/harnesses/registry.d.ts +0 -15
- package/dist/core/harnesses/registry.d.ts.map +0 -1
- package/dist/core/harnesses/types.d.ts.map +0 -1
- package/dist/core/hooks/harness/detect.d.ts +0 -9
- package/dist/core/hooks/harness/events.d.ts.map +0 -1
- package/dist/core/hooks/harness/output.d.ts.map +0 -1
- package/dist/core/supervisor/index.d.ts +0 -7
- package/dist/core/supervisor/index.d.ts.map +0 -1
- package/dist/core/supervisor/index.js +0 -6
- package/dist/core/supervisor/plan-api.d.ts +0 -23
- package/dist/core/supervisor/plan-api.d.ts.map +0 -1
- package/dist/core/supervisor/plan-api.js +0 -50
- package/dist/core/supervisor/plan-read.d.ts +0 -5
- package/dist/core/supervisor/plan-read.d.ts.map +0 -1
- package/dist/core/supervisor/plan-types.d.ts.map +0 -1
- package/dist/core/supervisor/planning.d.ts +0 -33
- package/dist/core/supervisor/planning.d.ts.map +0 -1
- package/dist/core/supervisor/read.d.ts +0 -6
- package/dist/core/supervisor/read.d.ts.map +0 -1
- package/dist/core/supervisor/read.js +0 -4
- package/dist/core/supervisor/runner.d.ts +0 -37
- package/dist/core/supervisor/runner.d.ts.map +0 -1
- package/dist/core/supervisor/service-read.d.ts +0 -6
- package/dist/core/supervisor/service-read.d.ts.map +0 -1
- package/dist/core/supervisor/service.d.ts +0 -114
- package/dist/core/supervisor/service.d.ts.map +0 -1
- package/dist/core/supervisor/state.d.ts +0 -95
- package/dist/core/supervisor/state.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.d.ts +0 -17
- package/dist/core/workflow/harnesses.d.ts.map +0 -1
- package/dist/core/workflow/harnesses.js +0 -21
- package/dist/core/workflow/journal.d.ts.map +0 -1
- package/src/commands/session.ts +0 -187
- package/src/core/harnesses/index.ts +0 -56
- package/src/core/hooks/harness/detect.ts +0 -30
- package/src/core/supervisor/index.ts +0 -89
- package/src/core/supervisor/plan-api.ts +0 -73
- package/src/core/supervisor/read.ts +0 -59
- package/src/core/workflow/harnesses.ts +0 -33
- /package/dist/core/{harnesses → adapters}/attest-projection.js +0 -0
|
@@ -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,15 +170,25 @@ export function readSupervisorPlanReviewReceipt(
|
|
|
169
170
|
|
|
170
171
|
function deriveStatus(
|
|
171
172
|
coordRoot: string,
|
|
172
|
-
events:
|
|
173
|
-
proposal:
|
|
173
|
+
events: GovernorPlanEvent[],
|
|
174
|
+
proposal: GovernorPlanProposal | undefined,
|
|
174
175
|
): Pick<
|
|
175
|
-
|
|
176
|
+
GovernorPlanRecord,
|
|
176
177
|
"status" | "approval_id" | "root_work_id" | "work_ids" | "reason" | "class"
|
|
177
178
|
> {
|
|
178
179
|
const latest = events.at(-1);
|
|
179
180
|
const completed = [...events].reverse().find((event) => event.event === "plan.completed");
|
|
180
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
|
+
}
|
|
181
192
|
return { status: "completed", work_ids: [], reason: completed.reason };
|
|
182
193
|
}
|
|
183
194
|
const applied = [...events].reverse().find((event) => event.event === "plan.applied");
|
|
@@ -220,22 +231,21 @@ function deriveStatus(
|
|
|
220
231
|
return { status: "interrupted", work_ids: [], reason: latest?.reason };
|
|
221
232
|
}
|
|
222
233
|
|
|
223
|
-
function readEvents(path: string, planId: string):
|
|
234
|
+
function readEvents(path: string, planId: string): GovernorPlanEvent[] {
|
|
224
235
|
if (!existsSync(path)) return [];
|
|
225
236
|
const size = statSync(path).size;
|
|
226
|
-
if (size > MAX_EVENTS_BYTES) throw new Error("
|
|
237
|
+
if (size > MAX_EVENTS_BYTES) throw new Error("governor plan events exceed their byte limit");
|
|
227
238
|
const body = readFileSync(path, "utf8");
|
|
228
|
-
if (body && !body.endsWith("\n"))
|
|
229
|
-
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`);
|
|
230
240
|
const lines = body.split("\n").filter(Boolean);
|
|
231
|
-
if (lines.length > MAX_EVENTS) throw new Error(`
|
|
241
|
+
if (lines.length > MAX_EVENTS) throw new Error(`governor plan exceeds ${MAX_EVENTS} events`);
|
|
232
242
|
return lines.map((line, index) => {
|
|
233
|
-
let event:
|
|
243
|
+
let event: GovernorPlanEvent;
|
|
234
244
|
try {
|
|
235
|
-
event = JSON.parse(line) as
|
|
245
|
+
event = JSON.parse(line) as GovernorPlanEvent;
|
|
236
246
|
} catch (error) {
|
|
237
247
|
throw new Error(
|
|
238
|
-
`cannot parse
|
|
248
|
+
`cannot parse governor plan ${planId} event ${index + 1}: ${(error as Error).message}`,
|
|
239
249
|
);
|
|
240
250
|
}
|
|
241
251
|
validateEvent(event, planId, index + 1);
|
|
@@ -243,9 +253,9 @@ function readEvents(path: string, planId: string): SupervisorPlanEvent[] {
|
|
|
243
253
|
});
|
|
244
254
|
}
|
|
245
255
|
|
|
246
|
-
function validateRequest(request:
|
|
256
|
+
function validateRequest(request: GovernorPlanRequest, goalId: string, planId: string): void {
|
|
247
257
|
if (
|
|
248
|
-
request.schema_version !==
|
|
258
|
+
request.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
249
259
|
request.id !== planId ||
|
|
250
260
|
request.goal_id !== goalId ||
|
|
251
261
|
!Number.isSafeInteger(request.sequence) ||
|
|
@@ -260,13 +270,13 @@ function validateRequest(request: SupervisorPlanRequest, goalId: string, planId:
|
|
|
260
270
|
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(request.workflow_run_id) ||
|
|
261
271
|
!validTimestamp(request.created_at)
|
|
262
272
|
) {
|
|
263
|
-
throw new Error(`
|
|
273
|
+
throw new Error(`governor plan request ${planId} has an unsupported schema`);
|
|
264
274
|
}
|
|
265
275
|
}
|
|
266
276
|
|
|
267
|
-
function validateProposalEnvelope(proposal:
|
|
277
|
+
function validateProposalEnvelope(proposal: GovernorPlanProposal, planId: string): void {
|
|
268
278
|
if (
|
|
269
|
-
proposal.schema_version !==
|
|
279
|
+
proposal.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
270
280
|
proposal.plan_id !== planId ||
|
|
271
281
|
!["apply", "complete", "attention"].includes(proposal.decision) ||
|
|
272
282
|
typeof proposal.rationale !== "string" ||
|
|
@@ -278,7 +288,7 @@ function validateProposalEnvelope(proposal: SupervisorPlanProposal, planId: stri
|
|
|
278
288
|
proposal.root.length > 32 ||
|
|
279
289
|
!validTimestamp(proposal.proposed_at)
|
|
280
290
|
) {
|
|
281
|
-
throw new Error(`
|
|
291
|
+
throw new Error(`governor plan proposal ${planId} has an unsupported schema`);
|
|
282
292
|
}
|
|
283
293
|
if (proposal.milestone !== undefined) {
|
|
284
294
|
const milestone = proposal.milestone;
|
|
@@ -300,14 +310,14 @@ function validateProposalEnvelope(proposal: SupervisorPlanProposal, planId: stri
|
|
|
300
310
|
typeof criterion !== "string" || criterion.length < 1 || criterion.length > 500,
|
|
301
311
|
)
|
|
302
312
|
) {
|
|
303
|
-
throw new Error(`
|
|
313
|
+
throw new Error(`governor plan proposal ${planId} milestone is invalid`);
|
|
304
314
|
}
|
|
305
315
|
}
|
|
306
316
|
if (
|
|
307
317
|
(proposal.decision === "attention" || proposal.decision === "complete") &&
|
|
308
318
|
(proposal.root !== "" || proposal.work.length > 0 || proposal.milestone !== undefined)
|
|
309
319
|
) {
|
|
310
|
-
throw new Error(`
|
|
320
|
+
throw new Error(`governor plan proposal ${planId} terminal decision contains work`);
|
|
311
321
|
}
|
|
312
322
|
for (const [index, spec] of proposal.work.entries()) {
|
|
313
323
|
if (
|
|
@@ -328,88 +338,88 @@ function validateProposalEnvelope(proposal: SupervisorPlanProposal, planId: stri
|
|
|
328
338
|
spec.dependencies.some((value) => typeof value !== "string" || value.length > 100) ||
|
|
329
339
|
!TEMPLATE_ID.test(spec.template)
|
|
330
340
|
) {
|
|
331
|
-
throw new Error(`
|
|
341
|
+
throw new Error(`governor plan proposal ${planId} work[${index}] is invalid`);
|
|
332
342
|
}
|
|
333
343
|
}
|
|
334
344
|
}
|
|
335
345
|
|
|
336
|
-
function validateReviewReceipt(receipt:
|
|
346
|
+
function validateReviewReceipt(receipt: GovernorPlanReviewReceipt, planId: string): void {
|
|
337
347
|
if (
|
|
338
348
|
!receipt ||
|
|
339
349
|
typeof receipt !== "object" ||
|
|
340
|
-
receipt.schema_version !==
|
|
350
|
+
receipt.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
341
351
|
receipt.plan_id !== planId ||
|
|
342
352
|
!["passed", "revision_exhausted", "attention", "failed"].includes(receipt.status) ||
|
|
343
353
|
!/^[a-f0-9]{64}$/.test(receipt.candidate_sha256) ||
|
|
344
354
|
!Array.isArray(receipt.rounds) ||
|
|
345
355
|
receipt.rounds.length < 1 ||
|
|
346
|
-
receipt.rounds.length >
|
|
356
|
+
receipt.rounds.length > MAX_GOVERNOR_PLAN_REVISION_ROUNDS + 1
|
|
347
357
|
) {
|
|
348
|
-
throw new Error(`
|
|
358
|
+
throw new Error(`governor plan review ${planId} has an unsupported schema`);
|
|
349
359
|
}
|
|
350
360
|
validateProposalEnvelope(receipt.final_candidate, planId);
|
|
351
361
|
if (receipt.candidate_sha256 !== candidateDigest(receipt.final_candidate)) {
|
|
352
|
-
throw new Error(`
|
|
362
|
+
throw new Error(`governor plan review ${planId} has invalid candidate digest`);
|
|
353
363
|
}
|
|
354
364
|
receipt.rounds.forEach((round, index) => {
|
|
355
365
|
validateReviewRound(round, planId, index + 1);
|
|
356
366
|
});
|
|
357
367
|
const finalRound = receipt.rounds.at(-1);
|
|
358
368
|
if (finalRound?.candidate_sha256 !== receipt.candidate_sha256) {
|
|
359
|
-
throw new Error(`
|
|
369
|
+
throw new Error(`governor plan review ${planId} final round does not match its candidate`);
|
|
360
370
|
}
|
|
361
371
|
if (receipt.status === "passed" && finalRound?.outcome !== "approved") {
|
|
362
|
-
throw new Error(`
|
|
372
|
+
throw new Error(`governor plan review ${planId} passed without approval`);
|
|
363
373
|
}
|
|
364
374
|
if (receipt.status === "attention" && finalRound?.outcome === "approved") {
|
|
365
|
-
throw new Error(`
|
|
375
|
+
throw new Error(`governor plan review ${planId} attention conflicts with approval`);
|
|
366
376
|
}
|
|
367
377
|
}
|
|
368
378
|
|
|
369
379
|
function readFrozenReviewPolicy(
|
|
370
380
|
coordRoot: string,
|
|
371
381
|
goalId: string,
|
|
372
|
-
):
|
|
373
|
-
const path = join(coordRoot, ".harnery", "
|
|
382
|
+
): GovernorReplanningPolicy["review"] | undefined {
|
|
383
|
+
const path = join(coordRoot, ".harnery", "governors", goalId, "intent.json");
|
|
374
384
|
if (!existsSync(path)) return undefined;
|
|
375
|
-
const intent = readJson<{ replanning?:
|
|
385
|
+
const intent = readJson<{ replanning?: GovernorReplanningPolicy }>(path, "governor intent");
|
|
376
386
|
return intent.replanning?.review;
|
|
377
387
|
}
|
|
378
388
|
|
|
379
389
|
function validateReviewReceiptMatchesPolicy(
|
|
380
|
-
receipt:
|
|
390
|
+
receipt: GovernorPlanReviewReceipt,
|
|
381
391
|
planId: string,
|
|
382
|
-
review: NonNullable<
|
|
392
|
+
review: NonNullable<GovernorReplanningPolicy["review"]>,
|
|
383
393
|
): void {
|
|
384
394
|
if (receipt.rounds.length > review.max_revision_rounds + 1) {
|
|
385
|
-
throw new Error(`
|
|
395
|
+
throw new Error(`governor plan review ${planId} exceeds the frozen review policy`);
|
|
386
396
|
}
|
|
387
397
|
for (const round of receipt.rounds) {
|
|
388
398
|
if (round.reviewers.length !== review.reviewer_specialists.length) {
|
|
389
|
-
throw new Error(`
|
|
399
|
+
throw new Error(`governor plan review ${planId} does not match the frozen review policy`);
|
|
390
400
|
}
|
|
391
401
|
round.reviewers.forEach((reviewer, index) => {
|
|
392
402
|
if (reviewer.specialist !== review.reviewer_specialists[index]) {
|
|
393
|
-
throw new Error(`
|
|
403
|
+
throw new Error(`governor plan review ${planId} does not match the frozen review policy`);
|
|
394
404
|
}
|
|
395
405
|
});
|
|
396
406
|
const outcome = aggregateReviewers(round.reviewers);
|
|
397
407
|
if (round.outcome !== outcome) {
|
|
398
|
-
throw new Error(`
|
|
408
|
+
throw new Error(`governor plan review ${planId} has an invalid reviewer outcome`);
|
|
399
409
|
}
|
|
400
410
|
}
|
|
401
411
|
const finalRound = receipt.rounds.at(-1)!;
|
|
402
412
|
if (receipt.status === "passed" && finalRound.outcome !== "approved") {
|
|
403
|
-
throw new Error(`
|
|
413
|
+
throw new Error(`governor plan review ${planId} passed without policy approval`);
|
|
404
414
|
}
|
|
405
415
|
if (receipt.status === "revision_exhausted" && finalRound.round <= review.max_revision_rounds) {
|
|
406
|
-
throw new Error(`
|
|
416
|
+
throw new Error(`governor plan review ${planId} exhausted before the frozen review limit`);
|
|
407
417
|
}
|
|
408
418
|
}
|
|
409
419
|
|
|
410
420
|
function aggregateReviewers(
|
|
411
|
-
reviewers: readonly
|
|
412
|
-
):
|
|
421
|
+
reviewers: readonly GovernorPlanReviewReviewer[],
|
|
422
|
+
): GovernorPlanReviewRound["outcome"] {
|
|
413
423
|
if (reviewers.length < 1) return "failed";
|
|
414
424
|
if (reviewers.some((reviewer) => reviewer.verdict === "attention")) return "attention";
|
|
415
425
|
if (
|
|
@@ -424,13 +434,13 @@ function aggregateReviewers(
|
|
|
424
434
|
return "approved";
|
|
425
435
|
}
|
|
426
436
|
|
|
427
|
-
function candidateDigest(candidate:
|
|
437
|
+
function candidateDigest(candidate: GovernorPlanProposal): string {
|
|
428
438
|
return createHash("sha256")
|
|
429
439
|
.update(JSON.stringify(canonicalCandidate(candidate)))
|
|
430
440
|
.digest("hex");
|
|
431
441
|
}
|
|
432
442
|
|
|
433
|
-
function canonicalCandidate(candidate:
|
|
443
|
+
function canonicalCandidate(candidate: GovernorPlanProposal): unknown {
|
|
434
444
|
return {
|
|
435
445
|
schema_version: candidate.schema_version,
|
|
436
446
|
plan_id: candidate.plan_id,
|
|
@@ -443,7 +453,7 @@ function canonicalCandidate(candidate: SupervisorPlanProposal): unknown {
|
|
|
443
453
|
}
|
|
444
454
|
|
|
445
455
|
function validateReviewRound(
|
|
446
|
-
round:
|
|
456
|
+
round: GovernorPlanReviewRound,
|
|
447
457
|
planId: string,
|
|
448
458
|
sequence: number,
|
|
449
459
|
): void {
|
|
@@ -454,12 +464,12 @@ function validateReviewRound(
|
|
|
454
464
|
!/^[a-f0-9]{64}$/.test(round.candidate_sha256) ||
|
|
455
465
|
!Array.isArray(round.reviewers) ||
|
|
456
466
|
round.reviewers.length < 1 ||
|
|
457
|
-
round.reviewers.length >
|
|
467
|
+
round.reviewers.length > MAX_GOVERNOR_PLAN_REVIEWERS ||
|
|
458
468
|
!["approved", "revise", "attention", "failed"].includes(round.outcome) ||
|
|
459
469
|
(round.revision_workflow_run_id !== undefined &&
|
|
460
470
|
!/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(round.revision_workflow_run_id))
|
|
461
471
|
) {
|
|
462
|
-
throw new Error(`
|
|
472
|
+
throw new Error(`governor plan review ${planId} round ${sequence} is invalid`);
|
|
463
473
|
}
|
|
464
474
|
round.reviewers.forEach((reviewer, index) => {
|
|
465
475
|
validateReviewReviewer(reviewer, planId, sequence, index);
|
|
@@ -467,7 +477,7 @@ function validateReviewRound(
|
|
|
467
477
|
}
|
|
468
478
|
|
|
469
479
|
function validateReviewReviewer(
|
|
470
|
-
reviewer:
|
|
480
|
+
reviewer: GovernorPlanReviewReviewer,
|
|
471
481
|
planId: string,
|
|
472
482
|
round: number,
|
|
473
483
|
index: number,
|
|
@@ -478,14 +488,14 @@ function validateReviewReviewer(
|
|
|
478
488
|
typeof reviewer.specialist !== "string" ||
|
|
479
489
|
reviewer.specialist.length < 1 ||
|
|
480
490
|
reviewer.specialist.length > 100 ||
|
|
481
|
-
!["approve", "revise", "attention"].includes(reviewer.verdict as
|
|
491
|
+
!["approve", "revise", "attention"].includes(reviewer.verdict as GovernorPlanReviewVerdict) ||
|
|
482
492
|
typeof reviewer.rationale !== "string" ||
|
|
483
493
|
reviewer.rationale.length < 1 ||
|
|
484
494
|
reviewer.rationale.length > 2_000 ||
|
|
485
495
|
!Array.isArray(reviewer.findings) ||
|
|
486
496
|
reviewer.findings.length > 50
|
|
487
497
|
) {
|
|
488
|
-
throw new Error(`
|
|
498
|
+
throw new Error(`governor plan review ${planId} round ${round} reviewer ${index} is invalid`);
|
|
489
499
|
}
|
|
490
500
|
reviewer.findings.forEach((finding, findingIndex) => {
|
|
491
501
|
validateReviewFinding(finding, planId, round, index, findingIndex);
|
|
@@ -493,7 +503,7 @@ function validateReviewReviewer(
|
|
|
493
503
|
}
|
|
494
504
|
|
|
495
505
|
function validateReviewFinding(
|
|
496
|
-
finding:
|
|
506
|
+
finding: GovernorPlanReviewFinding,
|
|
497
507
|
planId: string,
|
|
498
508
|
round: number,
|
|
499
509
|
reviewerIndex: number,
|
|
@@ -513,12 +523,12 @@ function validateReviewFinding(
|
|
|
513
523
|
finding.recommendation.length > 1_000
|
|
514
524
|
) {
|
|
515
525
|
throw new Error(
|
|
516
|
-
`
|
|
526
|
+
`governor plan review ${planId} round ${round} reviewer ${reviewerIndex} finding ${findingIndex} is invalid`,
|
|
517
527
|
);
|
|
518
528
|
}
|
|
519
529
|
}
|
|
520
530
|
|
|
521
|
-
function summarizeReview(receipt:
|
|
531
|
+
function summarizeReview(receipt: GovernorPlanReviewReceipt): GovernorPlanReviewSummary {
|
|
522
532
|
const findings = receipt.rounds.flatMap((round) =>
|
|
523
533
|
round.reviewers.flatMap((reviewer) => reviewer.findings),
|
|
524
534
|
);
|
|
@@ -531,9 +541,9 @@ function summarizeReview(receipt: SupervisorPlanReviewReceipt): SupervisorPlanRe
|
|
|
531
541
|
};
|
|
532
542
|
}
|
|
533
543
|
|
|
534
|
-
function validateEvent(event:
|
|
544
|
+
function validateEvent(event: GovernorPlanEvent, planId: string, sequence: number): void {
|
|
535
545
|
if (
|
|
536
|
-
event.schema_version !==
|
|
546
|
+
event.schema_version !== GOVERNOR_PLAN_SCHEMA_VERSION ||
|
|
537
547
|
event.plan_id !== planId ||
|
|
538
548
|
event.seq !== sequence ||
|
|
539
549
|
!EVENT_TYPES.has(event.event) ||
|
|
@@ -545,21 +555,26 @@ function validateEvent(event: SupervisorPlanEvent, planId: string, sequence: num
|
|
|
545
555
|
event.reason.length < 1 ||
|
|
546
556
|
event.reason.length > 2_000
|
|
547
557
|
) {
|
|
548
|
-
throw new Error(`
|
|
558
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an unsupported schema`);
|
|
549
559
|
}
|
|
550
560
|
if (event.approval_id !== undefined && !APPROVAL_ID.test(event.approval_id)) {
|
|
551
|
-
throw new Error(`
|
|
561
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an invalid approval id`);
|
|
552
562
|
}
|
|
553
563
|
if (event.root_work_id !== undefined && !WORK_ID.test(event.root_work_id)) {
|
|
554
|
-
throw new Error(`
|
|
564
|
+
throw new Error(`governor plan ${planId} event ${sequence} has an invalid root work id`);
|
|
555
565
|
}
|
|
556
566
|
if (event.work_ids !== undefined) {
|
|
557
567
|
if (!Array.isArray(event.work_ids) || event.work_ids.some((id) => !WORK_ID.test(id))) {
|
|
558
|
-
throw new Error(`
|
|
568
|
+
throw new Error(`governor plan ${planId} event ${sequence} has invalid work ids`);
|
|
559
569
|
}
|
|
560
570
|
}
|
|
561
|
-
if (
|
|
562
|
-
|
|
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`);
|
|
563
578
|
}
|
|
564
579
|
}
|
|
565
580
|
|
|
@@ -586,7 +601,7 @@ function readJson<T>(path: string, label: string): T {
|
|
|
586
601
|
}
|
|
587
602
|
|
|
588
603
|
function plansRoot(coordRoot: string, goalId: string): string {
|
|
589
|
-
return join(coordRoot, ".harnery", "
|
|
604
|
+
return join(coordRoot, ".harnery", "governors", goalId, "plans");
|
|
590
605
|
}
|
|
591
606
|
|
|
592
607
|
function planDir(coordRoot: string, goalId: string, planId: string): string {
|