@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,1074 +0,0 @@
|
|
|
1
|
-
// Builtin Policy Pack: `understanding-before-execution`.
|
|
2
|
-
//
|
|
3
|
-
// Bundles three hook contributions for Claude Code (UserPromptSubmit,
|
|
4
|
-
// Stop, PreToolUse), plus a per-mode instructions.md that documents what
|
|
5
|
-
// the pack is doing for human auditors. The actual prompt that the agent
|
|
6
|
-
// sees at UserPromptSubmit time is owned by `@lannguyensi/understanding-gate`
|
|
7
|
-
// (specifically `src/prompts/{full,fast-confirm,grill-me}.ts`); harness's
|
|
8
|
-
// instructions.md is the operator-facing summary, not the agent-injected
|
|
9
|
-
// text. Drift on instructions.md is therefore meaningful (someone edited
|
|
10
|
-
// the audit copy), distinct from drift on the package's own templates
|
|
11
|
-
// (which the package's own drift detection would handle on a future
|
|
12
|
-
// `understanding-gate init` reinstall).
|
|
13
|
-
import { z } from "zod";
|
|
14
|
-
import { PolicyUxSchema, ProducerSchema } from "../../schema/policies.js";
|
|
15
|
-
import { profileToSettingsPermissions } from "../permission-translator.js";
|
|
16
|
-
import { DEFAULT_RUNTIME } from "../runtime.js";
|
|
17
|
-
import { isKnownProfileName, resolveProfile, KNOWN_PROFILE_NAMES, } from "./permission-profiles.js";
|
|
18
|
-
import { AUTO_APPROVE_HARNESS_VALUES, REPORTS_DIR_ENV, } from "./understanding-before-execution-runtime.js";
|
|
19
|
-
// Through the `understanding-before-execution/index.ts` aggregator, not
|
|
20
|
-
// through the concern-scoped `auto-approve.ts` sibling directly (review
|
|
21
|
-
// fix): the prior direct import contradicted the
|
|
22
|
-
// precedent every other symbol at this call site already follows (the
|
|
23
|
-
// `AUTO_APPROVE_HARNESS_VALUES` / `REPORTS_DIR_ENV` import just above).
|
|
24
|
-
// `parseReportScanMaxWait` is now part of the shim's pinned public surface
|
|
25
|
-
// (tests/policy-packs/ube-export-surface.test.ts), alongside
|
|
26
|
-
// `DEFAULT_REPORT_SCAN_MAX_WAIT_MS` and `REPORT_SCAN_MAX_WAIT_CEILING_MS`,
|
|
27
|
-
// which this file only names in comments and so does not import.
|
|
28
|
-
import { parseReportScanMaxWait } from "./understanding-before-execution/index.js";
|
|
29
|
-
import { SHELL_ALIASES } from "../../runtime/tool-name-aliases.js";
|
|
30
|
-
import { ACTIVE_CLAIM_TOOL_NAMES, DEFAULT_BOUNDARY_TOOL_NAMES, } from "../../runtime/task-providers/agent-tasks.js";
|
|
31
|
-
import { resolveStayInScopeConfig, StayInScopeConfigSchema, } from "./understanding-before-execution/stay-in-scope-config.js";
|
|
32
|
-
// Env var the npm-backed `understanding-gate-claude-hook` bin reads to find
|
|
33
|
-
// the harness pause sentinel (`src/runtime/pause-sentinel.ts`,
|
|
34
|
-
// SENTINEL_BASENAME = ".harness-paused"). The bin runs OUTSIDE harness's
|
|
35
|
-
// own runtime (it's a package-owned process, not a `harness pack hook ...`
|
|
36
|
-
// subcommand), so it cannot resolve `generatedDir` itself the way
|
|
37
|
-
// `src/cli/pause-check.ts` does for harness's own hooks — the apply path
|
|
38
|
-
// bakes the resolved sentinel path in as an env-var prefix instead, same
|
|
39
|
-
// mechanism as UNDERSTANDING_GATE_REPORT_DIR below (agent-tasks 63fefe3a).
|
|
40
|
-
export const PAUSE_FILE_ENV = "UNDERSTANDING_GATE_PAUSE_FILE";
|
|
41
|
-
export const PACK_NAME = "understanding-before-execution";
|
|
42
|
-
// Canonical version probe for the pack's package-side bin. Consumed by
|
|
43
|
-
// `harness doctor` when the operator declares a pack-level `min_version`
|
|
44
|
-
// floor. Mirrors the hook-level UG_VERSION_COMMAND (which is scoped to
|
|
45
|
-
// individual hooks); a pack-level floor exists so a `config:` key only
|
|
46
|
-
// the newer package honours (e.g. the v0.25.0 `--task` variadic flag)
|
|
47
|
-
// can be caught at health-check time independent of any one hook.
|
|
48
|
-
export const VERSION_COMMAND = [
|
|
49
|
-
"understanding-gate",
|
|
50
|
-
"--version",
|
|
51
|
-
];
|
|
52
|
-
const MODES = ["fast_confirm", "grill_me", "strict"];
|
|
53
|
-
export const DEFAULT_MODE = "grill_me";
|
|
54
|
-
/**
|
|
55
|
-
* Env var carrying an operator-set mode override. Also the exact name
|
|
56
|
-
* `@lannguyensi/understanding-gate` reads on its own (package
|
|
57
|
-
* `src/mode.ts`: "ENV wins because operators set it consciously").
|
|
58
|
-
*
|
|
59
|
-
* Two DIFFERENT resolution contracts read this name, deliberately (task
|
|
60
|
-
* 5d73d78d, review HIGH-3 fix-round):
|
|
61
|
-
*
|
|
62
|
-
* - The GENERATION path — {@link resolve}/`buildHooks`, and
|
|
63
|
-
* `resolveBuiltinDefaultConfig` in `../registry.ts` (consumed by
|
|
64
|
-
* `harness doctor`'s UX-drift comparison and `harness pack reseed`) —
|
|
65
|
-
* resolves mode via {@link resolveModeFromConfig}, which reads ONLY
|
|
66
|
-
* `pack.config.mode`. It never consults this env var. Generation runs
|
|
67
|
-
* at `harness apply` / `harness doctor` / `harness pack reseed` time,
|
|
68
|
-
* writing artefacts (settings.json hook commands, instructions.md,
|
|
69
|
-
* reseeded config) that persist until the NEXT apply; if that write
|
|
70
|
-
* depended on whatever happened to be exported in the operator's
|
|
71
|
-
* shell at that moment, the artefact would silently drift from
|
|
72
|
-
* `config.mode` the instant the shell's env changed — exactly the
|
|
73
|
-
* class of bug this task closes for the OTHER resolver (see below),
|
|
74
|
-
* re-opened one layer up. `buildHooks` DOES still bake this env var
|
|
75
|
-
* into the two npm-backed Claude bin commands it emits (`wrapMode`)
|
|
76
|
-
* — but the value baked in is the GENERATION-time config-resolved
|
|
77
|
-
* mode, frozen at apply time, not a live env read.
|
|
78
|
-
* - LIVE runtime consumers — {@link resolveMode} (used by
|
|
79
|
-
* `approve/understanding.ts`'s stdin-report gap-fill, and by the
|
|
80
|
-
* Codex `UserPromptSubmit` injector,
|
|
81
|
-
* `src/cli/pack/hook-codex-user-prompt-submit.ts`) — resolve mode at
|
|
82
|
-
* INVOCATION time, with the live process environment actually
|
|
83
|
-
* available, so Env > `config.mode` > {@link DEFAULT_MODE} is the
|
|
84
|
-
* correct priority there: this is what makes a one-off
|
|
85
|
-
* `UNDERSTANDING_GATE_MODE=fast_confirm harness approve understanding`
|
|
86
|
-
* override work without editing harness.yaml, mirroring the npm
|
|
87
|
-
* package's own env-wins rule for the exact same reason.
|
|
88
|
-
*
|
|
89
|
-
* Before task 5d73d78d, NEITHER resolver read `config.mode` for
|
|
90
|
-
* enforcement at all — the package-owned Claude bins were invoked bare
|
|
91
|
-
* (no env var), and `persistStdinReport`'s gap-fill default was a
|
|
92
|
-
* hardcoded `"fast_confirm"` literal — so a host with `config.mode:
|
|
93
|
-
* grill_me` was silently enforced as `fast_confirm` regardless. See
|
|
94
|
-
* `docs/policy-packs/understanding-before-execution.md`'s "Mode
|
|
95
|
-
* resolution and enforcement" section for the full narrative.
|
|
96
|
-
*/
|
|
97
|
-
export const MODE_ENV = "UNDERSTANDING_GATE_MODE";
|
|
98
|
-
/**
|
|
99
|
-
* The agent-facing `required:` phrase for the understanding-gate deny
|
|
100
|
-
* envelope, derived from the configured mode. Only `strict` forces
|
|
101
|
-
* `requiresHumanApproval` (see {@link modeFriction}); in `fast_confirm`
|
|
102
|
-
* and `grill_me` the agent self-attests and a structural validator
|
|
103
|
-
* checks the report, so naming it "human-approved" there would overstate
|
|
104
|
-
* what the gate actually enforces. Generation surfaces (the Custom
|
|
105
|
-
* composer, the init templates) call this so the wording can never drift
|
|
106
|
-
* from the mode it is paired with.
|
|
107
|
-
*/
|
|
108
|
-
export function understandingApprovalRequirement(mode) {
|
|
109
|
-
return mode === "strict"
|
|
110
|
-
? "a human-approved Understanding Report for this session"
|
|
111
|
-
: "an approved Understanding Report for this session";
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Shipped default `config.producers` for this pack (agent-tasks/25bced52).
|
|
115
|
-
* Canonical source for the "golden path" recovery command: both `harness
|
|
116
|
-
* init` generation surfaces (Solo/Team/Full templates, the Custom
|
|
117
|
-
* composer) and `harness pack reseed` (task 68b9ad9c) read from here, so
|
|
118
|
-
* a future wording change to the producer descriptions only has to land
|
|
119
|
-
* in one place to reach every manifest-generating surface plus the
|
|
120
|
-
* reseed path used to backfill already-installed manifests.
|
|
121
|
-
*/
|
|
122
|
-
export function defaultProducers() {
|
|
123
|
-
return [
|
|
124
|
-
{
|
|
125
|
-
kind: "ask",
|
|
126
|
-
command: "harness approve understanding",
|
|
127
|
-
description: "Bare command, no pipes or chaining. The hook recognises it via isEscapeCommand and emits permissionDecision:ask; the operator's go on that prompt IS the gate approval. Golden path.",
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
kind: "bash",
|
|
131
|
-
command: "harness approve understanding",
|
|
132
|
-
description: "Same command from any un-hooked terminal (operator only, not reachable from inside the gated session). Writes the canonical marker at harness.generated/.approvals/${SESSION_ID}.",
|
|
133
|
-
},
|
|
134
|
-
];
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Shipped default `config.ux` for this pack, parameterised on the
|
|
138
|
-
* resolved mode (only the `required` line varies across modes — see
|
|
139
|
-
* `understandingApprovalRequirement` above). Canonical source consumed
|
|
140
|
-
* by the same generation surfaces as `defaultProducers()`, plus
|
|
141
|
-
* `harness doctor`'s divergence warning and `harness pack reseed` (task
|
|
142
|
-
* 68b9ad9c): the dogfood motivating that task found that a deny-message
|
|
143
|
-
* wording fix (e.g. the heredoc submission form, agent-tasks/e48e3b45)
|
|
144
|
-
* only reached NEW `harness init` manifests, because nothing propagated
|
|
145
|
-
* the improved text into an already-installed operator manifest whose
|
|
146
|
-
* `config.ux` still taught the old wording. Reading from one function
|
|
147
|
-
* here means a future wording fix is available to `pack reseed`
|
|
148
|
-
* automatically, with no separate update needed.
|
|
149
|
-
*/
|
|
150
|
-
export function defaultUx(mode) {
|
|
151
|
-
return {
|
|
152
|
-
cannot: "You cannot use write-capable tools yet.",
|
|
153
|
-
required: [understandingApprovalRequirement(mode)],
|
|
154
|
-
run: [
|
|
155
|
-
"Write an Understanding Report covering: Current Understanding, Intended Outcome, Derived Todos, Acceptance Criteria, Assumptions, Open Questions, Out Of Scope, Risks, Verification Plan, Prior Art (state what you searched for an existing solution and what you found, with an explicit adopt-or-build judgment)",
|
|
156
|
-
"Run `harness approve understanding` with the report attached as a quoted heredoc (harness approve understanding <<'UNDERSTANDING_REPORT' ...report... UNDERSTANDING_REPORT) so it is persisted for audit, then approve the prompt; the heredoc is the only extra shell shape the gate allows (no pipes, chaining, or other redirection)",
|
|
157
|
-
],
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
const HOOK_NAME_PREFIX = `policy-pack:${PACK_NAME}`;
|
|
161
|
-
// Per-runtime hook surface. Claude Code keys on tool name (Edit|Write|Bash);
|
|
162
|
-
// Codex's write surface is `apply_patch` plus shell tool aliases used by
|
|
163
|
-
// current runtimes (`Bash`/`shell`/`exec_command`). The hook contract Codex
|
|
164
|
-
// feeds to the adapter is the same generic envelope harness publishes:
|
|
165
|
-
// `{ session_id, tool_name, raw_input, event }` on stdin, `{ decision }`
|
|
166
|
-
// on stdout, exit 2 on block. See dogfood/phase6-6/README.md for the wire
|
|
167
|
-
// format.
|
|
168
|
-
const PRE_TOOL_USE_MATCH_CLAUDE = "Edit|Write|Bash";
|
|
169
|
-
const PRE_TOOL_USE_MATCH_CODEX = "apply_patch|Bash|shell|exec_command|functions.exec_command";
|
|
170
|
-
// UserPromptSubmit + Stop hooks point at `@lannguyensi/understanding-gate`
|
|
171
|
-
// bare bin names (npm i -g). The harness validator's checkHooks skips
|
|
172
|
-
// PATH lookup for non-rooted commands by design, so missing-bin shows
|
|
173
|
-
// up at runtime, not at lint. `harness doctor` (Phase 6 #4 follow-up)
|
|
174
|
-
// will add the presence check.
|
|
175
|
-
const BIN_USER_PROMPT_SUBMIT_CLAUDE = "understanding-gate-claude-hook";
|
|
176
|
-
const BIN_STOP_CLAUDE = "understanding-gate-claude-stop";
|
|
177
|
-
// PreToolUse blocker is the harness CLI itself (Phase 6 #4): it consults
|
|
178
|
-
// BOTH the evidence-ledger tag (canonical for harnessed sessions) AND
|
|
179
|
-
// the persisted JSON report under `.understanding-gate/reports/`
|
|
180
|
-
// (fallback for sessions without grounding-mcp wired). The npm package's
|
|
181
|
-
// own bin remains available for solo users; the harness blocker is
|
|
182
|
-
// strictly more powerful.
|
|
183
|
-
const PRE_TOOL_USE_COMMAND_CLAUDE = "harness pack hook pre-tool-use";
|
|
184
|
-
// Codex variants. The package `@lannguyensi/understanding-gate` does
|
|
185
|
-
// not yet ship Codex bins, so harness owns the adapter:
|
|
186
|
-
//
|
|
187
|
-
// - UserPromptSubmit-equivalent injector (Phase 6 #6).
|
|
188
|
-
// - Stop-equivalent capture into `.understanding-gate/reports/`
|
|
189
|
-
// (Phase 6 #6 follow-up).
|
|
190
|
-
// - PreToolUse blocker on apply_patch plus Codex shell aliases (Phase 6 #6).
|
|
191
|
-
// - PostToolUse marker-expiry (task a1348c89): Codex's published hooks
|
|
192
|
-
// reference (developers.openai.com/codex/hooks) documents
|
|
193
|
-
// `PostToolUse` as a first-class event — `[[hooks.PostToolUse]]`
|
|
194
|
-
// with a `matcher` on `tool_name`, same allow/exit-0 or
|
|
195
|
-
// block/exit-2 contract as PreToolUse. Mirrors the Claude
|
|
196
|
-
// `post-tool-use` hook via the shared matching/clearing core in
|
|
197
|
-
// understanding-before-execution-runtime.ts.
|
|
198
|
-
//
|
|
199
|
-
// Cross-runtime sessions can still approve from a Claude Code report:
|
|
200
|
-
// the ledger tag is the canonical source for harnessed sessions,
|
|
201
|
-
// independent of which runtime captured the report. The persisted-
|
|
202
|
-
// report directory is shared between runtimes, so a Codex stop that
|
|
203
|
-
// writes a report is approvable via `harness approve understanding`
|
|
204
|
-
// regardless of which runtime invokes the next tool call.
|
|
205
|
-
const COMMAND_USER_PROMPT_SUBMIT_CODEX = "harness pack hook codex-user-prompt-submit";
|
|
206
|
-
const COMMAND_STOP_CODEX = "harness pack hook codex-stop";
|
|
207
|
-
const COMMAND_PRE_TOOL_USE_CODEX = "harness pack hook codex-pre-tool-use";
|
|
208
|
-
const COMMAND_POST_TOOL_USE_CODEX = "harness pack hook codex-post-tool-use";
|
|
209
|
-
export function isMode(value) {
|
|
210
|
-
return (typeof value === "string" && MODES.includes(value));
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Zod schema for this pack's `config:` block. Surfaced via
|
|
214
|
-
* `resolveBuiltinConfigSchema()` and consumed by `harness validate` /
|
|
215
|
-
* `harness doctor` so typo'd keys (e.g. `permision_profile`) or values
|
|
216
|
-
* (e.g. `mode: fastConfirm`) fail loud at lint time instead of falling
|
|
217
|
-
* through to the runtime fallback. Each shape mirrors what the pack's
|
|
218
|
-
* own resolvers (`resolveMode`, `resolveExpireOnToolMatch`,
|
|
219
|
-
* `resolvePermissionProfile`) accept — the schema is a typo guard, not
|
|
220
|
-
* a replacement parser; the resolvers still own defaults + warnings for
|
|
221
|
-
* borderline cases the schema lets through.
|
|
222
|
-
*
|
|
223
|
-
* `.strict()` is intentional: this pack already documents every
|
|
224
|
-
* supported key, and an unknown key in the operator's manifest is far
|
|
225
|
-
* more likely to be a typo than forward-compat. New keys added in a
|
|
226
|
-
* future harness version land in this schema first, then in the pack.
|
|
227
|
-
*/
|
|
228
|
-
export const configSchema = z
|
|
229
|
-
.object({
|
|
230
|
-
mode: z.enum(MODES).optional(),
|
|
231
|
-
permission_profile: z
|
|
232
|
-
.enum(KNOWN_PROFILE_NAMES)
|
|
233
|
-
.optional(),
|
|
234
|
-
approval_lifecycle: z
|
|
235
|
-
.object({
|
|
236
|
-
// `mode: session` opts out of the PostToolUse marker-expiry hook
|
|
237
|
-
// entirely (legacy "one approval per session" UX).
|
|
238
|
-
mode: z.literal("session").optional(),
|
|
239
|
-
// Tool-name boundaries: clear the marker after one of these
|
|
240
|
-
// agent-tasks (or operator-overridden) MCP tools fires.
|
|
241
|
-
expire_on_tool_match: z.array(z.string().min(1)).optional(),
|
|
242
|
-
// Bash-command boundaries: clear the marker when a Bash call
|
|
243
|
-
// matches any of these regexes (e.g. `^gh pr (merge|close)\b`).
|
|
244
|
-
// Operators on gh-cli workflows use this in place of MCP tools.
|
|
245
|
-
expire_on_bash_match: z.array(z.string().min(1)).optional(),
|
|
246
|
-
// Safety net for sessions that never hit a listed tool/Bash
|
|
247
|
-
// boundary. Duration strings like `1h`, `4h`, `30m` are parsed
|
|
248
|
-
// by `parseApprovalLifecycle`; enforced by the marker freshness
|
|
249
|
-
// check on PreToolUse (`checkApprovalMarker`'s `max_age`
|
|
250
|
-
// comparison), not by a PostToolUse hook — `max_age` still
|
|
251
|
-
// applies under `mode: session`, which only opts out of the
|
|
252
|
-
// PostToolUse boundary hooks and the session marker's task binding.
|
|
253
|
-
max_age: z.string().min(1).optional(),
|
|
254
|
-
})
|
|
255
|
-
.strict()
|
|
256
|
-
.optional(),
|
|
257
|
-
// Operator opt-in to the hook-written signed auto-marker path for
|
|
258
|
-
// an allowlisted `permission_mode` (docs/decisions/2026-08-27-ug-auto-mode-approval.md,
|
|
259
|
-
// "Option A"). `when` names the exact permission-mode literals the
|
|
260
|
-
// hook may auto-approve; `harnesses` names which runtimes' PreToolUse
|
|
261
|
-
// hooks may take the auto path at all (absent means Claude Code only,
|
|
262
|
-
// the meaning the key had before the Codex hook joined the shared
|
|
263
|
-
// path, so an existing opt-in is never silently widened);
|
|
264
|
-
// `require_report` is required and must be literal `true` in v1 (ADR
|
|
265
|
-
// threat model (b) item 3: rejecting `false` here makes a future
|
|
266
|
-
// relaxation a visible schema change instead of a silent default).
|
|
267
|
-
// `report_scan.max_wait` (slice 3) bounds the child's transcript poll
|
|
268
|
-
// under `claude -p`; it is optional, defaults to
|
|
269
|
-
// `DEFAULT_REPORT_SCAN_MAX_WAIT_MS` when absent, and is range-checked
|
|
270
|
-
// here so an over-long bound is a `harness validate` error rather
|
|
271
|
-
// than a hook that parks a session.
|
|
272
|
-
// Runtime parsing/validation lives in
|
|
273
|
-
// `./understanding-before-execution/auto-approve.ts`.
|
|
274
|
-
auto_approve: z
|
|
275
|
-
.object({
|
|
276
|
-
when: z.array(z.string().min(1)).min(1),
|
|
277
|
-
harnesses: z
|
|
278
|
-
.array(z.enum(AUTO_APPROVE_HARNESS_VALUES))
|
|
279
|
-
.min(1)
|
|
280
|
-
.refine((values) => new Set(values).size === values.length, {
|
|
281
|
-
message: "harnesses must not contain duplicate entries",
|
|
282
|
-
})
|
|
283
|
-
.optional(),
|
|
284
|
-
report_scan: z
|
|
285
|
-
.object({
|
|
286
|
-
// Parsed by the SAME function the runtime hook uses, so the
|
|
287
|
-
// lint-time gate and the hook cannot drift on the grammar,
|
|
288
|
-
// the zero/negative rejection, or the hard ceiling.
|
|
289
|
-
max_wait: z.string().min(1).superRefine((value, ctx) => {
|
|
290
|
-
const parsed = parseReportScanMaxWait(value);
|
|
291
|
-
if (!parsed.ok) {
|
|
292
|
-
ctx.addIssue({ code: z.ZodIssueCode.custom, message: parsed.reason });
|
|
293
|
-
}
|
|
294
|
-
}),
|
|
295
|
-
})
|
|
296
|
-
.strict()
|
|
297
|
-
.optional(),
|
|
298
|
-
require_report: z.literal(true),
|
|
299
|
-
})
|
|
300
|
-
.strict()
|
|
301
|
-
.optional(),
|
|
302
|
-
// `ux` + `producers` are consumed by the PreToolUse blocker
|
|
303
|
-
// (`src/cli/pack/hook-pre-tool-use.ts`) to render an agent-facing
|
|
304
|
-
// remediation block when the gate trips. Same shape as the
|
|
305
|
-
// policy-layer `ux:` / `producers:` keys.
|
|
306
|
-
ux: PolicyUxSchema.optional(),
|
|
307
|
-
producers: z.array(ProducerSchema).min(1).optional(),
|
|
308
|
-
stay_in_scope: StayInScopeConfigSchema.optional(),
|
|
309
|
-
})
|
|
310
|
-
.strict();
|
|
311
|
-
/**
|
|
312
|
-
* POSIX single-quote-escape for an arbitrary path. Safe inside the
|
|
313
|
-
* `VAR=<value>` prefix of a `sh -c` command line. Always quotes — paths
|
|
314
|
-
* derived from `path.dirname()` may contain spaces or other shell
|
|
315
|
-
* metacharacters, and a plain `VAR=$path` would split on whitespace.
|
|
316
|
-
*/
|
|
317
|
-
export function shellQuoteSingle(s) {
|
|
318
|
-
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
319
|
-
}
|
|
320
|
-
function prefixCommandWithReportsDir(command, reportsDir) {
|
|
321
|
-
if (!reportsDir)
|
|
322
|
-
return command;
|
|
323
|
-
return `${REPORTS_DIR_ENV}=${shellQuoteSingle(reportsDir)} ${command}`;
|
|
324
|
-
}
|
|
325
|
-
function prefixCommandWithPauseFile(command, pauseFile) {
|
|
326
|
-
if (!pauseFile)
|
|
327
|
-
return command;
|
|
328
|
-
return `${PAUSE_FILE_ENV}=${shellQuoteSingle(pauseFile)} ${command}`;
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Resolve the pack's effective mode from `pack.config.mode` alone —
|
|
332
|
-
* `pack.config.mode` (harness.yaml) > {@link DEFAULT_MODE}. Never reads
|
|
333
|
-
* {@link MODE_ENV}. This is the GENERATION-path resolver: see
|
|
334
|
-
* {@link MODE_ENV}'s doc comment for why the artefacts this function's
|
|
335
|
-
* callers write (hook commands, instructions.md, reseeded config) must
|
|
336
|
-
* not depend on the live process environment. Used by {@link resolve} /
|
|
337
|
-
* `buildHooks` below, and by `resolveBuiltinDefaultConfig` in
|
|
338
|
-
* `../registry.ts`.
|
|
339
|
-
*/
|
|
340
|
-
export function resolveModeFromConfig(pack) {
|
|
341
|
-
const raw = pack.config["mode"];
|
|
342
|
-
if (raw === undefined)
|
|
343
|
-
return { mode: DEFAULT_MODE, warning: null };
|
|
344
|
-
if (isMode(raw))
|
|
345
|
-
return { mode: raw, warning: null };
|
|
346
|
-
const warning = `policy_packs[${pack.name}].config.mode: unrecognised value ${JSON.stringify(raw)}, falling back to "${DEFAULT_MODE}". Allowed: ${MODES.join(", ")}.`;
|
|
347
|
-
return { mode: DEFAULT_MODE, warning };
|
|
348
|
-
}
|
|
349
|
-
/**
|
|
350
|
-
* Resolve the pack's effective mode for a LIVE runtime consumer. Priority:
|
|
351
|
-
* {@link MODE_ENV} (env) > `pack.config.mode` (harness.yaml) >
|
|
352
|
-
* {@link DEFAULT_MODE} — see {@link MODE_ENV}'s doc comment for which
|
|
353
|
-
* callers this is (and is not) correct for. An invalid value at either
|
|
354
|
-
* the env or the config layer is skipped (with a warning) rather than
|
|
355
|
-
* short-circuiting straight to the default, so a typo'd env var does not
|
|
356
|
-
* also stomp on an otherwise-valid YAML setting. The config layer is
|
|
357
|
-
* VALIDATED (and its warning surfaced) even when a valid env value
|
|
358
|
-
* already resolved `mode` (task 5d73d78d review LOW-8): otherwise a
|
|
359
|
-
* config.mode typo would go unreported for as long as an operator happens
|
|
360
|
-
* to have a valid env override exported, resurfacing silently the moment
|
|
361
|
-
* they unset it. Env wins over YAML deliberately: it is the same
|
|
362
|
-
* precedence `@lannguyensi/understanding-gate` gives its own
|
|
363
|
-
* env-vs-marker resolution, and it is how an operator (or CI) does a
|
|
364
|
-
* one-off override without editing harness.yaml.
|
|
365
|
-
*
|
|
366
|
-
* The env value is trimmed and lower-cased before matching (task 5d73d78d
|
|
367
|
-
* review LOW-9), aligned with the npm package's own normalisation of the
|
|
368
|
-
* same env var (`pickMode`, package `src/mode.ts`:
|
|
369
|
-
* `env.UNDERSTANDING_GATE_MODE?.trim().toLowerCase()`) — so
|
|
370
|
-
* `UNDERSTANDING_GATE_MODE=' Grill_Me '` resolves the same way on both
|
|
371
|
-
* sides of the interop boundary instead of harness rejecting a value the
|
|
372
|
-
* package would have accepted.
|
|
373
|
-
*/
|
|
374
|
-
export function resolveMode(pack) {
|
|
375
|
-
const configResult = resolveModeFromConfig(pack);
|
|
376
|
-
const envRaw = process.env[MODE_ENV];
|
|
377
|
-
if (envRaw === undefined || envRaw === "")
|
|
378
|
-
return configResult;
|
|
379
|
-
const normalizedEnv = envRaw.trim().toLowerCase();
|
|
380
|
-
if (isMode(normalizedEnv)) {
|
|
381
|
-
return { mode: normalizedEnv, warning: configResult.warning };
|
|
382
|
-
}
|
|
383
|
-
const envWarning = `${MODE_ENV}=${JSON.stringify(envRaw)}: unrecognised value, ignoring. Allowed: ${MODES.join(", ")}.`;
|
|
384
|
-
return {
|
|
385
|
-
mode: configResult.mode,
|
|
386
|
-
warning: configResult.warning ? `${envWarning} ${configResult.warning}` : envWarning,
|
|
387
|
-
};
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Map harness's {@link Mode} (which includes `strict`) onto the two-value
|
|
391
|
-
* mode `@lannguyensi/understanding-gate` itself understands
|
|
392
|
-
* (`fast_confirm` | `grill_me`; package `src/schema/types.ts`). The
|
|
393
|
-
* package has no `strict` variant of its own; `grill_me` is the closest
|
|
394
|
-
* available approximation (full Report, Prior Art enforced) — passing
|
|
395
|
-
* `strict` through unmapped would mean the package silently ignores the
|
|
396
|
-
* env override (it only recognises its own two literals) and falls back
|
|
397
|
-
* to its own default, `fast_confirm`, i.e. the exact drift this task
|
|
398
|
-
* closes for `grill_me`, just unfixed for `strict`. This does not change
|
|
399
|
-
* what `strict` means inside harness (modeFriction/
|
|
400
|
-
* understandingApprovalRequirement are untouched); it only picks what to
|
|
401
|
-
* tell the external package, which cannot represent `strict` at all.
|
|
402
|
-
*/
|
|
403
|
-
export function toPackageMode(mode) {
|
|
404
|
-
return mode === "fast_confirm" ? "fast_confirm" : "grill_me";
|
|
405
|
-
}
|
|
406
|
-
// Default tools that mark task-completion boundaries when the operator
|
|
407
|
-
// has not overridden `config.approval_lifecycle.expire_on_tool_match`.
|
|
408
|
-
// agent-tasks verbs are the dogfood case; operators on Linear / JIRA /
|
|
409
|
-
// other task systems override the list in their manifest. Kept here so
|
|
410
|
-
// the PostToolUse hook always emits a sensible match pattern even when
|
|
411
|
-
// the operator hasn't set the config explicitly.
|
|
412
|
-
const DEFAULT_EXPIRE_ON_TOOL_MATCH = DEFAULT_BOUNDARY_TOOL_NAMES;
|
|
413
|
-
const POST_TOOL_USE_COMMAND_CLAUDE = "harness pack hook post-tool-use";
|
|
414
|
-
// Slice 2 of the subagent-gate work (docs/decisions/2026-08-27-ug-auto-
|
|
415
|
-
// mode-approval.md "TTL, cwd, and subagents"): Claude-only for now (an
|
|
416
|
-
// Agent-tool subagent is a Claude Code concept; Codex has no equivalent
|
|
417
|
-
// event to emit these against). Always emitted alongside the PreToolUse
|
|
418
|
-
// blocker, independent of `approval_lifecycle.mode` — an in-flight
|
|
419
|
-
// record is a copy of whatever approval the parent holds at spawn time,
|
|
420
|
-
// not itself governed by the marker-expiry opt-out.
|
|
421
|
-
const SUBAGENT_START_COMMAND = "harness pack hook subagent-start";
|
|
422
|
-
const SUBAGENT_STOP_COMMAND = "harness pack hook subagent-stop";
|
|
423
|
-
// Task cf4cdc93 (Codex parity gap #3): unlike stop/pre-tool-use/
|
|
424
|
-
// post-tool-use, the active-claim tracker and stay-in-scope reminder
|
|
425
|
-
// need NO runtime-specific CLI verb — both hook bodies only ever
|
|
426
|
-
// inspect the generic `tool_name` / `tool_input` fields already common
|
|
427
|
-
// to Claude's and Codex's PostToolUse envelope (no session_id, no
|
|
428
|
-
// shell-command extraction, no Codex-only synonym). One shared command
|
|
429
|
-
// constant per hook is therefore reused verbatim on both runtimes below
|
|
430
|
-
// instead of a `codex-track-active-claim` / `codex-stay-in-scope`
|
|
431
|
-
// sibling binary — avoids reintroducing the exact Claude/Codex drift
|
|
432
|
-
// class task e7c2ec3c fixed on the PreToolUse side.
|
|
433
|
-
const TRACK_ACTIVE_CLAIM_COMMAND = "harness pack hook track-active-claim";
|
|
434
|
-
// Hardcoded matcher for the v2 active-claim tracker (harness/494fd1e5).
|
|
435
|
-
// Agent-tasks specific; operators on other tasking systems can ignore
|
|
436
|
-
// this hook (the matcher won't fire for their tools). A config-driven
|
|
437
|
-
// extension can land later if a second tasking system asks for it.
|
|
438
|
-
const TRACK_ACTIVE_CLAIM_MATCH = `^(?:${ACTIVE_CLAIM_TOOL_NAMES.join("|")})$`;
|
|
439
|
-
// Codex sibling of TRACK_ACTIVE_CLAIM_MATCH above (task cf4cdc93): a
|
|
440
|
-
// bare, unescaped `|`-joined list, NOT the anchored `^(?:...)$` form —
|
|
441
|
-
// same rationale as `codexPostToolUseMatchPattern`'s own doc comment
|
|
442
|
-
// (task a1348c89 review finding): `expandCodexHookMatchPattern`'s
|
|
443
|
-
// "simple token" guard (`isSimpleToolPatternToken`, generate-codex-config.ts)
|
|
444
|
-
// only alias-expands a match string whose tokens are ALL "simple"; the
|
|
445
|
-
// anchor characters `^`, `(`, `?` trip that guard and the anchored form
|
|
446
|
-
// is passed through UNCHANGED at TOML-emit time, so a Codex session
|
|
447
|
-
// sending a dotted/underscore-server MCP tool-name variant would never
|
|
448
|
-
// even reach the hook. This bare form lets the emitted `config.toml`
|
|
449
|
-
// matcher — and therefore Codex's own dispatcher — recognize those
|
|
450
|
-
// variants, exactly like `PRE_TOOL_USE_MATCH_CODEX` already does.
|
|
451
|
-
const TRACK_ACTIVE_CLAIM_MATCH_CODEX = ACTIVE_CLAIM_TOOL_NAMES.join("|");
|
|
452
|
-
const STAY_IN_SCOPE_COMMAND = "harness pack hook stay-in-scope";
|
|
453
|
-
function escapeMatcherLiteral(value) {
|
|
454
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
455
|
-
}
|
|
456
|
-
// Bash tool name used to widen the PostToolUse matcher when
|
|
457
|
-
// `expire_on_bash_match` is configured (task bea04a03). Matches the
|
|
458
|
-
// single entry of `DEFAULT_BASH_TOOL_NAMES` in
|
|
459
|
-
// understanding-before-execution-runtime.ts.
|
|
460
|
-
const BASH_TOOL_NAME_CLAUDE = "Bash";
|
|
461
|
-
// Codex shell-tool aliases used for the same widening on the Codex
|
|
462
|
-
// matcher builder below. Derived from the canonical `SHELL_ALIASES` in
|
|
463
|
-
// `src/runtime/tool-name-aliases.ts` (task bea04a03 review finding) —
|
|
464
|
-
// `policy-packs/` IS allowed to depend on `runtime/` (layering rule,
|
|
465
|
-
// `.dependency-cruiser.cjs`; the sibling understanding-before-execution-runtime.ts
|
|
466
|
-
// already imports from there), so this is a shared source of truth
|
|
467
|
-
// rather than a third hand-maintained copy. `CODEX_SHELL_TOOLS` in
|
|
468
|
-
// `src/cli/pack/hook-codex-pre-tool-use.ts` stays a separate literal:
|
|
469
|
-
// `policy-packs/` may not depend on `cli/` (same layering rule), so that
|
|
470
|
-
// one cannot be unified with this without a boundary violation.
|
|
471
|
-
const BASH_TOOL_NAMES_CODEX = SHELL_ALIASES;
|
|
472
|
-
/**
|
|
473
|
-
* Compose the PostToolUse `match` regex from the configured tool list,
|
|
474
|
-
* widened with the Bash tool name when `includeBash` is true (task
|
|
475
|
-
* bea04a03: `approval_lifecycle.expire_on_bash_match` carries at least
|
|
476
|
-
* one pattern). Before this widening, `expire_on_tool_match` alone
|
|
477
|
-
* gated the matcher, so a real `Bash` call never reached the hook at
|
|
478
|
-
* all — `matchPostToolUseBoundary`'s bash-regex check (which DOES
|
|
479
|
-
* correctly evaluate `expire_on_bash_match` once invoked) was
|
|
480
|
-
* unreachable in practice. Adding "Bash" here only ROUTES the call to
|
|
481
|
-
* the hook; it does not add "Bash" to `expire_on_tool_match`'s own
|
|
482
|
-
* semantics — the hook body still classifies a matched Bash call as a
|
|
483
|
-
* bash-regex match (`toolNameMatched: false`), never a tool-name match.
|
|
484
|
-
* Each tool name is regex-escaped and joined with `|` so settings.json
|
|
485
|
-
* fires the hook only when the just-completed tool is one we care
|
|
486
|
-
* about. When the operator declared `approval_lifecycle: { mode: session }`
|
|
487
|
-
* (or cleared both lists), no PostToolUse hook is emitted at all (caller
|
|
488
|
-
* filters).
|
|
489
|
-
*/
|
|
490
|
-
function postToolUseMatchPattern(tools, includeBash) {
|
|
491
|
-
const widened = includeBash && !tools.includes(BASH_TOOL_NAME_CLAUDE)
|
|
492
|
-
? [...tools, BASH_TOOL_NAME_CLAUDE]
|
|
493
|
-
: tools;
|
|
494
|
-
const escaped = widened.map((t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
495
|
-
return `^(?:${escaped.join("|")})$`;
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Compose the CODEX PostToolUse `match` field — deliberately NOT
|
|
499
|
-
* `postToolUseMatchPattern` above (review finding on task a1348c89,
|
|
500
|
-
* verified via a direct probe of `expandCodexHookMatchPattern`). The
|
|
501
|
-
* Claude builder anchors its output in `^(?:...)$` and regex-escapes
|
|
502
|
-
* every tool name; `expandCodexHookMatchPattern` in
|
|
503
|
-
* `generate-codex-config.ts` only alias-expands a match string whose
|
|
504
|
-
* `|`-split tokens are ALL "simple" (`isSimpleToolPatternToken`,
|
|
505
|
-
* `/^[A-Za-z0-9_.:-]+$/`) — the anchor characters `^`, `(`, `?` on the
|
|
506
|
-
* first/last token trip that guard, so an anchored match is passed
|
|
507
|
-
* through UNCHANGED at emit time. Concretely: a Codex session sending
|
|
508
|
-
* the dotted `mcp__agent-tasks__.task_finish` or an underscore-server
|
|
509
|
-
* `mcp__agent_tasks__task_finish` variant would never even reach the
|
|
510
|
-
* hook — Codex's own dispatcher tests `tool_name` against the emitted
|
|
511
|
-
* `matcher`, and the anchored form only contains the canonical forms.
|
|
512
|
-
* (`matchPostToolUseBoundary`'s alias-aware body-side fix, same task,
|
|
513
|
-
* only helps once the hook is actually invoked — it cannot compensate
|
|
514
|
-
* for a dispatcher that never calls it.)
|
|
515
|
-
*
|
|
516
|
-
* This builder instead emits a BARE, unescaped `|`-joined list — same
|
|
517
|
-
* shape as the existing `PRE_TOOL_USE_MATCH_CODEX` constant above —
|
|
518
|
-
* so every token stays "simple" and `expandCodexHookMatchPattern`
|
|
519
|
-
* expands each MCP tool name into its full alias set (server
|
|
520
|
-
* hyphen/underscore swap, the `mcp__server__.tool` dotted form) at
|
|
521
|
-
* `harness apply --runtime codex` time, exactly like the Codex
|
|
522
|
-
* PreToolUse blocker's own matcher already does. No anchoring is
|
|
523
|
-
* needed here: Codex's own hook dispatch (like the sibling PreToolUse
|
|
524
|
-
* matcher) is unanchored substring-style matching already, and this
|
|
525
|
-
* keeps the Codex and Claude builders independently tunable rather
|
|
526
|
-
* than smuggling a Codex-only branch into the shared Claude helper.
|
|
527
|
-
*
|
|
528
|
-
* Like the Claude builder above, `includeBash` (task bea04a03) widens
|
|
529
|
-
* the emitted list with the Codex shell-tool aliases
|
|
530
|
-
* (`BASH_TOOL_NAMES_CODEX`: Bash/shell/exec_command/functions.exec_command)
|
|
531
|
-
* when `approval_lifecycle.expire_on_bash_match` carries at least one
|
|
532
|
-
* pattern, so a real Codex shell call is actually routed to the hook.
|
|
533
|
-
* The aliases stay simple tokens (no anchors), so they still pass
|
|
534
|
-
* through `expandCodexHookMatchPattern` unchanged — they have no MCP-style
|
|
535
|
-
* variants to expand, but they must not trip the "simple token" guard
|
|
536
|
-
* either.
|
|
537
|
-
*/
|
|
538
|
-
function codexPostToolUseMatchPattern(tools, includeBash) {
|
|
539
|
-
const widened = includeBash
|
|
540
|
-
? [...tools, ...BASH_TOOL_NAMES_CODEX.filter((t) => !tools.includes(t))]
|
|
541
|
-
: tools;
|
|
542
|
-
return widened.join("|");
|
|
543
|
-
}
|
|
544
|
-
function resolveExpireOnToolMatch(pack) {
|
|
545
|
-
const raw = pack.config["approval_lifecycle"];
|
|
546
|
-
// No config block at all: default-on with the agent-tasks tool list.
|
|
547
|
-
// This is the intentional behaviour change in v0.18 — operators who
|
|
548
|
-
// want the legacy "one approval per session" UX opt out via
|
|
549
|
-
// `approval_lifecycle: { mode: session }`.
|
|
550
|
-
if (raw === undefined || raw === null) {
|
|
551
|
-
return { tools: [...DEFAULT_EXPIRE_ON_TOOL_MATCH], emitHook: true };
|
|
552
|
-
}
|
|
553
|
-
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
554
|
-
return { tools: [...DEFAULT_EXPIRE_ON_TOOL_MATCH], emitHook: true };
|
|
555
|
-
}
|
|
556
|
-
const obj = raw;
|
|
557
|
-
if (obj["mode"] === "session") {
|
|
558
|
-
return { tools: [], emitHook: false };
|
|
559
|
-
}
|
|
560
|
-
const list = obj["expire_on_tool_match"];
|
|
561
|
-
if (Array.isArray(list)) {
|
|
562
|
-
const tools = list.filter((v) => typeof v === "string" && v.length > 0);
|
|
563
|
-
return { tools, emitHook: tools.length > 0 };
|
|
564
|
-
}
|
|
565
|
-
return { tools: [...DEFAULT_EXPIRE_ON_TOOL_MATCH], emitHook: true };
|
|
566
|
-
}
|
|
567
|
-
/**
|
|
568
|
-
* Whether `approval_lifecycle.expire_on_bash_match` carries at least one
|
|
569
|
-
* non-empty pattern (task bea04a03). Used ONLY to decide whether the
|
|
570
|
-
* emitted PostToolUse matcher should be widened to route Bash (Claude) /
|
|
571
|
-
* shell-alias (Codex) calls to the hook at all — the actual regex
|
|
572
|
-
* compiling and matching against `tool_input.command` happens downstream
|
|
573
|
-
* in `parseApprovalLifecycle` / `matchPostToolUseBoundary`
|
|
574
|
-
* (understanding-before-execution-runtime.ts). An entry that turns out to
|
|
575
|
-
* be an invalid regex is silently dropped there with a warning; that is
|
|
576
|
-
* harmless here — the matcher merely routes the call to the hook, and a
|
|
577
|
-
* hook invocation that finds no live bash-regex match just no-ops
|
|
578
|
-
* (mirrors the existing `noBoundariesConfigured` / `boundary.matched`
|
|
579
|
-
* no-op paths in hook-post-tool-use.ts / hook-codex-post-tool-use.ts).
|
|
580
|
-
*
|
|
581
|
-
* Mirrors `resolveExpireOnToolMatch`'s traversal of the same config
|
|
582
|
-
* block (undefined/non-object/`mode: session` all resolve to "not
|
|
583
|
-
* configured"), but returns a bare boolean since the matcher builders
|
|
584
|
-
* only need presence, not the pattern strings themselves.
|
|
585
|
-
*/
|
|
586
|
-
function resolveExpireOnBashMatchConfigured(pack) {
|
|
587
|
-
const raw = pack.config["approval_lifecycle"];
|
|
588
|
-
if (raw === undefined || raw === null)
|
|
589
|
-
return false;
|
|
590
|
-
if (typeof raw !== "object" || Array.isArray(raw))
|
|
591
|
-
return false;
|
|
592
|
-
const obj = raw;
|
|
593
|
-
if (obj["mode"] === "session")
|
|
594
|
-
return false;
|
|
595
|
-
const list = obj["expire_on_bash_match"];
|
|
596
|
-
if (!Array.isArray(list))
|
|
597
|
-
return false;
|
|
598
|
-
return list.some((v) => typeof v === "string" && v.length > 0);
|
|
599
|
-
}
|
|
600
|
-
/**
|
|
601
|
-
* Shared PostToolUse boundary resolution for BOTH the Claude and Codex
|
|
602
|
-
* `buildHooks` branches (task bea04a03): combines
|
|
603
|
-
* `resolveExpireOnToolMatch` and `resolveExpireOnBashMatchConfigured`
|
|
604
|
-
* into the one decision each branch's IIFE needs. Extracted specifically
|
|
605
|
-
* to avoid re-introducing the exact clone-avoidance problem
|
|
606
|
-
* `understanding-before-execution-runtime.ts`'s `matchPostToolUseBoundary`
|
|
607
|
-
* / `applyPostToolUseExpiry` / `describePostToolUseExpiry` extraction
|
|
608
|
-
* already solved once for the two runtimes' hook CLIs (`check:duplication`
|
|
609
|
-
* flagged the inline duplicate when this task first wired the two nearly-
|
|
610
|
-
* identical IIFEs by hand).
|
|
611
|
-
*/
|
|
612
|
-
function resolvePostToolUseBoundaries(pack) {
|
|
613
|
-
const { tools, emitHook: toolsEmitHook } = resolveExpireOnToolMatch(pack);
|
|
614
|
-
const bashConfigured = resolveExpireOnBashMatchConfigured(pack);
|
|
615
|
-
return { tools, bashConfigured, emit: toolsEmitHook || bashConfigured };
|
|
616
|
-
}
|
|
617
|
-
function buildHooks(runtime, pack, mode, opts = {}) {
|
|
618
|
-
// Per-mode hook commands are otherwise identical: the mode reaches the
|
|
619
|
-
// package-owned Claude bins (BIN_USER_PROMPT_SUBMIT_CLAUDE,
|
|
620
|
-
// BIN_STOP_CLAUDE) via the `UNDERSTANDING_GATE_MODE` env-var prefix
|
|
621
|
-
// below (`wrapMode`), resolved by `resolveModeFromConfig` (config.mode >
|
|
622
|
-
// DEFAULT_MODE — this is the GENERATION path, it does NOT read the env
|
|
623
|
-
// var; see {@link MODE_ENV}'s doc comment for why) and coerced through
|
|
624
|
-
// `toPackageMode` for the package's two-value enum. What changes per
|
|
625
|
-
// mode beyond that is the instructions.md content + the actual injected
|
|
626
|
-
// prompt (owned by the npm package, itself keyed off this same env var
|
|
627
|
-
// at ITS OWN, later, live-invocation time).
|
|
628
|
-
//
|
|
629
|
-
// When `opts.reportsDir` is set (the apply path), each command is ALSO
|
|
630
|
-
// prefixed with `UNDERSTANDING_GATE_REPORT_DIR=<absolute>` so all hooks
|
|
631
|
-
// — including the standalone-package Stop bin which honors the same
|
|
632
|
-
// env var — write/read the same directory.
|
|
633
|
-
const wrap = (cmd) => prefixCommandWithReportsDir(cmd, opts.reportsDir);
|
|
634
|
-
// When `opts.pauseFile` is set (the apply path), the Claude
|
|
635
|
-
// UserPromptSubmit command ALSO gets prefixed with
|
|
636
|
-
// `UNDERSTANDING_GATE_PAUSE_FILE=<absolute>` (see {@link PAUSE_FILE_ENV}'s
|
|
637
|
-
// doc comment for why only this one hook needs it: the npm-backed bin
|
|
638
|
-
// runs outside harness's own runtime and cannot resolve `generatedDir`
|
|
639
|
-
// the way harness's own hooks do).
|
|
640
|
-
const wrapPause = (cmd) => prefixCommandWithPauseFile(cmd, opts.pauseFile);
|
|
641
|
-
// Task 5d73d78d review MEDIUM-7: omit the prefix entirely when the
|
|
642
|
-
// resolved mode already coerces to the package's OWN default
|
|
643
|
-
// (`fast_confirm`). Baking `UNDERSTANDING_GATE_MODE=fast_confirm`
|
|
644
|
-
// unconditionally (as this did before this fix) made the package's
|
|
645
|
-
// in-prompt `/grill` / "grill me" escalation marker permanently dead:
|
|
646
|
-
// `pickMode()` (package `src/mode.ts`) checks its env var FIRST and
|
|
647
|
-
// returns immediately on a match, never reaching the marker check —
|
|
648
|
-
// so an operator on a `fast_confirm`-effective host could never
|
|
649
|
-
// escalate a single prompt to `grill_me` via the marker, even though
|
|
650
|
-
// the package ships exactly that mechanism. Leaving the command
|
|
651
|
-
// unprefixed changes nothing about the EFFECTIVE default (the
|
|
652
|
-
// package's own fallback is already `fast_confirm`) while restoring
|
|
653
|
-
// the marker's liveness; a `grill_me`/`strict`-resolved mode still
|
|
654
|
-
// gets the unconditional prefix, same as before.
|
|
655
|
-
const wrapMode = (cmd) => {
|
|
656
|
-
const pkgMode = toPackageMode(mode);
|
|
657
|
-
if (pkgMode === "fast_confirm")
|
|
658
|
-
return cmd;
|
|
659
|
-
return `${MODE_ENV}=${shellQuoteSingle(pkgMode)} ${cmd}`;
|
|
660
|
-
};
|
|
661
|
-
if (runtime === "codex") {
|
|
662
|
-
return [
|
|
663
|
-
{
|
|
664
|
-
name: `${HOOK_NAME_PREFIX}:codex:user-prompt-submit`,
|
|
665
|
-
event: "UserPromptSubmit",
|
|
666
|
-
command: COMMAND_USER_PROMPT_SUBMIT_CODEX,
|
|
667
|
-
blocking: false,
|
|
668
|
-
budget_ms: 5000,
|
|
669
|
-
description: "Codex adapter: inject the Understanding-Gate instruction template before the agent acts. Phase 6 #6.",
|
|
670
|
-
},
|
|
671
|
-
{
|
|
672
|
-
name: `${HOOK_NAME_PREFIX}:codex:stop`,
|
|
673
|
-
event: "Stop",
|
|
674
|
-
command: wrap(COMMAND_STOP_CODEX),
|
|
675
|
-
blocking: false,
|
|
676
|
-
budget_ms: 5000,
|
|
677
|
-
description: "Codex adapter: capture the agent's Understanding Report into .understanding-gate/reports/ as approvalStatus:pending. Phase 6 #6 follow-up.",
|
|
678
|
-
},
|
|
679
|
-
{
|
|
680
|
-
name: `${HOOK_NAME_PREFIX}:codex:pre-tool-use`,
|
|
681
|
-
event: "PreToolUse",
|
|
682
|
-
match: PRE_TOOL_USE_MATCH_CODEX,
|
|
683
|
-
command: wrap(COMMAND_PRE_TOOL_USE_CODEX),
|
|
684
|
-
blocking: "hard",
|
|
685
|
-
// 15000 (task 7bf47554): `checkLedger` (src/cli/pack/hook-codex-
|
|
686
|
-
// pre-tool-use.ts) runs an unconditional, ledger-consulting audit
|
|
687
|
-
// probe on every invocation — even when the filesystem marker
|
|
688
|
-
// already resolved the decision — bounded by the grounding-mcp
|
|
689
|
-
// server's own `health.timeout_ms` (default 5000ms), the same
|
|
690
|
-
// number budget_ms=5000 used for the outer Claude/Codex
|
|
691
|
-
// kill-timeout, leaving no margin against a merely-slow (not
|
|
692
|
-
// dead) ledger. See src/cli/init/templates.ts's budget note above
|
|
693
|
-
// require-review-evidence for the full fail-open mechanism this
|
|
694
|
-
// guards against.
|
|
695
|
-
budget_ms: 15000,
|
|
696
|
-
description: "Codex adapter: block apply_patch and Codex shell tools until the operator has approved the session's Understanding Report via harness approve understanding. Opens only on the signed approval marker; the persisted JSON report and the evidence-ledger tag are audit evidence.",
|
|
697
|
-
},
|
|
698
|
-
// PostToolUse marker-expiry (task a1348c89, widened by task
|
|
699
|
-
// bea04a03). Same boundary-tool list as the Claude hook below
|
|
700
|
-
// (resolveExpireOnToolMatch) so Codex expires on the identical
|
|
701
|
-
// configured set (agent-tasks task_finish / task_abandon /
|
|
702
|
-
// task_merge / pull_requests_merge / tasks_transition in the
|
|
703
|
-
// scaffolds), but a DIFFERENT
|
|
704
|
-
// `match` builder (`codexPostToolUseMatchPattern`, not
|
|
705
|
-
// `postToolUseMatchPattern`): see that function's own doc comment
|
|
706
|
-
// for why the Claude builder's anchored regex form silently
|
|
707
|
-
// defeats the Codex generator's MCP tool-name alias expansion
|
|
708
|
-
// (review finding on task a1348c89).
|
|
709
|
-
// `match` is ALSO widened with the Codex shell-tool aliases
|
|
710
|
-
// (Bash/shell/exec_command/functions.exec_command) whenever
|
|
711
|
-
// `approval_lifecycle.expire_on_bash_match` carries at least one
|
|
712
|
-
// pattern (task bea04a03): before this, `match` was built ONLY
|
|
713
|
-
// from `expire_on_tool_match`, so a real shell call never reached
|
|
714
|
-
// the hook body at all on EITHER runtime, even though
|
|
715
|
-
// `matchPostToolUseBoundary`'s bash-regex check correctly
|
|
716
|
-
// evaluates `expire_on_bash_match` once invoked. The widened
|
|
717
|
-
// aliases are NEVER added to `expire_on_tool_match` itself — the
|
|
718
|
-
// hook body still classifies a matched shell call as a bash-regex
|
|
719
|
-
// match, not a tool-name match, via `CODEX_SHELL_TOOLS.has(toolName)`
|
|
720
|
-
// in the caller (hook-codex-post-tool-use.ts).
|
|
721
|
-
...(() => {
|
|
722
|
-
const { tools, bashConfigured, emit } = resolvePostToolUseBoundaries(pack);
|
|
723
|
-
if (!emit)
|
|
724
|
-
return [];
|
|
725
|
-
const hook = {
|
|
726
|
-
name: `${HOOK_NAME_PREFIX}:codex:post-tool-use`,
|
|
727
|
-
event: "PostToolUse",
|
|
728
|
-
match: codexPostToolUseMatchPattern(tools, bashConfigured),
|
|
729
|
-
command: wrap(COMMAND_POST_TOOL_USE_CODEX),
|
|
730
|
-
blocking: false,
|
|
731
|
-
budget_ms: 2000,
|
|
732
|
-
description: "Codex adapter: expire the approval marker AND the persisted report after a task-completion boundary tool listed in approval_lifecycle.expire_on_tool_match (scaffolds: agent-tasks task_finish / task_abandon / task_merge / pull_requests_merge / tasks_transition; a task_finish that lands in review keeps the approval) or an expire_on_bash_match shell command. Forces a fresh Understanding Report on the next task.",
|
|
733
|
-
};
|
|
734
|
-
return [hook];
|
|
735
|
-
})(),
|
|
736
|
-
// Active-claim tracker (harness/494fd1e5), Codex parity task
|
|
737
|
-
// cf4cdc93 (parity-gaps doc gap #3). Always emitted alongside the
|
|
738
|
-
// pack, mirroring the Claude sibling below — the matcher won't
|
|
739
|
-
// fire for operators on non-agent-tasks tasking systems, so the
|
|
740
|
-
// file simply never appears for them. Same command as Claude
|
|
741
|
-
// (see TRACK_ACTIVE_CLAIM_COMMAND's doc comment above): the hook
|
|
742
|
-
// body needs no Codex-specific handling.
|
|
743
|
-
{
|
|
744
|
-
name: `${HOOK_NAME_PREFIX}:codex:track-active-claim`,
|
|
745
|
-
event: "PostToolUse",
|
|
746
|
-
match: TRACK_ACTIVE_CLAIM_MATCH_CODEX,
|
|
747
|
-
command: TRACK_ACTIVE_CLAIM_COMMAND,
|
|
748
|
-
blocking: false,
|
|
749
|
-
budget_ms: 2000,
|
|
750
|
-
description: "Codex adapter: track the active agent-tasks claim by writing/clearing <generatedDir>/active-claim on task_start / task_finish / task_abandon / task_merge. Lets `harness approve understanding` auto-resolve the task id (harness/494fd1e5, Codex parity task cf4cdc93).",
|
|
751
|
-
},
|
|
752
|
-
...(() => {
|
|
753
|
-
const stayInScope = resolveStayInScopeConfig(pack.config["stay_in_scope"]);
|
|
754
|
-
if (stayInScope === null)
|
|
755
|
-
return [];
|
|
756
|
-
return [{
|
|
757
|
-
name: `${HOOK_NAME_PREFIX}:codex:stay-in-scope`,
|
|
758
|
-
event: "PostToolUse",
|
|
759
|
-
match: stayInScope.tools.join("|"),
|
|
760
|
-
command: STAY_IN_SCOPE_COMMAND,
|
|
761
|
-
blocking: false,
|
|
762
|
-
budget_ms: 2000,
|
|
763
|
-
description: "Codex adapter: emit the configured soft stay-in-scope reminder and audit row.",
|
|
764
|
-
}];
|
|
765
|
-
})(),
|
|
766
|
-
];
|
|
767
|
-
}
|
|
768
|
-
// `min_version` floor on the npm-backed bins: 0.4.0 ships the
|
|
769
|
-
// required "Prior Art" 10th section of the Understanding Report
|
|
770
|
-
// (agent-grounding PR #85, harness task 798d7173). Operators below
|
|
771
|
-
// this floor would silently miss the section because the Stop-capture
|
|
772
|
-
// parser doesn't yet enforce it. The prior floor was 0.3.1 (first
|
|
773
|
-
// release whose `understanding-gate --version` reported the actual
|
|
774
|
-
// installed version rather than a stale literal; agent-grounding PRs
|
|
775
|
-
// #80 + #81); 0.4.0 supersedes it. The PreToolUse blocker below is
|
|
776
|
-
// the harness CLI itself, not an npm-backed bin, so it does not carry
|
|
777
|
-
// a floor here.
|
|
778
|
-
// 0.5.0 raises the floor again: the UserPromptSubmit hook now carries an
|
|
779
|
-
// UNDERSTANDING_GATE_PAUSE_FILE prefix, and only 0.5.0 and later read that
|
|
780
|
-
// variable. On an older gate the prefix is set but ignored, so the pause
|
|
781
|
-
// wiring is silently inert; the floor makes `harness doctor` say so instead
|
|
782
|
-
// of leaving the operator to discover it.
|
|
783
|
-
const UG_MIN_VERSION = "0.5.0";
|
|
784
|
-
const UG_VERSION_COMMAND = [
|
|
785
|
-
"understanding-gate",
|
|
786
|
-
"--version",
|
|
787
|
-
];
|
|
788
|
-
return [
|
|
789
|
-
{
|
|
790
|
-
name: `${HOOK_NAME_PREFIX}:user-prompt-submit`,
|
|
791
|
-
event: "UserPromptSubmit",
|
|
792
|
-
command: wrapMode(wrapPause(BIN_USER_PROMPT_SUBMIT_CLAUDE)),
|
|
793
|
-
blocking: false,
|
|
794
|
-
budget_ms: 5000,
|
|
795
|
-
min_version: UG_MIN_VERSION,
|
|
796
|
-
version_command: UG_VERSION_COMMAND,
|
|
797
|
-
description: "Inject the Understanding-Gate instruction template before the agent acts. Source: @lannguyensi/understanding-gate.",
|
|
798
|
-
},
|
|
799
|
-
{
|
|
800
|
-
name: `${HOOK_NAME_PREFIX}:stop`,
|
|
801
|
-
event: "Stop",
|
|
802
|
-
command: wrapMode(wrap(BIN_STOP_CLAUDE)),
|
|
803
|
-
blocking: false,
|
|
804
|
-
budget_ms: 5000,
|
|
805
|
-
min_version: UG_MIN_VERSION,
|
|
806
|
-
version_command: UG_VERSION_COMMAND,
|
|
807
|
-
description: "Capture the agent's Understanding Report into .understanding-gate/reports/. Source: @lannguyensi/understanding-gate.",
|
|
808
|
-
},
|
|
809
|
-
{
|
|
810
|
-
name: `${HOOK_NAME_PREFIX}:pre-tool-use`,
|
|
811
|
-
event: "PreToolUse",
|
|
812
|
-
match: PRE_TOOL_USE_MATCH_CLAUDE,
|
|
813
|
-
command: wrap(PRE_TOOL_USE_COMMAND_CLAUDE),
|
|
814
|
-
blocking: "hard",
|
|
815
|
-
// 15000: same rationale as the Codex sibling above (checkLedger in
|
|
816
|
-
// src/cli/pack/hook-pre-tool-use.ts is the same unconditional
|
|
817
|
-
// ledger-consulting audit probe, same health.timeout_ms bound).
|
|
818
|
-
budget_ms: 15000,
|
|
819
|
-
description: "Block Edit/Write/Bash until the operator has approved the session's Understanding Report via harness approve understanding. Opens only on the signed approval marker; the persisted JSON report and the evidence-ledger tag (understanding-approved:${SESSION_ID}) are audit evidence.",
|
|
820
|
-
},
|
|
821
|
-
// In-flight subagent records (slice 2, docs/decisions/2026-08-27-ug-
|
|
822
|
-
// auto-mode-approval.md "TTL, cwd, and subagents"). An Agent-tool
|
|
823
|
-
// subagent shares its parent's session_id but cannot itself call
|
|
824
|
-
// `harness approve understanding`; SubagentStart copies whatever
|
|
825
|
-
// approval the parent holds AT SPAWN TIME into a signed record the
|
|
826
|
-
// subagent can present later even if the parent's own marker expires
|
|
827
|
-
// mid-flight, and SubagentStop removes it when the subagent finishes.
|
|
828
|
-
// Always emitted alongside the PreToolUse blocker above — never
|
|
829
|
-
// gated behind `approval_lifecycle.mode` the way the marker-expiry
|
|
830
|
-
// hook below is, since a record is a copy of authority, not itself
|
|
831
|
-
// subject to that opt-out. Claude-only: the Agent tool (and its
|
|
832
|
-
// SubagentStart/SubagentStop events) has no Codex equivalent.
|
|
833
|
-
{
|
|
834
|
-
name: `${HOOK_NAME_PREFIX}:subagent-start`,
|
|
835
|
-
event: "SubagentStart",
|
|
836
|
-
// Reads persisted reports (report-hash cross-check before minting the
|
|
837
|
-
// record), so it carries the same reports-dir prefix as the other
|
|
838
|
-
// report-reading hooks and agrees with where `harness approve` wrote.
|
|
839
|
-
command: wrap(SUBAGENT_START_COMMAND),
|
|
840
|
-
blocking: false,
|
|
841
|
-
budget_ms: 2000,
|
|
842
|
-
description: "Write a signed in-flight record for a newly-started Agent-tool subagent when the parent session currently holds a valid understanding-gate approval, so the subagent can keep that approval independent of what happens to the parent's own marker afterwards.",
|
|
843
|
-
},
|
|
844
|
-
{
|
|
845
|
-
name: `${HOOK_NAME_PREFIX}:subagent-stop`,
|
|
846
|
-
event: "SubagentStop",
|
|
847
|
-
command: SUBAGENT_STOP_COMMAND,
|
|
848
|
-
blocking: false,
|
|
849
|
-
budget_ms: 2000,
|
|
850
|
-
description: "Remove the in-flight record written for this subagent by subagent-start when it finishes.",
|
|
851
|
-
},
|
|
852
|
-
// PostToolUse marker-expiry hook (agent-tasks/d8ee60ca). Fires on the
|
|
853
|
-
// configured task-boundary tools, and (task bea04a03) on a Bash call
|
|
854
|
-
// when `approval_lifecycle.expire_on_bash_match` carries at least one
|
|
855
|
-
// pattern, and deletes the approval marker so the next Edit / Write /
|
|
856
|
-
// Bash forces a fresh Understanding Report. The runtime tool list is
|
|
857
|
-
// the configured expire_on_tool_match (scaffolds: agent-tasks
|
|
858
|
-
// task_finish / task_abandon / task_merge / pull_requests_merge /
|
|
859
|
-
// tasks_transition); DEFAULT_BOUNDARY_TOOL_NAMES only shapes the
|
|
860
|
-
// emitted matcher when no list is configured.
|
|
861
|
-
// Operators on other task systems override the list via
|
|
862
|
-
// config.approval_lifecycle.expire_on_tool_match; setting
|
|
863
|
-
// `approval_lifecycle: { mode: session }` opts out entirely and
|
|
864
|
-
// suppresses this hook from being emitted at all.
|
|
865
|
-
//
|
|
866
|
-
// Before task bea04a03, `match` was built ONLY from
|
|
867
|
-
// `expire_on_tool_match`, so a real `Bash` call never invoked this
|
|
868
|
-
// hook at all — `matchPostToolUseBoundary`'s bash-regex check (which
|
|
869
|
-
// DOES correctly evaluate `expire_on_bash_match` once invoked)
|
|
870
|
-
// was unreachable. Widening `match` to include "Bash" does not
|
|
871
|
-
// change how the hook body classifies the match: a Bash call that
|
|
872
|
-
// fires the hook is still evaluated as a bash-regex match
|
|
873
|
-
// (`toolNameMatched: false`), never folded into
|
|
874
|
-
// `expire_on_tool_match`'s own tool-name semantics.
|
|
875
|
-
...(() => {
|
|
876
|
-
const { tools, bashConfigured, emit } = resolvePostToolUseBoundaries(pack);
|
|
877
|
-
if (!emit)
|
|
878
|
-
return [];
|
|
879
|
-
const hook = {
|
|
880
|
-
name: `${HOOK_NAME_PREFIX}:post-tool-use`,
|
|
881
|
-
event: "PostToolUse",
|
|
882
|
-
match: postToolUseMatchPattern(tools, bashConfigured),
|
|
883
|
-
// Wrap with UNDERSTANDING_GATE_REPORT_DIR so the post-tool-use
|
|
884
|
-
// hook resolves the same persisted-reports directory as the
|
|
885
|
-
// pre-tool-use blocker; otherwise it can't expire the persisted
|
|
886
|
-
// report alongside the marker (harness/1ee26e77 follow-up).
|
|
887
|
-
command: wrap(POST_TOOL_USE_COMMAND_CLAUDE),
|
|
888
|
-
blocking: false,
|
|
889
|
-
budget_ms: 2000,
|
|
890
|
-
description: "Expire the approval marker AND the persisted report after a task-completion boundary tool listed in approval_lifecycle.expire_on_tool_match (scaffolds: agent-tasks task_finish / task_abandon / task_merge / pull_requests_merge / tasks_transition; a task_finish that lands in review keeps the approval) or an expire_on_bash_match Bash command. Forces a fresh Understanding Report on the next task.",
|
|
891
|
-
};
|
|
892
|
-
return [hook];
|
|
893
|
-
})(),
|
|
894
|
-
// Active-claim tracker (harness/494fd1e5). PostToolUse hook on
|
|
895
|
-
// agent-tasks task_start / task_finish / task_abandon / task_merge
|
|
896
|
-
// (task_merge added by task c86e3c4a: previously untracked here, so
|
|
897
|
-
// a real task_merge tool call never dispatched to the hook at all).
|
|
898
|
-
// Maintains a small file at <generatedDir>/active-claim so `harness
|
|
899
|
-
// approve understanding` can auto-resolve the task id when --task is
|
|
900
|
-
// absent. Always emitted alongside the pack — operators on other
|
|
901
|
-
// tasking systems are unaffected (the matcher won't fire for
|
|
902
|
-
// their tools), the file simply never appears.
|
|
903
|
-
{
|
|
904
|
-
name: `${HOOK_NAME_PREFIX}:track-active-claim`,
|
|
905
|
-
event: "PostToolUse",
|
|
906
|
-
match: TRACK_ACTIVE_CLAIM_MATCH,
|
|
907
|
-
command: TRACK_ACTIVE_CLAIM_COMMAND,
|
|
908
|
-
blocking: false,
|
|
909
|
-
budget_ms: 2000,
|
|
910
|
-
description: "Track the active agent-tasks claim by writing/clearing <generatedDir>/active-claim on task_start / task_finish / task_abandon / task_merge. Lets `harness approve understanding` auto-resolve the task id (harness/494fd1e5).",
|
|
911
|
-
},
|
|
912
|
-
...(() => {
|
|
913
|
-
const stayInScope = resolveStayInScopeConfig(pack.config["stay_in_scope"]);
|
|
914
|
-
if (stayInScope === null)
|
|
915
|
-
return [];
|
|
916
|
-
return [{
|
|
917
|
-
name: `${HOOK_NAME_PREFIX}:stay-in-scope`,
|
|
918
|
-
event: "PostToolUse",
|
|
919
|
-
match: `^(?:${stayInScope.tools.map(escapeMatcherLiteral).join("|")})$`,
|
|
920
|
-
command: STAY_IN_SCOPE_COMMAND,
|
|
921
|
-
blocking: false,
|
|
922
|
-
budget_ms: 2000,
|
|
923
|
-
description: "Emit the configured soft stay-in-scope reminder and audit row.",
|
|
924
|
-
}];
|
|
925
|
-
})(),
|
|
926
|
-
];
|
|
927
|
-
}
|
|
928
|
-
function modeFriction(mode) {
|
|
929
|
-
switch (mode) {
|
|
930
|
-
case "fast_confirm":
|
|
931
|
-
return "low friction. The gate fires on prompts the classifier flags as execution-relevant. Brief Understanding Report; one-line approval.";
|
|
932
|
-
case "grill_me":
|
|
933
|
-
return "medium friction (default). The gate fires on any prompt the agent might respond to with a write. Full Understanding Report (assumptions, openQuestions, outOfScope, risks, verificationPlan). Push-back is encouraged.";
|
|
934
|
-
case "strict":
|
|
935
|
-
return "high friction. The gate fires on every prompt. Report MUST include verificationPlan and outOfScope; requiresHumanApproval is forced to true.";
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
function buildInstructions(pack, mode, runtime) {
|
|
939
|
-
const description = pack.description?.trim() ?? "";
|
|
940
|
-
const isCodex = runtime === "codex";
|
|
941
|
-
const isOpencode = runtime === "opencode";
|
|
942
|
-
const injectorCmd = isCodex
|
|
943
|
-
? COMMAND_USER_PROMPT_SUBMIT_CODEX
|
|
944
|
-
: BIN_USER_PROMPT_SUBMIT_CLAUDE;
|
|
945
|
-
const stopCmd = isCodex ? COMMAND_STOP_CODEX : BIN_STOP_CLAUDE;
|
|
946
|
-
const blockerCmd = isCodex
|
|
947
|
-
? COMMAND_PRE_TOOL_USE_CODEX
|
|
948
|
-
: PRE_TOOL_USE_COMMAND_CLAUDE;
|
|
949
|
-
const blockerMatch = isCodex
|
|
950
|
-
? PRE_TOOL_USE_MATCH_CODEX
|
|
951
|
-
: PRE_TOOL_USE_MATCH_CLAUDE;
|
|
952
|
-
const settingsArtefact = isCodex
|
|
953
|
-
? "`harness.generated/codex/config.toml`"
|
|
954
|
-
: "harness-managed `settings.json`";
|
|
955
|
-
// HIGH-F1 (batch18 fix-round, task f34eb233): before this, opencode
|
|
956
|
-
// fell through to the claude-code `else` branch above (buildHooks
|
|
957
|
-
// does the same) and the "## Effect" text below claimed hooks were
|
|
958
|
-
// wired into `settings.json` even though opencode has no declarative
|
|
959
|
-
// hook/event field and `harness apply --runtime opencode` never
|
|
960
|
-
// projects `hooks[]` into the generated opencode artefact (see
|
|
961
|
-
// runtime.ts's header). Mirrors post-merge-gate.ts's "## Runtime"
|
|
962
|
-
// UNSUPPORTED marker.
|
|
963
|
-
const runtimeUnsupportedNote = isOpencode
|
|
964
|
-
? " (UNSUPPORTED — opencode has no declarative hook/event wiring; this pack's hooks are not projected into any opencode artefact)"
|
|
965
|
-
: "";
|
|
966
|
-
const wiringSentence = isOpencode
|
|
967
|
-
? "This pack's hooks are **not wired** under `--runtime opencode`: opencode has no declarative hook/event field (only a JS/TS plugin API), and `harness apply --runtime opencode` never projects `hooks[]` into the generated opencode artefact. The mechanics below describe the Claude Code / Codex behavior this pack implements; none of it fires today under opencode."
|
|
968
|
-
: `While this pack is enabled, hooks are wired into the ${settingsArtefact}:`;
|
|
969
|
-
const stopBullet = `2. \`Stop\` capture (\`${stopCmd}\`): persists the emitted Understanding
|
|
970
|
-
Report under \`.understanding-gate/reports/\` for audit and downstream
|
|
971
|
-
approval consumption.
|
|
972
|
-
`;
|
|
973
|
-
const blockerOrdinal = "3";
|
|
974
|
-
return `# Policy Pack: ${PACK_NAME}
|
|
975
|
-
|
|
976
|
-
> Operator audit copy. The agent-facing prompt is injected at runtime by
|
|
977
|
-
> the \`${injectorCmd}\` UserPromptSubmit hook; that text lives
|
|
978
|
-
> in the \`@lannguyensi/understanding-gate\` package, not here. This file
|
|
979
|
-
> records WHAT the pack is doing and HOW it is configured so that
|
|
980
|
-
> \`harness diff --since-apply\` can flag operator-facing drift.
|
|
981
|
-
|
|
982
|
-
## Runtime
|
|
983
|
-
|
|
984
|
-
${runtime}${runtimeUnsupportedNote}
|
|
985
|
-
|
|
986
|
-
## Mode
|
|
987
|
-
|
|
988
|
-
${mode}
|
|
989
|
-
|
|
990
|
-
${modeFriction(mode)}
|
|
991
|
-
|
|
992
|
-
## Effect
|
|
993
|
-
|
|
994
|
-
${wiringSentence}
|
|
995
|
-
|
|
996
|
-
1. \`UserPromptSubmit\` injector (\`${injectorCmd}\`): inserts the
|
|
997
|
-
Understanding-Gate instruction template into the agent's first response.
|
|
998
|
-
${stopBullet}${blockerOrdinal}. \`PreToolUse\` blocker (\`${blockerCmd}\`, blocking: hard)
|
|
999
|
-
on \`${blockerMatch}\`: refuses the tool call until the operator has
|
|
1000
|
-
approved the session's report. Opens ONLY on the HMAC-signed approval
|
|
1001
|
-
marker under \`harness.generated/.approvals/\` written by
|
|
1002
|
-
\`harness approve understanding\`; the persisted JSON report under
|
|
1003
|
-
\`.understanding-gate/reports/\` and the evidence-ledger tag
|
|
1004
|
-
(\`understanding-approved:\${SESSION_ID}\`) are audit evidence and
|
|
1005
|
-
never open the gate on their own (task 7402301d).
|
|
1006
|
-
|
|
1007
|
-
## Approval
|
|
1008
|
-
|
|
1009
|
-
The standalone blocker shipped in \`@lannguyensi/understanding-gate@>=0.2.0\`
|
|
1010
|
-
checks the persisted JSON report's \`approvalStatus\`. Phase 6 #4 will
|
|
1011
|
-
add a harness-side blocker that ALSO consults the evidence-ledger tag
|
|
1012
|
-
\`understanding-approved:\${SESSION_ID}\` (canonical for harnessed
|
|
1013
|
-
sessions), and \`harness approve understanding\` will round-trip both.
|
|
1014
|
-
Until then, approval flows through the package's own CLI.
|
|
1015
|
-
|
|
1016
|
-
## Pack metadata
|
|
1017
|
-
${description ? `\n> ${description.replace(/\n/g, "\n> ")}\n` : ""}
|
|
1018
|
-
- Source: \`builtin\`
|
|
1019
|
-
- Pack: \`${PACK_NAME}\`
|
|
1020
|
-
- Mode: \`${mode}\`
|
|
1021
|
-
- Runtime: \`${runtime}\`
|
|
1022
|
-
|
|
1023
|
-
## See also
|
|
1024
|
-
|
|
1025
|
-
- \`docs/policy-packs/understanding-before-execution.md\` (full reference)
|
|
1026
|
-
- \`docs/ROADMAP.md\` Phase 6 sub-task decomposition
|
|
1027
|
-
`;
|
|
1028
|
-
}
|
|
1029
|
-
function resolvePermissionProfile(pack) {
|
|
1030
|
-
const raw = pack.config["permission_profile"];
|
|
1031
|
-
if (raw === undefined)
|
|
1032
|
-
return { permissions: null, warning: null };
|
|
1033
|
-
if (typeof raw !== "string") {
|
|
1034
|
-
return {
|
|
1035
|
-
permissions: null,
|
|
1036
|
-
warning: `policy_packs[${pack.name}].config.permission_profile: expected a string, got ${typeof raw}; skipping permission contribution.`,
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
if (!isKnownProfileName(raw)) {
|
|
1040
|
-
return {
|
|
1041
|
-
permissions: null,
|
|
1042
|
-
warning: `policy_packs[${pack.name}].config.permission_profile: unrecognised profile ${JSON.stringify(raw)}. Allowed: ${KNOWN_PROFILE_NAMES.join(", ")}. Skipping permission contribution.`,
|
|
1043
|
-
};
|
|
1044
|
-
}
|
|
1045
|
-
const profile = resolveProfile(raw);
|
|
1046
|
-
if (!profile)
|
|
1047
|
-
return { permissions: null, warning: null };
|
|
1048
|
-
return { permissions: profileToSettingsPermissions(profile), warning: null };
|
|
1049
|
-
}
|
|
1050
|
-
export function resolve(pack, runtime = DEFAULT_RUNTIME, opts = {}) {
|
|
1051
|
-
// GENERATION path (task 5d73d78d review HIGH-3): config-only, no env —
|
|
1052
|
-
// see {@link MODE_ENV}'s doc comment for why apply-time artefacts must
|
|
1053
|
-
// not depend on the live process environment.
|
|
1054
|
-
const { mode, warning } = resolveModeFromConfig(pack);
|
|
1055
|
-
const hooks = buildHooks(runtime, pack, mode, opts);
|
|
1056
|
-
const instructionsContent = buildInstructions(pack, mode, runtime);
|
|
1057
|
-
const files = [
|
|
1058
|
-
{
|
|
1059
|
-
relativePath: `policy-packs/${PACK_NAME}/instructions.md`,
|
|
1060
|
-
content: instructionsContent,
|
|
1061
|
-
},
|
|
1062
|
-
];
|
|
1063
|
-
const warnings = [];
|
|
1064
|
-
if (warning)
|
|
1065
|
-
warnings.push(warning);
|
|
1066
|
-
const profileResult = resolvePermissionProfile(pack);
|
|
1067
|
-
if (profileResult.warning)
|
|
1068
|
-
warnings.push(profileResult.warning);
|
|
1069
|
-
const contribution = { hooks, files };
|
|
1070
|
-
if (profileResult.permissions)
|
|
1071
|
-
contribution.permissions = profileResult.permissions;
|
|
1072
|
-
return { contribution, warnings };
|
|
1073
|
-
}
|
|
1074
|
-
//# sourceMappingURL=understanding-before-execution.js.map
|