@lannguyensi/harness 0.63.0 → 1.0.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/CHANGELOG.md +90 -0
- package/README.md +46 -42
- package/dist/cli/add/index.js +17 -21
- package/dist/cli/add/index.js.map +1 -1
- package/dist/cli/adopt/derive.d.ts +2 -2
- package/dist/cli/adopt/derive.js +2 -19
- package/dist/cli/adopt/derive.js.map +1 -1
- package/dist/cli/adopt/index.d.ts +1 -1
- package/dist/cli/adopt/index.js +1 -12
- package/dist/cli/adopt/index.js.map +1 -1
- package/dist/cli/apply/apply.d.ts +20 -35
- package/dist/cli/apply/apply.js +61 -136
- package/dist/cli/apply/apply.js.map +1 -1
- package/dist/cli/apply/generate-codex-config.js +10 -58
- package/dist/cli/apply/generate-codex-config.js.map +1 -1
- package/dist/cli/apply/generate-memory-index.js +1 -2
- package/dist/cli/apply/generate-memory-index.js.map +1 -1
- package/dist/cli/apply/generate-opencode-config.d.ts +2 -10
- package/dist/cli/apply/generate-opencode-config.js +74 -113
- package/dist/cli/apply/generate-opencode-config.js.map +1 -1
- package/dist/cli/apply/generate-settings.d.ts +11 -64
- package/dist/cli/apply/generate-settings.js +27 -132
- package/dist/cli/apply/generate-settings.js.map +1 -1
- package/dist/cli/apply/index.d.ts +1 -1
- package/dist/cli/apply/index.js +1 -1
- package/dist/cli/apply/index.js.map +1 -1
- package/dist/cli/apply/install-codex-config.d.ts +153 -1
- package/dist/cli/apply/install-codex-config.js +445 -70
- package/dist/cli/apply/install-codex-config.js.map +1 -1
- package/dist/cli/apply/next-steps.d.ts +7 -0
- package/dist/cli/apply/next-steps.js +13 -1
- package/dist/cli/apply/next-steps.js.map +1 -1
- package/dist/cli/bounded-stdin.d.ts +0 -23
- package/dist/cli/bounded-stdin.js +2 -49
- package/dist/cli/bounded-stdin.js.map +1 -1
- package/dist/cli/describe.d.ts +1 -1
- package/dist/cli/describe.js +0 -3
- package/dist/cli/describe.js.map +1 -1
- package/dist/cli/diff/engine.d.ts +0 -11
- package/dist/cli/diff/engine.js +1 -17
- package/dist/cli/diff/engine.js.map +1 -1
- package/dist/cli/diff/index.js +14 -25
- package/dist/cli/diff/index.js.map +1 -1
- package/dist/cli/doctor/claude-mcp.d.ts +4 -19
- package/dist/cli/doctor/claude-mcp.js +11 -22
- package/dist/cli/doctor/claude-mcp.js.map +1 -1
- package/dist/cli/doctor/codex.d.ts +12 -14
- package/dist/cli/doctor/codex.js +31 -144
- package/dist/cli/doctor/codex.js.map +1 -1
- package/dist/cli/doctor/format.js +23 -338
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/hook-liveness.d.ts +56 -0
- package/dist/cli/doctor/hook-liveness.js +455 -0
- package/dist/cli/doctor/hook-liveness.js.map +1 -0
- package/dist/cli/doctor/index.d.ts +13 -87
- package/dist/cli/doctor/index.js +57 -705
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/opencode.d.ts +2 -1
- package/dist/cli/doctor/opencode.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +21 -378
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/drain-stdio.d.ts +31 -0
- package/dist/cli/drain-stdio.js +76 -0
- package/dist/cli/drain-stdio.js.map +1 -0
- package/dist/cli/export.d.ts +3 -1
- package/dist/cli/export.js +7 -16
- package/dist/cli/export.js.map +1 -1
- package/dist/cli/gate/codex-disable.d.ts +29 -0
- package/dist/cli/gate/codex-disable.js +195 -0
- package/dist/cli/gate/codex-disable.js.map +1 -0
- package/dist/cli/gate/codex-enable.d.ts +41 -0
- package/dist/cli/gate/codex-enable.js +127 -0
- package/dist/cli/gate/codex-enable.js.map +1 -0
- package/dist/cli/gate/codex-snapshot.d.ts +208 -0
- package/dist/cli/gate/codex-snapshot.js +402 -0
- package/dist/cli/gate/codex-snapshot.js.map +1 -0
- package/dist/cli/gate/disable.d.ts +9 -0
- package/dist/cli/gate/disable.js +263 -28
- package/dist/cli/gate/disable.js.map +1 -1
- package/dist/cli/gate/enable.d.ts +26 -6
- package/dist/cli/gate/enable.js +152 -80
- package/dist/cli/gate/enable.js.map +1 -1
- package/dist/cli/gate/link-chain.d.ts +53 -0
- package/dist/cli/gate/link-chain.js +122 -0
- package/dist/cli/gate/link-chain.js.map +1 -0
- package/dist/cli/gate/snapshot.d.ts +289 -12
- package/dist/cli/gate/snapshot.js +481 -22
- package/dist/cli/gate/snapshot.js.map +1 -1
- package/dist/cli/index.d.ts +0 -9
- package/dist/cli/index.js +15 -2607
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/composer.d.ts +3 -6
- package/dist/cli/init/composer.js +6 -370
- package/dist/cli/init/composer.js.map +1 -1
- package/dist/cli/init/dependencies.d.ts +1 -2
- package/dist/cli/init/dependencies.js +4 -80
- package/dist/cli/init/dependencies.js.map +1 -1
- package/dist/cli/init/detect.js +5 -4
- package/dist/cli/init/detect.js.map +1 -1
- package/dist/cli/init/interactive.d.ts +1 -23
- package/dist/cli/init/interactive.js +33 -247
- package/dist/cli/init/interactive.js.map +1 -1
- package/dist/cli/init/profiles.d.ts +2 -2
- package/dist/cli/init/profiles.js +51 -243
- package/dist/cli/init/profiles.js.map +1 -1
- package/dist/cli/init/templates.d.ts +2 -37
- package/dist/cli/init/templates.js +25 -1237
- package/dist/cli/init/templates.js.map +1 -1
- package/dist/cli/list.d.ts +1 -1
- package/dist/cli/list.js +1 -38
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/loader.d.ts +15 -1
- package/dist/cli/loader.js +56 -39
- package/dist/cli/loader.js.map +1 -1
- package/dist/cli/main.js +7 -2
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/migrate-home/index.js +2 -2
- package/dist/cli/migrate-home/index.js.map +1 -1
- package/dist/cli/pack/add.js +1 -1
- package/dist/cli/pack/add.js.map +1 -1
- package/dist/cli/pack/hook-bootstrap.d.ts +5 -164
- package/dist/cli/pack/hook-bootstrap.js +15 -291
- package/dist/cli/pack/hook-bootstrap.js.map +1 -1
- package/dist/cli/pack/hook-branch-protection.d.ts +28 -21
- package/dist/cli/pack/hook-branch-protection.js +365 -340
- package/dist/cli/pack/hook-branch-protection.js.map +1 -1
- package/dist/cli/pack/index.d.ts +0 -1
- package/dist/cli/pack/index.js +0 -1
- package/dist/cli/pack/index.js.map +1 -1
- package/dist/cli/pack/list.js +1 -6
- package/dist/cli/pack/list.js.map +1 -1
- package/dist/cli/pack/mutate.d.ts +7 -9
- package/dist/cli/pack/mutate.js +6 -9
- package/dist/cli/pack/mutate.js.map +1 -1
- package/dist/cli/pack/reseed.d.ts +2 -2
- package/dist/cli/pack/reseed.js +16 -22
- package/dist/cli/pack/reseed.js.map +1 -1
- package/dist/cli/register-gate-group.d.ts +5 -0
- package/dist/cli/register-gate-group.js +348 -0
- package/dist/cli/register-gate-group.js.map +1 -0
- package/dist/cli/register-inspect-group.d.ts +6 -0
- package/dist/cli/register-inspect-group.js +189 -0
- package/dist/cli/register-inspect-group.js.map +1 -0
- package/dist/cli/register-operator-lifecycle.d.ts +5 -0
- package/dist/cli/register-operator-lifecycle.js +20 -0
- package/dist/cli/register-operator-lifecycle.js.map +1 -0
- package/dist/cli/register-pack-group.d.ts +5 -0
- package/dist/cli/register-pack-group.js +134 -0
- package/dist/cli/register-pack-group.js.map +1 -0
- package/dist/cli/register-setup-group.d.ts +5 -0
- package/dist/cli/register-setup-group.js +495 -0
- package/dist/cli/register-setup-group.js.map +1 -0
- package/dist/cli/remove/index.d.ts +0 -14
- package/dist/cli/remove/index.js +2 -115
- package/dist/cli/remove/index.js.map +1 -1
- package/dist/cli/remove/mutate.d.ts +0 -2
- package/dist/cli/remove/mutate.js +1 -19
- package/dist/cli/remove/mutate.js.map +1 -1
- package/dist/cli/remove/register.d.ts +5 -0
- package/dist/cli/remove/register.js +25 -0
- package/dist/cli/remove/register.js.map +1 -0
- package/dist/cli/shell-quote.d.ts +7 -0
- package/dist/cli/shell-quote.js +17 -0
- package/dist/cli/shell-quote.js.map +1 -0
- package/dist/cli/uninstall/index.d.ts +4 -2
- package/dist/cli/uninstall/index.js +15 -7
- package/dist/cli/uninstall/index.js.map +1 -1
- package/dist/cli/uninstall/register.d.ts +5 -0
- package/dist/cli/uninstall/register.js +171 -0
- package/dist/cli/uninstall/register.js.map +1 -0
- package/dist/cli/uninstall/snapshot.d.ts +15 -0
- package/dist/cli/uninstall/snapshot.js +38 -0
- package/dist/cli/uninstall/snapshot.js.map +1 -1
- package/dist/cli/validate/checks.d.ts +0 -77
- package/dist/cli/validate/checks.js +3 -1049
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/cli/validate/index.js +19 -15
- package/dist/cli/validate/index.js.map +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/io/claude-mcp.d.ts +1 -1
- package/dist/io/claude-mcp.js +27 -14
- package/dist/io/claude-mcp.js.map +1 -1
- package/dist/io/harness-lock.js +2 -2
- package/dist/io/harness-lock.js.map +1 -1
- package/dist/io/lock.d.ts +0 -26
- package/dist/io/lock.js +10 -27
- package/dist/io/lock.js.map +1 -1
- package/dist/io/merge-settings.js +6 -4
- package/dist/io/merge-settings.js.map +1 -1
- package/dist/io/project-name.d.ts +22 -39
- package/dist/io/project-name.js +25 -42
- package/dist/io/project-name.js.map +1 -1
- package/dist/io/read-regular-file.d.ts +103 -40
- package/dist/io/read-regular-file.js +196 -35
- package/dist/io/read-regular-file.js.map +1 -1
- package/dist/io/restart-hints.js +3 -6
- package/dist/io/restart-hints.js.map +1 -1
- package/dist/io/version-compare.d.ts +1 -3
- package/dist/io/version-compare.js +1 -3
- package/dist/io/version-compare.js.map +1 -1
- package/dist/io/write-regular-file.d.ts +30 -0
- package/dist/io/write-regular-file.js +85 -0
- package/dist/io/write-regular-file.js.map +1 -0
- package/dist/overrides/index.d.ts +1 -0
- package/dist/overrides/index.js +1 -0
- package/dist/overrides/index.js.map +1 -1
- package/dist/overrides/merge-layers.d.ts +43 -0
- package/dist/overrides/merge-layers.js +76 -0
- package/dist/overrides/merge-layers.js.map +1 -0
- package/dist/overrides/merge.d.ts +16 -0
- package/dist/overrides/merge.js +21 -8
- package/dist/overrides/merge.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -69
- package/dist/policy-packs/builtin/branch-protection-runtime.js +12 -84
- package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection.d.ts +7 -30
- package/dist/policy-packs/builtin/branch-protection.js +56 -89
- package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
- package/dist/policy-packs/config-check.d.ts +7 -5
- package/dist/policy-packs/config-check.js +2 -2
- package/dist/policy-packs/config-check.js.map +1 -1
- package/dist/policy-packs/expand.d.ts +1 -3
- package/dist/policy-packs/expand.js +5 -42
- package/dist/policy-packs/expand.js.map +1 -1
- package/dist/policy-packs/index.d.ts +3 -3
- package/dist/policy-packs/index.js +2 -2
- package/dist/policy-packs/index.js.map +1 -1
- package/dist/policy-packs/registry.d.ts +9 -38
- package/dist/policy-packs/registry.js +5 -65
- package/dist/policy-packs/registry.js.map +1 -1
- package/dist/policy-packs/runtime.d.ts +0 -4
- package/dist/policy-packs/runtime.js +9 -22
- package/dist/policy-packs/runtime.js.map +1 -1
- package/dist/policy-packs/types.d.ts +0 -19
- package/dist/policy-packs/ux-compare.d.ts +1 -11
- package/dist/policy-packs/ux-compare.js +6 -42
- package/dist/policy-packs/ux-compare.js.map +1 -1
- package/dist/policy-packs/ux-drift-check.d.ts +5 -5
- package/dist/policy-packs/ux-drift-check.js +17 -22
- package/dist/policy-packs/ux-drift-check.js.map +1 -1
- package/dist/policy-packs/version-check.d.ts +5 -26
- package/dist/policy-packs/version-check.js +19 -74
- package/dist/policy-packs/version-check.js.map +1 -1
- package/dist/probes/memory.d.ts +1 -1
- package/dist/probes/memory.js +1 -1
- package/dist/probes/memory.js.map +1 -1
- package/dist/runtime/agent-facing.d.ts +9 -0
- package/dist/runtime/agent-facing.js +28 -14
- package/dist/runtime/agent-facing.js.map +1 -1
- package/dist/runtime/bounded-text.d.ts +15 -0
- package/dist/runtime/bounded-text.js +27 -0
- package/dist/runtime/bounded-text.js.map +1 -0
- package/dist/runtime/git-branch.d.ts +125 -0
- package/dist/runtime/git-branch.js +381 -0
- package/dist/runtime/git-branch.js.map +1 -0
- package/dist/runtime/hermetic-spawn-guard.d.ts +2 -2
- package/dist/runtime/hermetic-spawn-guard.js +24 -34
- package/dist/runtime/hermetic-spawn-guard.js.map +1 -1
- package/dist/runtime/home-dir.js +3 -2
- package/dist/runtime/home-dir.js.map +1 -1
- package/dist/runtime/tool-name-aliases.d.ts +0 -6
- package/dist/runtime/tool-name-aliases.js +5 -18
- package/dist/runtime/tool-name-aliases.js.map +1 -1
- package/dist/schema/grounding.d.ts +7 -54
- package/dist/schema/grounding.js +10 -12
- package/dist/schema/grounding.js.map +1 -1
- package/dist/schema/hooks.d.ts +39 -136
- package/dist/schema/hooks.js +3 -6
- package/dist/schema/hooks.js.map +1 -1
- package/dist/schema/index.d.ts +114 -3828
- package/dist/schema/index.js +41 -80
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/memory.d.ts +54 -131
- package/dist/schema/memory.js +2 -2
- package/dist/schema/memory.js.map +1 -1
- package/dist/schema/policy-packs.d.ts +3 -45
- package/dist/schema/policy-packs.js +7 -13
- package/dist/schema/policy-packs.js.map +1 -1
- package/dist/schema/policy-ux.d.ts +7 -0
- package/dist/schema/policy-ux.js +18 -0
- package/dist/schema/policy-ux.js.map +1 -0
- package/dist/schema/removed-keys.d.ts +185 -0
- package/dist/schema/removed-keys.js +531 -0
- package/dist/schema/removed-keys.js.map +1 -0
- package/dist/schema/tools.d.ts +30 -268
- package/dist/schema/tools.js +4 -4
- package/dist/schema/tools.js.map +1 -1
- package/package.json +5 -16
- package/dist/cli/approve/branch-protection.d.ts +0 -69
- package/dist/cli/approve/branch-protection.js +0 -144
- package/dist/cli/approve/branch-protection.js.map +0 -1
- package/dist/cli/approve/risk.d.ts +0 -112
- package/dist/cli/approve/risk.js +0 -197
- package/dist/cli/approve/risk.js.map +0 -1
- package/dist/cli/approve/stdin-report.d.ts +0 -57
- package/dist/cli/approve/stdin-report.js +0 -145
- package/dist/cli/approve/stdin-report.js.map +0 -1
- package/dist/cli/approve/understanding.d.ts +0 -410
- package/dist/cli/approve/understanding.js +0 -996
- package/dist/cli/approve/understanding.js.map +0 -1
- package/dist/cli/audit.d.ts +0 -80
- package/dist/cli/audit.js +0 -252
- package/dist/cli/audit.js.map +0 -1
- package/dist/cli/delegate/index.d.ts +0 -76
- package/dist/cli/delegate/index.js +0 -443
- package/dist/cli/delegate/index.js.map +0 -1
- package/dist/cli/doctor/auto-approve-mode.d.ts +0 -37
- package/dist/cli/doctor/auto-approve-mode.js +0 -80
- package/dist/cli/doctor/auto-approve-mode.js.map +0 -1
- package/dist/cli/doctor/bypass-without-auto-approve.d.ts +0 -38
- package/dist/cli/doctor/bypass-without-auto-approve.js +0 -95
- package/dist/cli/doctor/bypass-without-auto-approve.js.map +0 -1
- package/dist/cli/doctor/codex-config-drift.d.ts +0 -28
- package/dist/cli/doctor/codex-config-drift.js +0 -240
- package/dist/cli/doctor/codex-config-drift.js.map +0 -1
- package/dist/cli/doctor/rogue-ledger.d.ts +0 -53
- package/dist/cli/doctor/rogue-ledger.js +0 -153
- package/dist/cli/doctor/rogue-ledger.js.map +0 -1
- package/dist/cli/doctor/session-start-preflight-setup-version.d.ts +0 -83
- package/dist/cli/doctor/session-start-preflight-setup-version.js +0 -114
- package/dist/cli/doctor/session-start-preflight-setup-version.js.map +0 -1
- package/dist/cli/doctor/settings-drift.d.ts +0 -25
- package/dist/cli/doctor/settings-drift.js +0 -213
- package/dist/cli/doctor/settings-drift.js.map +0 -1
- package/dist/cli/doctor/toolchain-parity.d.ts +0 -63
- package/dist/cli/doctor/toolchain-parity.js +0 -154
- package/dist/cli/doctor/toolchain-parity.js.map +0 -1
- package/dist/cli/doctor/ug-auto-approvals.d.ts +0 -40
- package/dist/cli/doctor/ug-auto-approvals.js +0 -91
- package/dist/cli/doctor/ug-auto-approvals.js.map +0 -1
- package/dist/cli/doctor/ug-delegations.d.ts +0 -26
- package/dist/cli/doctor/ug-delegations.js +0 -121
- package/dist/cli/doctor/ug-delegations.js.map +0 -1
- package/dist/cli/doctor/ug-inflight.d.ts +0 -35
- package/dist/cli/doctor/ug-inflight.js +0 -57
- package/dist/cli/doctor/ug-inflight.js.map +0 -1
- package/dist/cli/doctor/understanding-mode-env.d.ts +0 -51
- package/dist/cli/doctor/understanding-mode-env.js +0 -98
- package/dist/cli/doctor/understanding-mode-env.js.map +0 -1
- package/dist/cli/dry-run.d.ts +0 -46
- package/dist/cli/dry-run.js +0 -250
- package/dist/cli/dry-run.js.map +0 -1
- package/dist/cli/event-input.d.ts +0 -28
- package/dist/cli/event-input.js +0 -73
- package/dist/cli/event-input.js.map +0 -1
- package/dist/cli/explain-action.d.ts +0 -20
- package/dist/cli/explain-action.js +0 -27
- package/dist/cli/explain-action.js.map +0 -1
- package/dist/cli/explain-policy.d.ts +0 -135
- package/dist/cli/explain-policy.js +0 -266
- package/dist/cli/explain-policy.js.map +0 -1
- package/dist/cli/explain.d.ts +0 -31
- package/dist/cli/explain.js +0 -159
- package/dist/cli/explain.js.map +0 -1
- package/dist/cli/gc/index.d.ts +0 -63
- package/dist/cli/gc/index.js +0 -566
- package/dist/cli/gc/index.js.map +0 -1
- package/dist/cli/pack/approve-escape.d.ts +0 -19
- package/dist/cli/pack/approve-escape.js +0 -190
- package/dist/cli/pack/approve-escape.js.map +0 -1
- package/dist/cli/pack/auto-approve-path.d.ts +0 -146
- package/dist/cli/pack/auto-approve-path.js +0 -462
- package/dist/cli/pack/auto-approve-path.js.map +0 -1
- package/dist/cli/pack/hook-codex-post-tool-use.d.ts +0 -25
- package/dist/cli/pack/hook-codex-post-tool-use.js +0 -160
- package/dist/cli/pack/hook-codex-post-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +0 -48
- package/dist/cli/pack/hook-codex-pre-tool-use.js +0 -474
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-codex-stop.d.ts +0 -35
- package/dist/cli/pack/hook-codex-stop.js +0 -329
- package/dist/cli/pack/hook-codex-stop.js.map +0 -1
- package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +0 -24
- package/dist/cli/pack/hook-codex-user-prompt-submit.js +0 -93
- package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +0 -1
- package/dist/cli/pack/hook-post-merge-gate-record.d.ts +0 -37
- package/dist/cli/pack/hook-post-merge-gate-record.js +0 -190
- package/dist/cli/pack/hook-post-merge-gate-record.js.map +0 -1
- package/dist/cli/pack/hook-post-merge-gate.d.ts +0 -34
- package/dist/cli/pack/hook-post-merge-gate.js +0 -277
- package/dist/cli/pack/hook-post-merge-gate.js.map +0 -1
- package/dist/cli/pack/hook-post-tool-use.d.ts +0 -45
- package/dist/cli/pack/hook-post-tool-use.js +0 -137
- package/dist/cli/pack/hook-post-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-pre-tool-use.d.ts +0 -92
- package/dist/cli/pack/hook-pre-tool-use.js +0 -1328
- package/dist/cli/pack/hook-pre-tool-use.js.map +0 -1
- package/dist/cli/pack/hook-runtime-reality.d.ts +0 -63
- package/dist/cli/pack/hook-runtime-reality.js +0 -210
- package/dist/cli/pack/hook-runtime-reality.js.map +0 -1
- package/dist/cli/pack/hook-solution-acceptance-writeguard.d.ts +0 -32
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js +0 -337
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +0 -1
- package/dist/cli/pack/hook-solution-acceptance.d.ts +0 -157
- package/dist/cli/pack/hook-solution-acceptance.js +0 -530
- package/dist/cli/pack/hook-solution-acceptance.js.map +0 -1
- package/dist/cli/pack/hook-stay-in-scope.d.ts +0 -37
- package/dist/cli/pack/hook-stay-in-scope.js +0 -128
- package/dist/cli/pack/hook-stay-in-scope.js.map +0 -1
- package/dist/cli/pack/hook-subagent-start.d.ts +0 -23
- package/dist/cli/pack/hook-subagent-start.js +0 -88
- package/dist/cli/pack/hook-subagent-start.js.map +0 -1
- package/dist/cli/pack/hook-subagent-stop.d.ts +0 -19
- package/dist/cli/pack/hook-subagent-stop.js +0 -41
- package/dist/cli/pack/hook-subagent-stop.js.map +0 -1
- package/dist/cli/pack/hook-track-active-claim.d.ts +0 -27
- package/dist/cli/pack/hook-track-active-claim.js +0 -275
- package/dist/cli/pack/hook-track-active-claim.js.map +0 -1
- package/dist/cli/pack/transcript-report-scan.d.ts +0 -71
- package/dist/cli/pack/transcript-report-scan.js +0 -359
- package/dist/cli/pack/transcript-report-scan.js.map +0 -1
- package/dist/cli/pack/understanding-report-schema-hint.d.ts +0 -26
- package/dist/cli/pack/understanding-report-schema-hint.js +0 -120
- package/dist/cli/pack/understanding-report-schema-hint.js.map +0 -1
- package/dist/cli/pack/upgrade.d.ts +0 -32
- package/dist/cli/pack/upgrade.js +0 -273
- package/dist/cli/pack/upgrade.js.map +0 -1
- package/dist/cli/pause/index.d.ts +0 -113
- package/dist/cli/pause/index.js +0 -251
- package/dist/cli/pause/index.js.map +0 -1
- package/dist/cli/pause-check.d.ts +0 -22
- package/dist/cli/pause-check.js +0 -54
- package/dist/cli/pause-check.js.map +0 -1
- package/dist/cli/policy/intercept.d.ts +0 -233
- package/dist/cli/policy/intercept.js +0 -1020
- package/dist/cli/policy/intercept.js.map +0 -1
- package/dist/cli/policy/risk-envelope-enrichment.d.ts +0 -40
- package/dist/cli/policy/risk-envelope-enrichment.js +0 -108
- package/dist/cli/policy/risk-envelope-enrichment.js.map +0 -1
- package/dist/cli/record/index.d.ts +0 -81
- package/dist/cli/record/index.js +0 -348
- package/dist/cli/record/index.js.map +0 -1
- package/dist/cli/resolve-env.d.ts +0 -32
- package/dist/cli/resolve-env.js +0 -47
- package/dist/cli/resolve-env.js.map +0 -1
- package/dist/cli/session-export/index.d.ts +0 -46
- package/dist/cli/session-export/index.js +0 -169
- package/dist/cli/session-export/index.js.map +0 -1
- package/dist/cli/session-export/redact.d.ts +0 -22
- package/dist/cli/session-export/redact.js +0 -47
- package/dist/cli/session-export/redact.js.map +0 -1
- package/dist/cli/session-export/transcript.d.ts +0 -24
- package/dist/cli/session-export/transcript.js +0 -164
- package/dist/cli/session-export/transcript.js.map +0 -1
- package/dist/cli/session-start/branch-check.d.ts +0 -18
- package/dist/cli/session-start/branch-check.js +0 -140
- package/dist/cli/session-start/branch-check.js.map +0 -1
- package/dist/cli/session-start/index.d.ts +0 -121
- package/dist/cli/session-start/index.js +0 -591
- package/dist/cli/session-start/index.js.map +0 -1
- package/dist/cli/session-start/shared-options.d.ts +0 -103
- package/dist/cli/session-start/shared-options.js +0 -107
- package/dist/cli/session-start/shared-options.js.map +0 -1
- package/dist/cli/session-start/stale-base-check.d.ts +0 -46
- package/dist/cli/session-start/stale-base-check.js +0 -352
- package/dist/cli/session-start/stale-base-check.js.map +0 -1
- package/dist/cli/session-start/toolchain-parity.d.ts +0 -267
- package/dist/cli/session-start/toolchain-parity.js +0 -797
- package/dist/cli/session-start/toolchain-parity.js.map +0 -1
- package/dist/cli/smoke/assertions.d.ts +0 -46
- package/dist/cli/smoke/assertions.js +0 -170
- package/dist/cli/smoke/assertions.js.map +0 -1
- package/dist/cli/smoke/index.d.ts +0 -76
- package/dist/cli/smoke/index.js +0 -245
- package/dist/cli/smoke/index.js.map +0 -1
- package/dist/cli/smoke/runner.d.ts +0 -55
- package/dist/cli/smoke/runner.js +0 -134
- package/dist/cli/smoke/runner.js.map +0 -1
- package/dist/cli/smoke/stream-parser.d.ts +0 -65
- package/dist/cli/smoke/stream-parser.js +0 -115
- package/dist/cli/smoke/stream-parser.js.map +0 -1
- package/dist/cli/test-risk.d.ts +0 -26
- package/dist/cli/test-risk.js +0 -34
- package/dist/cli/test-risk.js.map +0 -1
- package/dist/io/display-path.d.ts +0 -11
- package/dist/io/display-path.js +0 -29
- package/dist/io/display-path.js.map +0 -1
- package/dist/io/duration.d.ts +0 -5
- package/dist/io/duration.js +0 -50
- package/dist/io/duration.js.map +0 -1
- package/dist/io/extract.d.ts +0 -79
- package/dist/io/extract.js +0 -226
- package/dist/io/extract.js.map +0 -1
- package/dist/io/ledger-record.d.ts +0 -83
- package/dist/io/ledger-record.js +0 -301
- package/dist/io/ledger-record.js.map +0 -1
- package/dist/io/read-json-dir-entries.d.ts +0 -36
- package/dist/io/read-json-dir-entries.js +0 -48
- package/dist/io/read-json-dir-entries.js.map +0 -1
- package/dist/io/safe-json-parse.d.ts +0 -5
- package/dist/io/safe-json-parse.js +0 -21
- package/dist/io/safe-json-parse.js.map +0 -1
- package/dist/policies/index.d.ts +0 -5
- package/dist/policies/index.js +0 -6
- package/dist/policies/index.js.map +0 -1
- package/dist/policies/ledger-client.d.ts +0 -113
- package/dist/policies/ledger-client.js +0 -500
- package/dist/policies/ledger-client.js.map +0 -1
- package/dist/policies/producers.d.ts +0 -12
- package/dist/policies/producers.js +0 -61
- package/dist/policies/producers.js.map +0 -1
- package/dist/policies/requires.d.ts +0 -75
- package/dist/policies/requires.js +0 -240
- package/dist/policies/requires.js.map +0 -1
- package/dist/policies/timestamp.d.ts +0 -14
- package/dist/policies/timestamp.js +0 -36
- package/dist/policies/timestamp.js.map +0 -1
- package/dist/policy-packs/builtin/permission-profiles.d.ts +0 -11
- package/dist/policy-packs/builtin/permission-profiles.js +0 -74
- package/dist/policy-packs/builtin/permission-profiles.js.map +0 -1
- package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +0 -286
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js +0 -397
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +0 -1
- package/dist/policy-packs/builtin/post-merge-gate.d.ts +0 -56
- package/dist/policy-packs/builtin/post-merge-gate.js +0 -347
- package/dist/policy-packs/builtin/post-merge-gate.js.map +0 -1
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.d.ts +0 -50
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.js +0 -151
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.js.map +0 -1
- package/dist/policy-packs/builtin/solution-acceptance-runtime.d.ts +0 -323
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js +0 -672
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +0 -1
- package/dist/policy-packs/builtin/solution-acceptance.d.ts +0 -45
- package/dist/policy-packs/builtin/solution-acceptance.js +0 -226
- package/dist/policy-packs/builtin/solution-acceptance.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/active-claim.d.ts +0 -25
- package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js +0 -94
- package/dist/policy-packs/builtin/understanding-before-execution/active-claim.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.d.ts +0 -35
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js +0 -86
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve-default.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.d.ts +0 -210
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js +0 -361
- package/dist/policy-packs/builtin/understanding-before-execution/auto-approve.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.d.ts +0 -304
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js +0 -734
- package/dist/policy-packs/builtin/understanding-before-execution/delegation-markers.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.d.ts +0 -36
- package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js +0 -73
- package/dist/policy-packs/builtin/understanding-before-execution/expiry-reason.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/index.d.ts +0 -19
- package/dist/policy-packs/builtin/understanding-before-execution/index.js +0 -83
- package/dist/policy-packs/builtin/understanding-before-execution/index.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.d.ts +0 -135
- package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js +0 -618
- package/dist/policy-packs/builtin/understanding-before-execution/inflight-records.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/ledger.d.ts +0 -25
- package/dist/policy-packs/builtin/understanding-before-execution/ledger.js +0 -56
- package/dist/policy-packs/builtin/understanding-before-execution/ledger.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.d.ts +0 -20
- package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js +0 -93
- package/dist/policy-packs/builtin/understanding-before-execution/lifecycle.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/markers.d.ts +0 -126
- package/dist/policy-packs/builtin/understanding-before-execution/markers.js +0 -245
- package/dist/policy-packs/builtin/understanding-before-execution/markers.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.d.ts +0 -29
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js +0 -82
- package/dist/policy-packs/builtin/understanding-before-execution/measured-permission-modes.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.d.ts +0 -71
- package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js +0 -175
- package/dist/policy-packs/builtin/understanding-before-execution/permission-mode-observations.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.d.ts +0 -620
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js +0 -1047
- package/dist/policy-packs/builtin/understanding-before-execution/persisted-reports.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.d.ts +0 -128
- package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js +0 -213
- package/dist/policy-packs/builtin/understanding-before-execution/post-tool-use-boundary.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.d.ts +0 -129
- package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js +0 -166
- package/dist/policy-packs/builtin/understanding-before-execution/stay-in-scope-config.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution/task-markers.d.ts +0 -164
- package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js +0 -275
- package/dist/policy-packs/builtin/understanding-before-execution/task-markers.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +0 -10
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +0 -1
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +0 -526
- package/dist/policy-packs/builtin/understanding-before-execution.js +0 -1074
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +0 -1
- package/dist/policy-packs/permission-translator.d.ts +0 -9
- package/dist/policy-packs/permission-translator.js +0 -76
- package/dist/policy-packs/permission-translator.js.map +0 -1
- package/dist/runtime/action-envelope.d.ts +0 -64
- package/dist/runtime/action-envelope.js +0 -46
- package/dist/runtime/action-envelope.js.map +0 -1
- package/dist/runtime/approval-signing.d.ts +0 -111
- package/dist/runtime/approval-signing.js +0 -384
- package/dist/runtime/approval-signing.js.map +0 -1
- package/dist/runtime/bash-match-facts.d.ts +0 -60
- package/dist/runtime/bash-match-facts.js +0 -196
- package/dist/runtime/bash-match-facts.js.map +0 -1
- package/dist/runtime/bash-match-registry.d.ts +0 -112
- package/dist/runtime/bash-match-registry.js +0 -406
- package/dist/runtime/bash-match-registry.js.map +0 -1
- package/dist/runtime/bash-prefix-parse.d.ts +0 -31
- package/dist/runtime/bash-prefix-parse.js +0 -576
- package/dist/runtime/bash-prefix-parse.js.map +0 -1
- package/dist/runtime/command-normalize.d.ts +0 -658
- package/dist/runtime/command-normalize.js +0 -2410
- package/dist/runtime/command-normalize.js.map +0 -1
- package/dist/runtime/deletion-target-resolve.d.ts +0 -28
- package/dist/runtime/deletion-target-resolve.js +0 -1078
- package/dist/runtime/deletion-target-resolve.js.map +0 -1
- package/dist/runtime/destructive-shell-floor.d.ts +0 -19
- package/dist/runtime/destructive-shell-floor.js +0 -611
- package/dist/runtime/destructive-shell-floor.js.map +0 -1
- package/dist/runtime/environment-resolver.d.ts +0 -36
- package/dist/runtime/environment-resolver.js +0 -138
- package/dist/runtime/environment-resolver.js.map +0 -1
- package/dist/runtime/git-context.d.ts +0 -201
- package/dist/runtime/git-context.js +0 -422
- package/dist/runtime/git-context.js.map +0 -1
- package/dist/runtime/index.d.ts +0 -12
- package/dist/runtime/index.js +0 -13
- package/dist/runtime/index.js.map +0 -1
- package/dist/runtime/intercept.d.ts +0 -494
- package/dist/runtime/intercept.js +0 -1313
- package/dist/runtime/intercept.js.map +0 -1
- package/dist/runtime/kube-context.d.ts +0 -16
- package/dist/runtime/kube-context.js +0 -63
- package/dist/runtime/kube-context.js.map +0 -1
- package/dist/runtime/kubectl-target-parse.d.ts +0 -31
- package/dist/runtime/kubectl-target-parse.js +0 -249
- package/dist/runtime/kubectl-target-parse.js.map +0 -1
- package/dist/runtime/ledger-add.d.ts +0 -16
- package/dist/runtime/ledger-add.js +0 -150
- package/dist/runtime/ledger-add.js.map +0 -1
- package/dist/runtime/ledger-writer.d.ts +0 -27
- package/dist/runtime/ledger-writer.js +0 -46
- package/dist/runtime/ledger-writer.js.map +0 -1
- package/dist/runtime/pause-sentinel.d.ts +0 -60
- package/dist/runtime/pause-sentinel.js +0 -156
- package/dist/runtime/pause-sentinel.js.map +0 -1
- package/dist/runtime/pending-approval.d.ts +0 -23
- package/dist/runtime/pending-approval.js +0 -67
- package/dist/runtime/pending-approval.js.map +0 -1
- package/dist/runtime/read-only-bash.d.ts +0 -141
- package/dist/runtime/read-only-bash.js +0 -2204
- package/dist/runtime/read-only-bash.js.map +0 -1
- package/dist/runtime/recovery-git-commit.d.ts +0 -22
- package/dist/runtime/recovery-git-commit.js +0 -284
- package/dist/runtime/recovery-git-commit.js.map +0 -1
- package/dist/runtime/reject-malformed-session-id.d.ts +0 -8
- package/dist/runtime/reject-malformed-session-id.js +0 -16
- package/dist/runtime/reject-malformed-session-id.js.map +0 -1
- package/dist/runtime/risk-classifier.d.ts +0 -38
- package/dist/runtime/risk-classifier.js +0 -311
- package/dist/runtime/risk-classifier.js.map +0 -1
- package/dist/runtime/session-id.d.ts +0 -113
- package/dist/runtime/session-id.js +0 -193
- package/dist/runtime/session-id.js.map +0 -1
- package/dist/runtime/shell-word.d.ts +0 -62
- package/dist/runtime/shell-word.js +0 -410
- package/dist/runtime/shell-word.js.map +0 -1
- package/dist/runtime/task-providers/agent-tasks.d.ts +0 -103
- package/dist/runtime/task-providers/agent-tasks.js +0 -245
- package/dist/runtime/task-providers/agent-tasks.js.map +0 -1
- package/dist/runtime/when-eval.d.ts +0 -62
- package/dist/runtime/when-eval.js +0 -212
- package/dist/runtime/when-eval.js.map +0 -1
- package/dist/runtime/workflow-policies.d.ts +0 -207
- package/dist/runtime/workflow-policies.js +0 -596
- package/dist/runtime/workflow-policies.js.map +0 -1
- package/dist/schema/audit.d.ts +0 -71
- package/dist/schema/audit.js +0 -32
- package/dist/schema/audit.js.map +0 -1
- package/dist/schema/doctor.d.ts +0 -25
- package/dist/schema/doctor.js +0 -23
- package/dist/schema/doctor.js.map +0 -1
- package/dist/schema/environments.d.ts +0 -215
- package/dist/schema/environments.js +0 -101
- package/dist/schema/environments.js.map +0 -1
- package/dist/schema/extract.d.ts +0 -9
- package/dist/schema/extract.js +0 -86
- package/dist/schema/extract.js.map +0 -1
- package/dist/schema/permission-profiles.d.ts +0 -2292
- package/dist/schema/permission-profiles.js +0 -60
- package/dist/schema/permission-profiles.js.map +0 -1
- package/dist/schema/policies.d.ts +0 -974
- package/dist/schema/policies.js +0 -298
- package/dist/schema/policies.js.map +0 -1
- package/dist/schema/requires.d.ts +0 -131
- package/dist/schema/requires.js +0 -88
- package/dist/schema/requires.js.map +0 -1
- package/dist/schema/risk.d.ts +0 -144
- package/dist/schema/risk.js +0 -194
- package/dist/schema/risk.js.map +0 -1
- package/dist/schema/session-start-preflight.d.ts +0 -10
- package/dist/schema/session-start-preflight.js +0 -106
- package/dist/schema/session-start-preflight.js.map +0 -1
- package/dist/schema/stale-base-check.d.ts +0 -18
- package/dist/schema/stale-base-check.js +0 -37
- package/dist/schema/stale-base-check.js.map +0 -1
- package/dist/schema/toolchain-parity.d.ts +0 -21
- package/dist/schema/toolchain-parity.js +0 -48
- package/dist/schema/toolchain-parity.js.map +0 -1
- package/dist/schema/workflows.d.ts +0 -519
- package/dist/schema/workflows.js +0 -81
- package/dist/schema/workflows.js.map +0 -1
- package/scripts/runtime-reality-docker-probe.mjs +0 -71
|
@@ -1,672 +0,0 @@
|
|
|
1
|
-
// Builtin Policy Pack runtime: `solution-acceptance` (consumer half).
|
|
2
|
-
//
|
|
3
|
-
// The PRODUCER lives in grounding-mcp (`solution_evaluate` / `solution_gate`,
|
|
4
|
-
// @lannguyensi/grounding-mcp >= 0.3.2): it runs a real `preflight run --json`
|
|
5
|
-
// and records a HEAD-pinned verdict marker outside the agent-writable
|
|
6
|
-
// evidence ledger. harness is the CONSUMER: it reimplements the marker read +
|
|
7
|
-
// gate decision here so it carries NO grounding-mcp runtime dependency (the
|
|
8
|
-
// same precedent as understanding-before-execution reimplementing its
|
|
9
|
-
// approval-marker read). Schema parity with the producer is pinned by a
|
|
10
|
-
// golden-fixture test against a real 0.3.2 marker; if grounding-mcp changes
|
|
11
|
-
// the Verdict shape, that test fails loudly.
|
|
12
|
-
//
|
|
13
|
-
// grounding-mcp >= 0.5.0 additionally folds orchestrator-workflow (OW)
|
|
14
|
-
// process-completeness into the verdict's `ready`, surfacing any failure
|
|
15
|
-
// reasons through the EXISTING `blockers[]` (each prefixed
|
|
16
|
-
// `orchestrator-workflow: `). It adds NO new Verdict field — the seven keys
|
|
17
|
-
// in `Verdict` below are unchanged — so the consumer needs NO gate-logic
|
|
18
|
-
// change: `evaluateGate` already denies a not-ready verdict and already joins
|
|
19
|
-
// `blockers` into the deny reason, so OW reasons reach the agent for free.
|
|
20
|
-
// Markers from older producers (< 0.5.0) stay SHAPE-compatible and remain
|
|
21
|
-
// preflight-only (no OW arm); there is no hard incompatibility.
|
|
22
|
-
//
|
|
23
|
-
// Two enforcement surfaces are built on top of these helpers (see the pack
|
|
24
|
-
// definition + the two hook verbs):
|
|
25
|
-
//
|
|
26
|
-
// 1. completion-gate — denies the task-finishing tools (agent-tasks MCP
|
|
27
|
-
// task_finish / task_submit_pr / task_merge / pull_requests_merge, plus
|
|
28
|
-
// a belt-and-suspenders bash match for `git push` / `gh pr merge`)
|
|
29
|
-
// unless a ready verdict exists at the CURRENT git HEAD.
|
|
30
|
-
//
|
|
31
|
-
// 2. write-guard — the actual anti-forgery closure. Relocating the verdict
|
|
32
|
-
// dir is NOT sufficient: understanding-gate allows all Bash post-approval
|
|
33
|
-
// (it does no write-target inspection in the allow path), so an approved
|
|
34
|
-
// agent could otherwise hand-write a `ready:true` marker. The write-guard
|
|
35
|
-
// blocks the agent's enumerated write paths into the verdict dir.
|
|
36
|
-
//
|
|
37
|
-
// Anti-forgery honesty (operator decision, 2026-05-30): v1 closed the
|
|
38
|
-
// ENUMERATED-WRITE-PATH residual (the Bash/Edit/Write spellings below), NOT
|
|
39
|
-
// arbitrary same-uid forgery. A `0500` chmod on the dir would be incoherent
|
|
40
|
-
// here because the producer (grounding-mcp) and the agent share a uid, so it
|
|
41
|
-
// would block the producer too.
|
|
42
|
-
//
|
|
43
|
-
// Content-authenticity (harness/c7c3f606): the verdict now carries an HMAC
|
|
44
|
-
// signature, reusing the SAME `signMarker` / `verifyMarkerSignature`
|
|
45
|
-
// primitive `src/runtime/approval-signing.ts` shipped for the
|
|
46
|
-
// understanding-gate / branch-protection markers (harness/f9485cc7) — same
|
|
47
|
-
// crypto, same operator-side key at `<generatedDir>/.approval-signing.key`,
|
|
48
|
-
// same fail-closed contract (missing/invalid signature = NOT satisfied,
|
|
49
|
-
// distinct `forged` reason, strict no-migration-window back-compat). See
|
|
50
|
-
// `verifyVerdictSignature` / `signVerdict` below for the payload mapping.
|
|
51
|
-
//
|
|
52
|
-
// HONEST RESIDUAL — this is consumer-side only (pattern + exemplar). Unlike
|
|
53
|
-
// the understanding-gate marker, harness does not write this one: the
|
|
54
|
-
// producer is `@lannguyensi/grounding-mcp`, a SEPARATE package/repo (see
|
|
55
|
-
// module doc above). No currently-released producer signs its output, so
|
|
56
|
-
// until a matching grounding-mcp release ships (a tracked cross-repo
|
|
57
|
-
// follow-up), EVERY verdict this consumer reads is "unsigned" and the
|
|
58
|
-
// completion-gate denies it — the SAME strict, no-grace-period POLICY
|
|
59
|
-
// f9485cc7 made (no unsigned marker satisfies the gate). The RECOVERY shape
|
|
60
|
-
// differs, though: f9485cc7's producer and consumer live in this one repo,
|
|
61
|
-
// so an operator hitting that denial has a local fix (`harness approve
|
|
62
|
-
// understanding` / `harness approve branch-protection`, one command, this
|
|
63
|
-
// release). Here the producer is a separate package on its own release
|
|
64
|
-
// cadence, so there is NO operator-side command that resolves the denial —
|
|
65
|
-
// re-running `solution_evaluate` today still yields an unsigned verdict.
|
|
66
|
-
// Operators running this pack should expect the completion-gate to deny
|
|
67
|
-
// universally until the grounding-mcp producer release ships; `harness
|
|
68
|
-
// pause` remains the operator override in the interim.
|
|
69
|
-
// Glob-every-segment / interpreter-runtime-path-construction spellings of
|
|
70
|
-
// the write-guard's residual (see below) are UNCHANGED by this: signing
|
|
71
|
-
// verifies content authenticity of whatever bytes land at the marker path,
|
|
72
|
-
// it does not additionally restrict which write primitives can reach that
|
|
73
|
-
// path (the write-guard already does that, separately, best-effort).
|
|
74
|
-
import * as os from "node:os";
|
|
75
|
-
import * as path from "node:path";
|
|
76
|
-
import { readRegularFileRejectingSymlink } from "../../io/read-regular-file.js";
|
|
77
|
-
import { sha256Hex, signMarker, verifyMarkerSignature, } from "../../runtime/approval-signing.js";
|
|
78
|
-
import { DEFAULT_PROTECTED_COMPLETION_TOOLS as ADAPTER_DEFAULT_PROTECTED_COMPLETION_TOOLS, resolveProtectedCompletionTools as resolveAdapterProtectedCompletionTools, } from "../../runtime/task-providers/agent-tasks.js";
|
|
79
|
-
export const PACK_NAME = "solution-acceptance";
|
|
80
|
-
/**
|
|
81
|
-
* agent-tasks MCP verbs that mark a completion boundary. The gate fires on
|
|
82
|
-
* these (matched by exact tool name `mcp__agent-tasks__<verb>`). These MCP
|
|
83
|
-
* choke points are reliable: unlike the bash matcher they cannot be evaded
|
|
84
|
-
* by shell indirection.
|
|
85
|
-
*/
|
|
86
|
-
export const DEFAULT_PROTECTED_COMPLETION_TOOLS = ADAPTER_DEFAULT_PROTECTED_COMPLETION_TOOLS;
|
|
87
|
-
/**
|
|
88
|
-
* Belt-and-suspenders bash matcher for `git push` / `gh pr merge`. Regex on
|
|
89
|
-
* the typed command, so an env-var indirection
|
|
90
|
-
* (`B=main && git push origin $B`) evades it — the MCP verbs above are the
|
|
91
|
-
* load-bearing choke points; hardening this is follow-up `7207d8f9`.
|
|
92
|
-
* Tolerates a leading `cd … &&`, inline `VAR=val` assignments, and `git -C
|
|
93
|
-
* <path> push`.
|
|
94
|
-
*
|
|
95
|
-
* Task 76671e5a: bare `&` added to the boundary alternation (`&&` kept to
|
|
96
|
-
* its left only to mirror `src/runtime/command-normalize.ts`'s alternation
|
|
97
|
-
* order for readability — NOT because order is load-bearing here, unlike
|
|
98
|
-
* that module). Same fix as `d834a065` applied to every policy trigger —
|
|
99
|
-
* bash starts a new command after a single `&`, so `A=x&git push` used to
|
|
100
|
-
* slip past this DENY matcher entirely. Broadening is the stricter direction
|
|
101
|
-
* here (this gates completion actions, it is not an allow-list). Measured:
|
|
102
|
-
* swapping to `&|&&` produces a byte-identical match set for this matcher
|
|
103
|
-
* (a `RegExp.test` existential check over every start offset, not a
|
|
104
|
-
* segmenter — the reasoning that makes order matter in
|
|
105
|
-
* `command-normalize.ts`'s `BOUNDARY_RE`/`AMP_BOUNDARY_RE` does not transfer
|
|
106
|
-
* to a plain `.test()` matcher like this one).
|
|
107
|
-
*/
|
|
108
|
-
export const DEFAULT_PUSH_BASH_RE = /(?:^|\n|;|\||&&|&|\()\s*(?:\w+=\S+\s+)*(?:git(?:\s+-C\s+\S+)?\s+push|gh\s+pr\s+merge)\b/;
|
|
109
|
-
/**
|
|
110
|
-
* Resolve the completion verbs the gate fires on: the pack's
|
|
111
|
-
* `config.protected_completion_tools` override, else the default set.
|
|
112
|
-
* Always non-empty. Lives here (not in the pack module) so the
|
|
113
|
-
* completion-gate hook can share it without importing the pack's zod
|
|
114
|
-
* surface (mirrors `resolveProtectedBranches` in branch-protection-runtime).
|
|
115
|
-
*/
|
|
116
|
-
export function resolveProtectedCompletionTools(pack) {
|
|
117
|
-
return resolveAdapterProtectedCompletionTools(pack.config["protected_completion_tools"]);
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Marker-id namespace the verdict's HMAC signature is bound to (mirrors
|
|
121
|
-
* `BRANCH_PROTECTION_MARKER_PREFIX` in branch-protection-runtime.ts): a
|
|
122
|
-
* validly-signed verdict for one id can never be replayed as a validly-
|
|
123
|
-
* signed verdict — or a validly-signed understanding-gate / branch-
|
|
124
|
-
* protection marker — for a different id, because `markerId` is bound into
|
|
125
|
-
* the signed payload (`approval-signing.ts` `canonicalPayload`) and this
|
|
126
|
-
* prefix keeps the three id spaces disjoint even where the raw ids
|
|
127
|
-
* (task ids, session ids) could otherwise collide.
|
|
128
|
-
*/
|
|
129
|
-
export const VERDICT_MARKER_ID_PREFIX = "solution-verdict-";
|
|
130
|
-
/** The HMAC markerId for verdict `id` (NOT a filesystem path — see `verdictPathFor` for that). */
|
|
131
|
-
export function verdictMarkerId(id) {
|
|
132
|
-
return `${VERDICT_MARKER_ID_PREFIX}${id}`;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Canonical JSON of the verdict fields the signature must bind BEYOND
|
|
136
|
-
* `(markerId, timestamp, source)` — i.e. the fields `signMarker`'s fixed
|
|
137
|
-
* `{approvedAt, approvedBy, reportContentHash}` shape has no dedicated slot
|
|
138
|
-
* for. Reusing that slot for this hash (rather than forking the primitive
|
|
139
|
-
* to add more parameters, per task scope) means `head` / `ready` /
|
|
140
|
-
* `confidence` / `blockers` are ALL covered by the signature: mutating any
|
|
141
|
-
* one of them after signing changes this hash and invalidates the
|
|
142
|
-
* signature. Fixed key order makes this injective (same argument as
|
|
143
|
-
* `canonicalPayload` in approval-signing.ts).
|
|
144
|
-
*/
|
|
145
|
-
function verdictContentHash(v) {
|
|
146
|
-
return sha256Hex(JSON.stringify({ head: v.head, ready: v.ready, confidence: v.confidence, blockers: v.blockers }));
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Sign `verdict`, reusing `signMarker` (`src/runtime/approval-signing.ts`)
|
|
150
|
-
* unmodified — same crypto as the understanding-gate / branch-protection
|
|
151
|
-
* markers (harness/f9485cc7). Payload mapping mirrors the approval
|
|
152
|
-
* marker's shape (`approvedAt`/`approvedBy`/`reportContentHash`) onto the
|
|
153
|
-
* verdict's own fields:
|
|
154
|
-
* - `approvedAt` <- `verdict.timestamp` (when the attestation was made)
|
|
155
|
-
* - `approvedBy` <- `verdict.source` (what attests it, e.g. "preflight")
|
|
156
|
-
* - `reportContentHash` <- `verdictContentHash(verdict)` (binds
|
|
157
|
-
* head/ready/confidence/blockers, the fields signMarker's fixed shape
|
|
158
|
-
* has no dedicated slot for)
|
|
159
|
-
*
|
|
160
|
-
* NOT wired to any production write path in harness (harness is a pure
|
|
161
|
-
* CONSUMER of this marker, see module doc) — exported as the pattern +
|
|
162
|
-
* exemplar a grounding-mcp-side producer change reuses, and used directly
|
|
163
|
-
* by this module's own tests to construct validly-signed fixtures.
|
|
164
|
-
*
|
|
165
|
-
* Load-bearing on the producer side: `signMarker` is called with
|
|
166
|
-
* `verdictMarkerId(verdict.id)`, while the consumer (`verifyVerdictSignature`
|
|
167
|
-
* below) verifies with `verdictMarkerId(id)` where `id` is the CALLER's id,
|
|
168
|
-
* not `verdict.id`. Those two only agree when a mirroring producer sets
|
|
169
|
-
* `verdict.id` to the EXACT id string the consumer looks the marker up by —
|
|
170
|
-
* byte-identical, no trimming or case normalization on either side — and the
|
|
171
|
-
* consumer additionally rejects outright when `verdict.id !== id` even if
|
|
172
|
-
* the signature itself still verifies (belt-and-braces, see `evaluateGate`).
|
|
173
|
-
*/
|
|
174
|
-
export function signVerdict(generatedDir, verdict) {
|
|
175
|
-
const signed = signMarker(generatedDir, verdictMarkerId(verdict.id), {
|
|
176
|
-
approvedAt: verdict.timestamp,
|
|
177
|
-
approvedBy: verdict.source,
|
|
178
|
-
reportContentHash: verdictContentHash(verdict),
|
|
179
|
-
});
|
|
180
|
-
return { ...verdict, alg: signed.alg, signature: signed.signature };
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Verify `verdict`'s signature, reusing `verifyMarkerSignature` unmodified.
|
|
184
|
-
* Recomputes `verdictContentHash` from the (possibly tampered) verdict
|
|
185
|
-
* being checked — the SAME name-mapping `signVerdict` uses — so any
|
|
186
|
-
* post-signing edit to `head` / `ready` / `confidence` / `blockers` /
|
|
187
|
-
* `timestamp` / `source` fails verification, not just an edit to
|
|
188
|
-
* `signature` itself.
|
|
189
|
-
*
|
|
190
|
-
* `id` is the CALLER's id — the one `evaluateGate` is actually checking
|
|
191
|
-
* (`readVerdict`'s lookup key) — NOT `verdict.id` (a field read back out of
|
|
192
|
-
* the marker BODY, which is exactly the bytes an attacker controls when
|
|
193
|
-
* copying a validly-signed marker verbatim onto a different id's path).
|
|
194
|
-
* This mirrors the load-bearing invariant `approval-signing.ts`'s
|
|
195
|
-
* `signMarker` doc states explicitly: "verification always recomputes the
|
|
196
|
-
* HMAC using the id the caller is checking, NOT one read back out of the
|
|
197
|
-
* marker body." Trusting `verdict.id` here would let a byte-for-byte copy
|
|
198
|
-
* of one id's signed verdict pass verification under a DIFFERENT id's
|
|
199
|
-
* request, because the copy's `signature` and its own (also-copied)
|
|
200
|
-
* `verdict.id` field would always agree with each other regardless of which
|
|
201
|
-
* id actually asked.
|
|
202
|
-
*/
|
|
203
|
-
export function verifyVerdictSignature(generatedDir, id, verdict) {
|
|
204
|
-
return verifyMarkerSignature(generatedDir, verdictMarkerId(id), {
|
|
205
|
-
approvedAt: verdict.timestamp,
|
|
206
|
-
approvedBy: verdict.source,
|
|
207
|
-
reportContentHash: verdictContentHash(verdict),
|
|
208
|
-
alg: verdict.alg,
|
|
209
|
-
signature: verdict.signature,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/** Env knob that overrides the verdict directory (mirrors the producer). */
|
|
213
|
-
export const VERDICT_DIR_ENV = "SOLUTION_VERDICT_DIR";
|
|
214
|
-
/**
|
|
215
|
-
* Env knob that supplies the verdict id for SOLO / non-agent-tasks sessions.
|
|
216
|
-
* The completion-gate consults it ONLY when no agent-tasks `active-claim` is
|
|
217
|
-
* recorded (resolution order: active-claim first, then this env, then
|
|
218
|
-
* fail-closed), so a claimed session's id stays authoritative and cannot be
|
|
219
|
-
* redirected by an env var. A sessionId fallback is intentionally still NOT a
|
|
220
|
-
* source (the wrong-scope bug class understanding-gate closed).
|
|
221
|
-
*/
|
|
222
|
-
export const VERDICT_ID_ENV = "SOLUTION_VERDICT_ID";
|
|
223
|
-
/**
|
|
224
|
-
* Stable tail of the default verdict dir. The write-guard's reference
|
|
225
|
-
* detection matches on this so ANY spelling of the home prefix is caught
|
|
226
|
-
* (`~/.local/state/...`, `$HOME/...`, `$XDG_STATE_HOME/...`, the literal
|
|
227
|
-
* absolute path).
|
|
228
|
-
*/
|
|
229
|
-
export const VERDICT_DIR_TAIL = path.join("agent-grounding", "solution-verdicts");
|
|
230
|
-
/**
|
|
231
|
-
* Resolve the verdict directory. Resolution order MUST match grounding-mcp's
|
|
232
|
-
* `verdictDir()` so the consumer reads exactly where the producer writes
|
|
233
|
-
* (operator decision B: both sides use the producer default; no apply-time
|
|
234
|
-
* env threading, no divergence risk):
|
|
235
|
-
* 1. SOLUTION_VERDICT_DIR
|
|
236
|
-
* 2. $XDG_STATE_HOME/agent-grounding/solution-verdicts
|
|
237
|
-
* 3. ~/.local/state/agent-grounding/solution-verdicts
|
|
238
|
-
*/
|
|
239
|
-
export function verdictDir(env = process.env, homedir = os.homedir) {
|
|
240
|
-
const override = env[VERDICT_DIR_ENV];
|
|
241
|
-
if (override && override.trim().length > 0)
|
|
242
|
-
return override;
|
|
243
|
-
const xdg = env["XDG_STATE_HOME"];
|
|
244
|
-
const base = xdg && xdg.trim().length > 0 ? xdg : path.join(homedir(), ".local", "state");
|
|
245
|
-
return path.join(base, "agent-grounding", "solution-verdicts");
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Reduce a verdict id to a single safe path segment. Mirrors the producer's
|
|
249
|
-
* `sanitizeVerdictId`: non-portable chars collapse to `_`, `path.basename`
|
|
250
|
-
* strips any residual separator (path-traversal guard), empty / dot-only ids
|
|
251
|
-
* are rejected.
|
|
252
|
-
*/
|
|
253
|
-
export function sanitizeVerdictId(id) {
|
|
254
|
-
const cleaned = id.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
255
|
-
const base = path.basename(cleaned);
|
|
256
|
-
if (base === "" || base === "." || base === "..") {
|
|
257
|
-
throw new Error(`invalid verdict id: ${JSON.stringify(id)}`);
|
|
258
|
-
}
|
|
259
|
-
return base;
|
|
260
|
-
}
|
|
261
|
-
export function verdictPathFor(dir, id) {
|
|
262
|
-
return path.join(dir, `${sanitizeVerdictId(id)}.json`);
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Resolve the explicit verdict id from `SOLUTION_VERDICT_ID`, or null when it
|
|
266
|
-
* is unset, blank, or not a safe single path segment. Validated through
|
|
267
|
-
* `sanitizeVerdictId` so a traversal-y or empty value fails closed here
|
|
268
|
-
* (returns null -> the gate denies) rather than reaching the marker read. This
|
|
269
|
-
* is the solo / non-agent-tasks fallback the completion-gate uses only when no
|
|
270
|
-
* active-claim is present.
|
|
271
|
-
*/
|
|
272
|
-
export function resolveExplicitVerdictId(env = process.env) {
|
|
273
|
-
const raw = env[VERDICT_ID_ENV];
|
|
274
|
-
if (typeof raw !== "string")
|
|
275
|
-
return null;
|
|
276
|
-
const trimmed = raw.trim();
|
|
277
|
-
if (trimmed.length === 0)
|
|
278
|
-
return null;
|
|
279
|
-
try {
|
|
280
|
-
sanitizeVerdictId(trimmed);
|
|
281
|
-
}
|
|
282
|
-
catch {
|
|
283
|
-
return null;
|
|
284
|
-
}
|
|
285
|
-
return trimmed;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* Read + validate the verdict marker for `id` in ONE filesystem
|
|
289
|
-
* observation, reporting the outcome instead of collapsing it. The
|
|
290
|
-
* symlink-rejecting read is the shared `src/io/read-regular-file.ts`
|
|
291
|
-
* helper (same defense-in-depth as `checkApprovalMarker` against a symlink
|
|
292
|
-
* planted at the marker path pointing at agent-controlled content), and
|
|
293
|
-
* its four non-ok kinds pass straight through, so this outcome set cannot
|
|
294
|
-
* drift from the reader's own. `invalid-record` is the one kind added on
|
|
295
|
-
* top: a regular file that WAS read but is not a verdict (unparseable
|
|
296
|
-
* JSON, or JSON missing one of the three required fields).
|
|
297
|
-
*/
|
|
298
|
-
export function readVerdictDetailed(dir, id) {
|
|
299
|
-
let p;
|
|
300
|
-
try {
|
|
301
|
-
p = verdictPathFor(dir, id);
|
|
302
|
-
}
|
|
303
|
-
catch {
|
|
304
|
-
return { kind: "invalid-id" };
|
|
305
|
-
}
|
|
306
|
-
const read = readRegularFileRejectingSymlink(p);
|
|
307
|
-
if (read.kind !== "ok")
|
|
308
|
-
return { kind: read.kind };
|
|
309
|
-
try {
|
|
310
|
-
const parsed = JSON.parse(read.content);
|
|
311
|
-
if (typeof parsed.id !== "string" ||
|
|
312
|
-
typeof parsed.head !== "string" ||
|
|
313
|
-
typeof parsed.ready !== "boolean") {
|
|
314
|
-
return { kind: "invalid-record" };
|
|
315
|
-
}
|
|
316
|
-
return {
|
|
317
|
-
kind: "ok",
|
|
318
|
-
verdict: {
|
|
319
|
-
id: parsed.id,
|
|
320
|
-
head: parsed.head,
|
|
321
|
-
ready: parsed.ready,
|
|
322
|
-
confidence: typeof parsed.confidence === "number" ? parsed.confidence : 0,
|
|
323
|
-
blockers: Array.isArray(parsed.blockers) ? parsed.blockers : [],
|
|
324
|
-
timestamp: typeof parsed.timestamp === "string" ? parsed.timestamp : "",
|
|
325
|
-
source: typeof parsed.source === "string" ? parsed.source : "",
|
|
326
|
-
// Optional (harness/c7c3f606): absent on a legacy/unsigned producer
|
|
327
|
-
// marker. `evaluateGate` treats that absence as forged/unsigned, not
|
|
328
|
-
// as a parse failure: the 7 fields above are still ALL a marker
|
|
329
|
-
// needs to parse successfully; signing is a separate, later gate.
|
|
330
|
-
alg: typeof parsed.alg === "string" ? parsed.alg : undefined,
|
|
331
|
-
signature: typeof parsed.signature === "string" ? parsed.signature : undefined,
|
|
332
|
-
},
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
catch {
|
|
336
|
-
return { kind: "invalid-record" };
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
/**
|
|
340
|
-
* Read + validate the verdict marker for `id`, or null when it is absent,
|
|
341
|
-
* unparseable, a symlink, or not a regular file: `readVerdictDetailed`
|
|
342
|
-
* above with the reason dropped. The completion-gate hook reads through
|
|
343
|
-
* `readVerdictDetailed` (it needs the reason), so this null-collapsing form
|
|
344
|
-
* has no production caller today; it stays as the exported form for a
|
|
345
|
-
* caller that only needs the verdict, and its collapse is unit-tested.
|
|
346
|
-
*/
|
|
347
|
-
export function readVerdict(dir, id) {
|
|
348
|
-
const read = readVerdictDetailed(dir, id);
|
|
349
|
-
return read.kind === "ok" ? read.verdict : null;
|
|
350
|
-
}
|
|
351
|
-
// `verifyMarkerSignature` (`src/runtime/approval-signing.ts`, NOT modified by
|
|
352
|
-
// this module) returns these exact literal reason strings when `verdict`'s
|
|
353
|
-
// `timestamp` / `source` map onto an empty `approvedAt` / `approvedBy`. That
|
|
354
|
-
// check runs FIRST, before `verifyMarkerSignature` ever looks at `signature`
|
|
355
|
-
// itself — so it fires identically whether the verdict carries NO signature
|
|
356
|
-
// at all (a genuinely legacy/unsigned marker) OR carries a well-formed
|
|
357
|
-
// `alg`/`signature` pair that no longer matches because the blank field was
|
|
358
|
-
// introduced AFTER signing (a forger tampering a real signed verdict to
|
|
359
|
-
// suppress the forged tag: blank `timestamp`, and the "missing approvedAt"
|
|
360
|
-
// short-circuit means the tampered signature is never even compared).
|
|
361
|
-
// `evaluateGate` below carves out ONLY the first case (no signature/alg
|
|
362
|
-
// present at all — the same carve-out shape as `SignatureVerification`'s
|
|
363
|
-
// `kind: "key-unavailable"`); a verdict that carries a signature/alg but
|
|
364
|
-
// still hits this reason falls through to the generic `forged: true`
|
|
365
|
-
// bucket, because "signed, yet a signed field reads blank" is post-signing
|
|
366
|
-
// tampering by construction (harness/c7c3f606 review R2). Matched by exact
|
|
367
|
-
// string since `verifyMarkerSignature` has no `kind` tag for this case; if
|
|
368
|
-
// its wording ever changes, these two constants must move with it.
|
|
369
|
-
const MISSING_APPROVED_AT_REASON = "missing approvedAt";
|
|
370
|
-
const MISSING_APPROVED_BY_REASON = "missing approvedBy";
|
|
371
|
-
/**
|
|
372
|
-
* Evaluate the gate for `id` at `currentHead`. First verifies the verdict's
|
|
373
|
-
* HMAC signature (harness/c7c3f606, fail-closed — see `verifyVerdictSignature`);
|
|
374
|
-
* a verdict that fails this is REJECTED before its `ready` / `head` fields
|
|
375
|
-
* are ever trusted, with a distinct forged/unsigned reason so an
|
|
376
|
-
* operator/auditor can tell that apart from the routine "not ready yet" or
|
|
377
|
-
* "no verdict" cases. Signature verification needs `generatedDir` (the
|
|
378
|
-
* harness `.generated/` dir holding the shared signing key, NOT the verdict
|
|
379
|
-
* dir) — `undefined` when it could not be resolved, which fails closed with
|
|
380
|
-
* its own distinct (non-forged) reason.
|
|
381
|
-
*
|
|
382
|
-
* `verifyVerdictSignature` is called with `id` — the CALLER's id, i.e. the
|
|
383
|
-
* one this function is asked to check — not `verdict.id`. A SECOND,
|
|
384
|
-
* belt-and-braces check below independently rejects `verdict.id !== id`:
|
|
385
|
-
* even though the signature check alone already closes the cross-id-replay
|
|
386
|
-
* hole (a byte-for-byte copy of a validly-signed verdict onto a different
|
|
387
|
-
* id's path fails signature verification, because the markerId the
|
|
388
|
-
* signature is bound to no longer matches `id`), the verdict body's `id`
|
|
389
|
-
* field itself is NOT part of the signed payload (only `timestamp` /
|
|
390
|
-
* `source` / the head-ready-confidence-blockers content hash are), so it
|
|
391
|
-
* can drift from the id that was actually verified without invalidating an
|
|
392
|
-
* otherwise-valid signature. This check makes that drift fail loudly too,
|
|
393
|
-
* rather than silently ignoring an inconsistency in the body of a verdict
|
|
394
|
-
* that otherwise passed.
|
|
395
|
-
*
|
|
396
|
-
* Once signed and identity-checked, mirrors grounding-mcp `evaluateGate`:
|
|
397
|
-
* allow iff `verdict.ready === true` AND `verdict.head === currentHead`.
|
|
398
|
-
* `confidence` is INFORMATIONAL ONLY and never gates — a `ready:true
|
|
399
|
-
* confidence:0` verdict at HEAD passes — so the harness consumer stays
|
|
400
|
-
* byte-parity with the producer's `solution_gate` for THAT decision.
|
|
401
|
-
* Signature verification itself is NOT (yet) mirrored on the producer side
|
|
402
|
-
* — see module doc, "HONEST RESIDUAL": grounding-mcp's own `solution_gate`
|
|
403
|
-
* does not enforce this signature, only this harness consumer does, until a
|
|
404
|
-
* matching producer release ships.
|
|
405
|
-
*/
|
|
406
|
-
export function evaluateGate(verdict, currentHead, id, generatedDir) {
|
|
407
|
-
if (!verdict) {
|
|
408
|
-
return {
|
|
409
|
-
allowed: false,
|
|
410
|
-
reason: `no usable solution-acceptance verdict for "${id}"`,
|
|
411
|
-
verdict: null,
|
|
412
|
-
forged: false,
|
|
413
|
-
};
|
|
414
|
-
}
|
|
415
|
-
if (generatedDir === undefined) {
|
|
416
|
-
return {
|
|
417
|
-
allowed: false,
|
|
418
|
-
reason: `cannot resolve harness.generated/ to verify the solution-acceptance verdict signature for "${id}"; treating as unapproved`,
|
|
419
|
-
verdict,
|
|
420
|
-
forged: false,
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
const verification = verifyVerdictSignature(generatedDir, id, verdict);
|
|
424
|
-
if (!verification.ok) {
|
|
425
|
-
if (verification.kind === "key-unavailable") {
|
|
426
|
-
return {
|
|
427
|
-
allowed: false,
|
|
428
|
-
reason: `solution-acceptance verdict for "${id}" could not be verified: ${verification.reason}; treating as unapproved`,
|
|
429
|
-
verdict,
|
|
430
|
-
forged: false,
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
if ((verification.reason === MISSING_APPROVED_AT_REASON ||
|
|
434
|
-
verification.reason === MISSING_APPROVED_BY_REASON) &&
|
|
435
|
-
verdict.signature === undefined &&
|
|
436
|
-
verdict.alg === undefined) {
|
|
437
|
-
// Scoped (harness/c7c3f606 review R2 MED): the carve-out applies ONLY
|
|
438
|
-
// to a verdict that carries NO signature/alg fields at all. A verdict
|
|
439
|
-
// that DOES carry them but still hits this reason is not "legitimately
|
|
440
|
-
// malformed" — it is a signature computed over content that now reads
|
|
441
|
-
// blank, which only happens via post-signing tampering (the blank
|
|
442
|
-
// field falls through to the generic forged:true branch below instead).
|
|
443
|
-
return {
|
|
444
|
-
allowed: false,
|
|
445
|
-
reason: `solution-acceptance verdict for "${id}" is missing a required field (${verification.reason}); ` +
|
|
446
|
-
`treating as unsigned, not forged (a legitimately malformed marker, re-run solution_evaluate)`,
|
|
447
|
-
verdict,
|
|
448
|
-
forged: false,
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
|
-
return {
|
|
452
|
-
allowed: false,
|
|
453
|
-
reason: `forged/unsigned solution-acceptance verdict rejected for "${id}": ${verification.reason} ` +
|
|
454
|
-
`(a producer that does not yet sign verdicts, or a marker written through an unguarded path)`,
|
|
455
|
-
verdict,
|
|
456
|
-
forged: true,
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
if (verdict.id !== id) {
|
|
460
|
-
return {
|
|
461
|
-
allowed: false,
|
|
462
|
-
reason: `forged/unsigned solution-acceptance verdict rejected for "${id}": verdict body identifies itself ` +
|
|
463
|
-
`as "${verdict.id}" (cross-id replay of a validly-signed verdict, or a corrupted marker)`,
|
|
464
|
-
verdict,
|
|
465
|
-
forged: true,
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
if (!verdict.ready) {
|
|
469
|
-
const why = verdict.blockers.length > 0 ? `: ${verdict.blockers.join("; ")}` : "";
|
|
470
|
-
return {
|
|
471
|
-
allowed: false,
|
|
472
|
-
reason: `solution-acceptance verdict for "${id}" is not ready${why} (fix, then re-run solution_evaluate)`,
|
|
473
|
-
verdict,
|
|
474
|
-
forged: false,
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
if (!currentHead) {
|
|
478
|
-
return {
|
|
479
|
-
allowed: false,
|
|
480
|
-
reason: `cannot resolve the current git HEAD to confirm the verdict for "${id}" is at HEAD`,
|
|
481
|
-
verdict,
|
|
482
|
-
forged: false,
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
if (verdict.head !== currentHead) {
|
|
486
|
-
return {
|
|
487
|
-
allowed: false,
|
|
488
|
-
reason: `stale solution-acceptance verdict for "${id}": recorded at ${verdict.head.slice(0, 7)}, current HEAD ${currentHead.slice(0, 7)} (re-run solution_evaluate after the rework)`,
|
|
489
|
-
verdict,
|
|
490
|
-
forged: false,
|
|
491
|
-
};
|
|
492
|
-
}
|
|
493
|
-
return {
|
|
494
|
-
allowed: true,
|
|
495
|
-
reason: `solution-acceptance verdict for "${id}" is ready at HEAD ${currentHead.slice(0, 7)} (confidence ${Math.round(verdict.confidence * 100)}%)`,
|
|
496
|
-
verdict,
|
|
497
|
-
forged: false,
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
// ── Write-guard target detection ──
|
|
501
|
-
/**
|
|
502
|
-
* Is `target` inside `dir` after resolution? Used for the path-tool arm
|
|
503
|
-
* (Write/Edit/MultiEdit/NotebookEdit `file_path`) and for a Bash shell whose
|
|
504
|
-
* cwd is the protected dir. A relative `target` resolves against `cwd`
|
|
505
|
-
* (falling back to process.cwd()).
|
|
506
|
-
*/
|
|
507
|
-
export function isInsideDir(target, dir, cwd) {
|
|
508
|
-
if (typeof target !== "string" || target.length === 0)
|
|
509
|
-
return false;
|
|
510
|
-
const absDir = path.resolve(dir);
|
|
511
|
-
const absTarget = path.isAbsolute(target)
|
|
512
|
-
? path.resolve(target)
|
|
513
|
-
: path.resolve(cwd ?? process.cwd(), target);
|
|
514
|
-
const rel = path.relative(absDir, absTarget);
|
|
515
|
-
return rel === "" || (!rel.startsWith("..") && !path.isAbsolute(rel));
|
|
516
|
-
}
|
|
517
|
-
/**
|
|
518
|
-
* Does a Bash command TEXTUALLY reference the verdict dir? Catches the
|
|
519
|
-
* enumerated spellings without shell-evaluating (same contract as
|
|
520
|
-
* read-only-bash):
|
|
521
|
-
* - the literal absolute dir,
|
|
522
|
-
* - the `$SOLUTION_VERDICT_DIR` env token,
|
|
523
|
-
* - the stable tail `agent-grounding/solution-verdicts` (covers `~/...`,
|
|
524
|
-
* `$HOME/...`, `$XDG_STATE_HOME/...`, and absolute spellings), and
|
|
525
|
-
* - the dir's LEAF segment (`solution-verdicts` for the default).
|
|
526
|
-
*
|
|
527
|
-
* The leaf segment closes the `cd <parent> && write <relative-into-dir>`
|
|
528
|
-
* descent (where the parent path and the child redirect never form the
|
|
529
|
-
* contiguous tail): ANY relative write into the dir from a cwd that is not
|
|
530
|
-
* the dir itself must name the leaf somewhere in the command, and a
|
|
531
|
-
* `cd <…/leaf>` to first make cwd==dir would itself contain the leaf. The
|
|
532
|
-
* write-guard's cwd-inside check covers the only remaining case (cwd already
|
|
533
|
-
* inside the dir). The leaf needle is length-guarded so a short custom
|
|
534
|
-
* basename does not over-block; the default leaf is distinctive, and a
|
|
535
|
-
* non-default dir already warns at validate time.
|
|
536
|
-
*
|
|
537
|
-
* `chmod`/`chattr` that target the dir are caught the same way, so the
|
|
538
|
-
* FS-perm-loosening attack is covered.
|
|
539
|
-
*
|
|
540
|
-
* Honest residual: a path constructed at runtime inside an interpreter with
|
|
541
|
-
* no textual reference (e.g. base64-decoded inside `python3 -c`) is NOT
|
|
542
|
-
* caught. That is what marker signing (follow-up) closes.
|
|
543
|
-
*/
|
|
544
|
-
export function bashReferencesVerdictDir(command, dir) {
|
|
545
|
-
if (typeof command !== "string" || command.length === 0)
|
|
546
|
-
return false;
|
|
547
|
-
const leaf = path.basename(dir);
|
|
548
|
-
// Direct literal references + the distinctive leaf segment.
|
|
549
|
-
if (command.includes(dir) ||
|
|
550
|
-
command.includes(VERDICT_DIR_ENV) ||
|
|
551
|
-
command.includes(VERDICT_DIR_TAIL) ||
|
|
552
|
-
(leaf.length >= 6 && command.includes(leaf))) {
|
|
553
|
-
return true;
|
|
554
|
-
}
|
|
555
|
-
// Glob- and brace-obscured references. bash expands `*?[` against EXISTING
|
|
556
|
-
// paths at runtime, so a glob like `solution-ver*/<id>.json` reaches the
|
|
557
|
-
// dir without the literal leaf ever appearing in the command text, and a
|
|
558
|
-
// matching glob can OVERWRITE an existing marker (flipping ready:false ->
|
|
559
|
-
// true). `{...,...}` brace expansion is unconditional (no filesystem
|
|
560
|
-
// lookup needed) and can split the leaf the same way: `solution-verdict{s,}`
|
|
561
|
-
// expands to `solution-verdicts` / `solution-verdict`, neither of which
|
|
562
|
-
// contains the literal leaf as a contiguous substring, so the direct check
|
|
563
|
-
// above misses it. We cannot safely expand either (that is the shell-eval
|
|
564
|
-
// surface read-only-bash refuses), so when a glob OR brace metacharacter is
|
|
565
|
-
// present we match the leaf's distinctive sub-words: a single glob or
|
|
566
|
-
// brace can split the hyphenated leaf but not erase every >=6-char word of
|
|
567
|
-
// it (`solution-ver*` and `solution-verdict{s,}` both keep "solution";
|
|
568
|
-
// `solu*verdicts` keeps "verdicts"). The leaf words, not the parent
|
|
569
|
-
// segment, are used on purpose: the parent here is `agent-grounding`,
|
|
570
|
-
// which is also a repo name and would over-block legitimate work. A
|
|
571
|
-
// command that globs/braces EVERY path segment is the residual the
|
|
572
|
-
// marker-signing follow-up closes.
|
|
573
|
-
//
|
|
574
|
-
// ACCEPTED COST of including `{` here: any brace now enters this
|
|
575
|
-
// leaf-word fallback, so a command carrying a brace AND one of the
|
|
576
|
-
// generic words above trips it even when it never reaches the dir.
|
|
577
|
-
// Measured examples that block today and did not before: `cd
|
|
578
|
-
// /repo/{solution,notes}`, `cd /repo/{a,b}/solution-docs`, and any
|
|
579
|
-
// non-read-only command containing a brace plus "solution"/"verdicts".
|
|
580
|
-
// "solution" is a common word, so this is not rare. It is deliberate:
|
|
581
|
-
// it fails safe, and the tighter alternative (dropping `{`) reopens
|
|
582
|
-
// the `solution-verdict{s,}` split-leaf hole, which fails open.
|
|
583
|
-
//
|
|
584
|
-
// NARROWING (task e8c9edaf): the leaf word "solution" is also the first
|
|
585
|
-
// word of this pack's own name, so any glob/brace/bracket character
|
|
586
|
-
// anywhere in the command text (a `[x]` or `**bold**` inside a heredoc body,
|
|
587
|
-
// a `.*` in a sed expression, the `***` of an apply_patch header) made a
|
|
588
|
-
// command that merely NAMES a pack source file
|
|
589
|
-
// (`docs/policy-packs/solution-acceptance.md`,
|
|
590
|
-
// `src/cli/pack/hook-solution-acceptance-writeguard.ts`, ...) look like a
|
|
591
|
-
// leaf-word hit. The word scan therefore runs on the command with each
|
|
592
|
-
// plain (no glob/brace/bracket character) whitespace-delimited word
|
|
593
|
-
// scrubbed of the pack name (`scrubPlainPackNameWords`), but ONLY when the
|
|
594
|
-
// command carries no runtime-construction syntax (`hasRuntimeConstruction`,
|
|
595
|
-
// rule stated there). A command that can build text at runtime may derive
|
|
596
|
-
// the verdict-dir leaf from the very pack-name word the scrub would erase
|
|
597
|
-
// (`v=solution-acceptance; ... ${v%-acceptance}-ver*`), so such a command
|
|
598
|
-
// is scanned unscrubbed, exactly as before the narrowing. Nothing else about
|
|
599
|
-
// the fallback changes: the direct literal checks above run on the untouched
|
|
600
|
-
// command, a word that itself carries a metacharacter is never scrubbed (so
|
|
601
|
-
// `solution-acceptance/../solution-ver*` and `[solution-acceptance]*` keep
|
|
602
|
-
// their leaf word), and a custom dir whose leaf contains the pack name is
|
|
603
|
-
// scanned unscrubbed.
|
|
604
|
-
//
|
|
605
|
-
// Still refused by design (fails closed, cannot be decided without
|
|
606
|
-
// shell-evaluating): a command whose text carries a glob/brace character AND
|
|
607
|
-
// the word "solution" or "verdicts" outside a plain pack-name word (for
|
|
608
|
-
// example prose in a heredoc body, or a glob over pack sources such as
|
|
609
|
-
// `solution-acceptance*`), and any command that carries runtime-construction
|
|
610
|
-
// syntax next to a glob/brace character and the word "solution" or
|
|
611
|
-
// "verdicts".
|
|
612
|
-
//
|
|
613
|
-
// NOT caught, before or after the narrowing (an open residual, the same one
|
|
614
|
-
// the header names): a name that is built at runtime and never appears as
|
|
615
|
-
// the word "solution" or "verdicts" in the command text. The fallback is a
|
|
616
|
-
// textual heuristic, not an evaluator; it does not turn such a command into
|
|
617
|
-
// a refusal. Marker signing (follow-up) is what closes that class.
|
|
618
|
-
if (/[*?[{]/.test(command)) {
|
|
619
|
-
const leafWords = leaf.split(/[^A-Za-z0-9]+/).filter((w) => w.length >= 6);
|
|
620
|
-
const scanned = leaf.includes(PACK_NAME) || hasRuntimeConstruction(command) ? command : scrubPlainPackNameWords(command);
|
|
621
|
-
if (leafWords.some((w) => scanned.includes(w)))
|
|
622
|
-
return true;
|
|
623
|
-
}
|
|
624
|
-
return false;
|
|
625
|
-
}
|
|
626
|
-
/** Glob, bracket and brace characters: a word carrying one can expand at runtime. */
|
|
627
|
-
const EXPANDABLE_WORD_CHARS = /[*?[\]{}]/;
|
|
628
|
-
/** The pack name as a whole word: not embedded in a longer alphanumeric run. */
|
|
629
|
-
const PACK_NAME_WORD_RE = new RegExp(`(?<![A-Za-z0-9])${PACK_NAME}(?![A-Za-z0-9])`, "g");
|
|
630
|
-
/**
|
|
631
|
-
* Replace the pack name with a space inside every whitespace-delimited word
|
|
632
|
-
* that cannot expand (no `*?[]{}` character). Such a word is a plain path or
|
|
633
|
-
* file name: its literal text reaches the verdict dir only if it contains the
|
|
634
|
-
* leaf, tail or env token, which the caller's direct checks already saw on the
|
|
635
|
-
* untouched command. A word that carries a metacharacter is returned as is.
|
|
636
|
-
* The replacement is a space, never the empty string, so scrubbing cannot
|
|
637
|
-
* join the text on either side into a new word. The caller applies this only
|
|
638
|
-
* to a command with no runtime-construction syntax (`hasRuntimeConstruction`).
|
|
639
|
-
*/
|
|
640
|
-
function scrubPlainPackNameWords(command) {
|
|
641
|
-
return command
|
|
642
|
-
.split(/(\s+)/)
|
|
643
|
-
.map((word) => (EXPANDABLE_WORD_CHARS.test(word) ? word : word.replace(PACK_NAME_WORD_RE, " ")))
|
|
644
|
-
.join("");
|
|
645
|
-
}
|
|
646
|
-
/**
|
|
647
|
-
* Runtime-construction syntax, the trigger that switches the pack-name scrub
|
|
648
|
-
* off. The rule is textual and deliberately wide (over-matching only returns
|
|
649
|
-
* the command to the pre-narrowing scan, which is the fail-closed side). A
|
|
650
|
-
* command is treated as able to build or run text at runtime when it contains
|
|
651
|
-
* any of:
|
|
652
|
-
* - a `$` (covers `$name`, `${...}` parameter expansion, `$(...)` command
|
|
653
|
-
* substitution, `$'...'`, `$"..."`) or a backtick,
|
|
654
|
-
* - `<(` or `>(` (process substitution),
|
|
655
|
-
* - `printf -v` (assigns to a variable),
|
|
656
|
-
* - one of the words `eval`, `source`, `read`, `declare`, `typeset`,
|
|
657
|
-
* `local`, `export`, `set`, `let`, `mapfile`, `readarray`, `exec`,
|
|
658
|
-
* `xargs`, `sh`, `bash`, `zsh`, `dash`, `ksh` (a word means: not part of
|
|
659
|
-
* a longer word, path segment or file name), or
|
|
660
|
-
* - a `.` in command position (`. file`, the source builtin).
|
|
661
|
-
*/
|
|
662
|
-
const RUNTIME_CONSTRUCTION_RES = [
|
|
663
|
-
/[$`]/,
|
|
664
|
-
/[<>]\(/,
|
|
665
|
-
/(?<![\w./-])printf\s+-[A-Za-z]*v/,
|
|
666
|
-
/(?<![\w./-])(?:eval|source|read|declare|typeset|local|export|set|let|mapfile|readarray|exec|xargs|sh|bash|zsh|dash|ksh)(?![\w.-])/,
|
|
667
|
-
/(?:^|[;&|(){\n]|\b(?:then|do|else)\s)\s*\.\s+\S/,
|
|
668
|
-
];
|
|
669
|
-
function hasRuntimeConstruction(command) {
|
|
670
|
-
return RUNTIME_CONSTRUCTION_RES.some((re) => re.test(command));
|
|
671
|
-
}
|
|
672
|
-
//# sourceMappingURL=solution-acceptance-runtime.js.map
|