@lannguyensi/harness 0.14.0 → 0.16.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.
Files changed (83) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +20 -2
  3. package/dist/cli/doctor/format.js +24 -0
  4. package/dist/cli/doctor/format.js.map +1 -1
  5. package/dist/cli/doctor/index.d.ts +7 -0
  6. package/dist/cli/doctor/index.js +10 -0
  7. package/dist/cli/doctor/index.js.map +1 -1
  8. package/dist/cli/doctor/rogue-ledger.d.ts +25 -0
  9. package/dist/cli/doctor/rogue-ledger.js +106 -0
  10. package/dist/cli/doctor/rogue-ledger.js.map +1 -0
  11. package/dist/cli/doctor/types.d.ts +10 -1
  12. package/dist/cli/doctor/types.js.map +1 -1
  13. package/dist/cli/index.js +177 -0
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/init/composer.d.ts +29 -0
  16. package/dist/cli/init/composer.js +377 -0
  17. package/dist/cli/init/composer.js.map +1 -0
  18. package/dist/cli/init/dependencies.d.ts +25 -0
  19. package/dist/cli/init/dependencies.js +100 -10
  20. package/dist/cli/init/dependencies.js.map +1 -1
  21. package/dist/cli/init/index.d.ts +18 -1
  22. package/dist/cli/init/index.js +17 -7
  23. package/dist/cli/init/index.js.map +1 -1
  24. package/dist/cli/init/interactive.d.ts +31 -2
  25. package/dist/cli/init/interactive.js +321 -79
  26. package/dist/cli/init/interactive.js.map +1 -1
  27. package/dist/cli/init/templates.d.ts +1 -1
  28. package/dist/cli/init/templates.js +60 -9
  29. package/dist/cli/init/templates.js.map +1 -1
  30. package/dist/cli/pack/hook-branch-protection.d.ts +30 -0
  31. package/dist/cli/pack/hook-branch-protection.js +279 -0
  32. package/dist/cli/pack/hook-branch-protection.js.map +1 -0
  33. package/dist/cli/pack/hook-codex-pre-tool-use.js +3 -1
  34. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
  35. package/dist/cli/pack/hook-pre-tool-use.d.ts +1 -1
  36. package/dist/cli/pack/hook-pre-tool-use.js +42 -3
  37. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  38. package/dist/cli/pack/understanding-report-schema-hint.d.ts +13 -0
  39. package/dist/cli/pack/understanding-report-schema-hint.js +54 -0
  40. package/dist/cli/pack/understanding-report-schema-hint.js.map +1 -0
  41. package/dist/cli/session-start/branch-check.d.ts +44 -0
  42. package/dist/cli/session-start/branch-check.js +165 -0
  43. package/dist/cli/session-start/branch-check.js.map +1 -0
  44. package/dist/cli/uninstall/index.d.ts +68 -0
  45. package/dist/cli/uninstall/index.js +586 -0
  46. package/dist/cli/uninstall/index.js.map +1 -0
  47. package/dist/cli/uninstall/snapshot.d.ts +40 -0
  48. package/dist/cli/uninstall/snapshot.js +34 -0
  49. package/dist/cli/uninstall/snapshot.js.map +1 -0
  50. package/dist/cli/validate/checks.d.ts +1 -1
  51. package/dist/cli/validate/checks.js +1 -7
  52. package/dist/cli/validate/checks.js.map +1 -1
  53. package/dist/io/harness-lock.js +1 -9
  54. package/dist/io/harness-lock.js.map +1 -1
  55. package/dist/policies/ledger-client.js +3 -9
  56. package/dist/policies/ledger-client.js.map +1 -1
  57. package/dist/policies/producers.d.ts +12 -0
  58. package/dist/policies/producers.js +61 -0
  59. package/dist/policies/producers.js.map +1 -0
  60. package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +47 -0
  61. package/dist/policy-packs/builtin/branch-protection-runtime.js +92 -0
  62. package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -0
  63. package/dist/policy-packs/builtin/branch-protection.d.ts +9 -0
  64. package/dist/policy-packs/builtin/branch-protection.js +146 -0
  65. package/dist/policy-packs/builtin/branch-protection.js.map +1 -0
  66. package/dist/policy-packs/registry.d.ts +1 -1
  67. package/dist/policy-packs/registry.js +10 -3
  68. package/dist/policy-packs/registry.js.map +1 -1
  69. package/dist/runtime/expand-home.d.ts +14 -0
  70. package/dist/runtime/expand-home.js +54 -0
  71. package/dist/runtime/expand-home.js.map +1 -0
  72. package/dist/runtime/intercept.js +13 -2
  73. package/dist/runtime/intercept.js.map +1 -1
  74. package/dist/runtime/ledger-add.js +10 -3
  75. package/dist/runtime/ledger-add.js.map +1 -1
  76. package/dist/runtime/ledger-record.js +11 -10
  77. package/dist/runtime/ledger-record.js.map +1 -1
  78. package/dist/schema/index.d.ts +281 -101
  79. package/dist/schema/permission-profiles.d.ts +125 -125
  80. package/dist/schema/policies.d.ts +261 -0
  81. package/dist/schema/policies.js +50 -0
  82. package/dist/schema/policies.js.map +1 -1
  83. package/package.json +2 -1
@@ -1,4 +1,4 @@
1
1
  export declare const MINIMAL_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template minimal`.\n#\n# This is the empty-but-valid manifest. Run `harness validate` to confirm it\n# parses, then add entries under the five top-level keys:\n#\n# grounding: evidence-ledger + claim-gate config (see docs/ARCHITECTURE.md \u00A72)\n# tools: mcp / cli / skills / builtin inventory (\u00A73)\n# memory: directories, retention, scopes (\u00A74)\n# hooks: event-bound shell commands (\u00A75)\n# policies: named rules that bind hooks to triggers (\u00A76)\n#\n# Phase 2 verbs to add entries safely: `harness add mcp <name> ...`,\n# `harness add cli`, `harness add hook`, `harness add skill`.\n# Per-machine overrides live at ~/.claude/machines/<discriminator>.harness.overrides.yaml\n# (ARCHITECTURE.md \u00A78) for paths that vary per host.\n#\n# Docs: https://github.com/LanNguyenSi/harness\n\nversion: 1\n";
2
- export declare const FULL_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template full`. The reference manifest:\n# every example policy from docs/examples/full-manifest.yaml wired through\n# the generic `harness policy intercept` engine, so no external shell\n# scripts under ~/.claude/hooks/ are required.\n#\n# Canonical source for the policy + policy_packs sections is\n# docs/examples/full-manifest.yaml. A parity vitest\n# (tests/cli/init-full-template-parity.test.ts) fails the build if the\n# two diverge on policy names or load-bearing fields.\n#\n# What you still need on PATH (the wizard offers to `npm i -g` these on\n# init): agent-tasks-mcp-bridge, grounding-mcp, memory-router-*,\n# understanding-gate-claude-*. Optional add-on: a local codebase-oracle\n# MCP server (see comment under tools.mcp below).\n\nversion: 1\n\ngrounding:\n session:\n auto_start: true\n id_format: \"gs-{repo}-{rand:8}\"\n evidence_ledger:\n path: ~/.evidence-ledger/ledger.db\n retention_days: 90\n policies_source: ~/.claude/harness.d/policies/claim-gate.yaml\n\ntools:\n mcp:\n # codebase-oracle (the Pandora RAG MCP server) is intentionally NOT\n # in this default. The npm name `codebase-oracle` is already taken\n # by an unrelated CLI, and the Pandora variant is not yet published\n # under a non-colliding scope. Operators who run from a local\n # checkout can add it back with (note: `harness add` splits the\n # command on commas, not whitespace):\n # harness add mcp codebase-oracle \\\n # --command 'npx,tsx,~/git/pandora/codebase-oracle/src/mcp-server.ts'\n - name: agent-tasks\n # Zero-setup entry: `@agent-tasks/mcp-bridge` exposes the\n # `agent-tasks-mcp-bridge` binary on PATH. The bridge owns token\n # storage and defaults to the hosted backend; override with\n # `AGENT_TASKS_BASE_URL` / `AGENT_TASKS_TOKEN` for self-hosted.\n # `min_version` floor: 0.6.0 added the `--version` short-circuit\n # the doctor probe needs (PR agent-tasks/240, release-cut PR 241).\n # Bump the floor whenever a fix you depend on lands; loose floors\n # are fine, the point is the drift signal not pinning a specific cut.\n command: [agent-tasks-mcp-bridge]\n min_version: \"0.6.0\"\n health:\n verb: projects_list\n timeout_ms: 5000\n enabled: true\n - name: grounding-mcp\n # Published bin from `@lannguyensi/grounding-mcp`. No env is set:\n # the bundled default resolves to `~/.evidence-ledger/ledger.db`\n # via os.homedir() at startup. Passing a literal tilde in env\n # bypasses shell expansion and creates rogue cwd-relative DB files\n # (see agent-tasks/42d224a6 incident). `min_version` floor: 0.2.0\n # added the `--version` short-circuit the doctor probe needs (PR\n # agent-grounding/76, release-cut PR 77).\n command: [grounding-mcp]\n min_version: \"0.2.0\"\n health:\n verb: ledger_status\n timeout_ms: 5000\n enabled: true\n\n cli:\n - name: gh\n binary: gh\n required: true\n\n skills:\n enabled:\n - simplify\n - init\n - review\n - security-review\n source_dirs:\n - ~/.claude/skills\n\n builtin:\n known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate, Glob, Grep]\n\nmemory:\n directories:\n - path: ~/.claude/projects/{project}/memory\n scope: project\n router:\n # Published bin from `@lannguyensi/memory-router`.\n # `min_version` floor: 0.3.0 added the `--version` short-circuit\n # the doctor probe needs (PR agent-memory/40, release-cut PR 41).\n command: [memory-router-user-prompt-submit]\n min_version: \"0.3.0\"\n enabled: true\n retention:\n staleness_days: 180\n broken_refs: warn\n scopes:\n default: project\n allowed: [project, user]\n\n# All PreToolUse hooks share the generic `harness policy intercept` CLI\n# entrypoint. The engine reads the tool event on stdin, evaluates whichever\n# policy below has a matching trigger (`match` + optional `bash_match`),\n# and emits Claude Code's deny envelope when the required ledger tag is\n# absent. No external shell scripts are required.\n#\n# The `git-preflight` SessionStart hook is the producer side of the\n# `preflight-before-*` policies: `harness session-start preflight` runs\n# agent-preflight against the session cwd and, on a ready:true result,\n# records `preflight:${REPO}` to the evidence ledger. It needs the\n# `preflight` binary on PATH (`npm i -g @lannguyensi/agent-preflight`); when\n# that is absent the hook logs to stderr and exits 0, so the session is\n# never broken \u2014 the preflight gates just stay closed until a tag is\n# produced some other way.\nhooks:\n - name: git-preflight\n event: SessionStart\n command: harness session-start preflight\n blocking: false\n budget_ms: 30000\n\n - name: require-review-evidence\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\n - name: require-dogfood-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*(npm publish\\b|git( -C \\S+)* tag v)'\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\n - name: require-preflight-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* (status|log|diff|branch)\\b'\n command: harness policy intercept\n blocking: hard\n budget_ms: 1000\n\n - name: require-review-subagent-evidence\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_create\"\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\n - name: require-preflight-push-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* push\\b'\n command: harness policy intercept\n blocking: hard\n budget_ms: 1000\n\npolicies:\n - name: review-before-merge\n description: Block PR merges unless a ledger entry tagged review:<pr-number> exists for this session.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n extract:\n PR_NUMBER: \"toolArgs.prNumber\"\n requires:\n ledger_tag: \"review:${PR_NUMBER}\"\n hook: require-review-evidence\n enforcement: block\n\n - name: dogfood-before-release\n description: Block npm publish / git tag v* without a recent dogfood ledger entry.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*(npm publish\\b|git( -C \\S+)* tag v)'\n requires:\n ledger_tag: \"dogfood:${SESSION_ID}\"\n within: 24h\n hook: require-dogfood-evidence\n enforcement: block\n\n - name: two-reviewers-required\n description: At least two distinct reviewer ledger entries must exist for the PR.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n extract:\n PR_NUMBER: \"toolArgs.prNumber\"\n requires:\n ledger_tag: \"review:${PR_NUMBER}\"\n count:\n min: 2\n hook: require-review-evidence\n enforcement: warn\n\n - name: preflight-before-investigation\n description: Block investigative git reads (status/log/diff/branch) when agent-preflight has not run recently with ready:true for the current repo.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* (status|log|diff|branch)\\b'\n requires:\n ledger_tag: \"preflight:${REPO}\"\n within: 1h\n hook: require-preflight-evidence\n enforcement: block\n\n - name: review-subagent-before-pr-create\n description: Block agent-tasks PR creation unless a review-subagent ledger entry tagged for this task already exists. Forces the rigorous review BEFORE the PR opens, not after.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_create\"\n extract:\n TASK_ID: \"toolArgs.taskId\"\n requires:\n ledger_tag: \"review-subagent:${TASK_ID}\"\n hook: require-review-subagent-evidence\n enforcement: block\n\n - name: preflight-before-push\n description: Block git push unless a fresh preflight ledger entry exists for the current branch. Catches the stale-checkout class of incident at the last reversible step.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* push\\b'\n requires:\n ledger_tag: \"preflight:${BRANCH}\"\n within: 10m\n hook: require-preflight-push-evidence\n enforcement: block\n\n# Full inherits the Solo/Team understanding-gate stack: the Stop hook\n# persists each Understanding Report and the PreToolUse pre-tool-use\n# blocker refuses Edit/Write/Bash until the report is approved. Drop\n# this block if you want the reference policies above without the\n# baseline gate.\npolicy_packs:\n - name: understanding-before-execution\n source: builtin\n enabled: true\n description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.\n config:\n mode: grill_me\n";
2
+ export declare const FULL_TEMPLATE = "# ~/.claude/harness.yaml\n#\n# Bootstrapped by `harness init --template full`. The reference manifest:\n# every example policy from docs/examples/full-manifest.yaml wired through\n# the generic `harness policy intercept` engine, so no external shell\n# scripts under ~/.claude/hooks/ are required.\n#\n# Canonical source for the policy + policy_packs sections is\n# docs/examples/full-manifest.yaml. A parity vitest\n# (tests/cli/init-full-template-parity.test.ts) fails the build if the\n# two diverge on policy names or load-bearing fields.\n#\n# What you still need on PATH (the wizard offers to `npm i -g` these on\n# init): agent-tasks-mcp-bridge, grounding-mcp, memory-router-*,\n# understanding-gate-claude-*.\n\nversion: 1\n\ngrounding:\n session:\n auto_start: true\n id_format: \"gs-{repo}-{rand:8}\"\n evidence_ledger:\n path: ~/.evidence-ledger/ledger.db\n retention_days: 90\n policies_source: ~/.claude/harness.d/policies/claim-gate.yaml\n\ntools:\n mcp:\n # codebase-oracle (the Pandora RAG MCP server) is intentionally NOT\n # in the Full default. It is published as\n # `@lannguyensi/codebase-oracle` and works fine standalone, but it\n # is an opinionated workflow add-on (multi-repo semantic search)\n # rather than infrastructure harness itself assumes. Operators who\n # want it wire it explicitly:\n # npm i -g @lannguyensi/codebase-oracle\n # harness add mcp codebase-oracle --command codebase-oracle,mcp\n # Set ORACLE_SCAN_ROOT (absolute path; tilde is not expanded by the\n # MCP env block) and OPENAI_API_KEY (or switch providers via\n # ORACLE_LLM_PROVIDER) before the first call.\n - name: agent-tasks\n # Zero-setup entry: `@agent-tasks/mcp-bridge` exposes the\n # `agent-tasks-mcp-bridge` binary on PATH. The bridge owns token\n # storage and defaults to the hosted backend; override with\n # `AGENT_TASKS_BASE_URL` / `AGENT_TASKS_TOKEN` for self-hosted.\n # `min_version` floor: 0.6.0 added the `--version` short-circuit\n # the doctor probe needs (PR agent-tasks/240, release-cut PR 241).\n # Bump the floor whenever a fix you depend on lands; loose floors\n # are fine, the point is the drift signal not pinning a specific cut.\n command: [agent-tasks-mcp-bridge]\n min_version: \"0.6.0\"\n health:\n verb: projects_list\n timeout_ms: 5000\n enabled: true\n - name: grounding-mcp\n # Published bin from `@lannguyensi/grounding-mcp`. No env is set:\n # the bundled default resolves to `~/.evidence-ledger/ledger.db`\n # via os.homedir() at startup. Passing a literal tilde in env\n # bypasses shell expansion and creates rogue cwd-relative DB files\n # (see agent-tasks/42d224a6 incident). `min_version` floor: 0.2.0\n # added the `--version` short-circuit the doctor probe needs (PR\n # agent-grounding/76, release-cut PR 77).\n command: [grounding-mcp]\n min_version: \"0.2.0\"\n health:\n verb: ledger_status\n timeout_ms: 5000\n enabled: true\n\n cli:\n - name: gh\n binary: gh\n required: true\n\n skills:\n enabled:\n - simplify\n - init\n - review\n - security-review\n source_dirs:\n - ~/.claude/skills\n\n builtin:\n known: [Read, Edit, Write, Bash, Agent, Skill, TaskCreate, Glob, Grep]\n\nmemory:\n directories:\n - path: ~/.claude/projects/{project}/memory\n scope: project\n router:\n # Published bin from `@lannguyensi/memory-router`.\n # `min_version` floor: 0.3.0 added the `--version` short-circuit\n # the doctor probe needs (PR agent-memory/40, release-cut PR 41).\n command: [memory-router-user-prompt-submit]\n min_version: \"0.3.0\"\n enabled: true\n retention:\n staleness_days: 180\n broken_refs: warn\n scopes:\n default: project\n allowed: [project, user]\n\n# All PreToolUse hooks share the generic `harness policy intercept` CLI\n# entrypoint. The engine reads the tool event on stdin, evaluates whichever\n# policy below has a matching trigger (`match` + optional `bash_match`),\n# and emits Claude Code's deny envelope when the required ledger tag is\n# absent. No external shell scripts are required.\n#\n# The `git-preflight` SessionStart hook is the producer side of the\n# `preflight-before-*` policies: `harness session-start preflight` runs\n# agent-preflight against the session cwd and, on a ready:true result,\n# records `preflight:${REPO}` to the evidence ledger. It needs the\n# `preflight` binary on PATH (`npm i -g @lannguyensi/agent-preflight`); when\n# that is absent the hook logs to stderr and exits 0, so the session is\n# never broken \u2014 the preflight gates just stay closed until a tag is\n# produced some other way.\nhooks:\n - name: git-preflight\n event: SessionStart\n command: harness session-start preflight\n blocking: false\n budget_ms: 30000\n\n - name: require-review-evidence\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\n - name: require-dogfood-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*(npm publish\\b|git( -C \\S+)* tag v)'\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\n - name: require-preflight-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* (status|log|diff|branch)\\b'\n command: harness policy intercept\n blocking: hard\n budget_ms: 1000\n\n - name: require-review-subagent-evidence\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_create\"\n command: harness policy intercept\n blocking: hard\n budget_ms: 2000\n\n - name: require-preflight-push-evidence\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* push\\b'\n command: harness policy intercept\n blocking: hard\n budget_ms: 1000\n\npolicies:\n - name: review-before-merge\n description: Block PR merges unless a ledger entry tagged review:<pr-number> exists for this session.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n extract:\n PR_NUMBER: \"toolArgs.prNumber\"\n requires:\n ledger_tag: \"review:${PR_NUMBER}\"\n hook: require-review-evidence\n enforcement: block\n producers:\n - kind: mcp\n verb: mcp__agent-grounding__ledger_add\n example: '{type:\"fact\", content:\"review:${PR_NUMBER} \u2014 <verdict + key findings + nits>\", source:\"Agent(general-purpose) review\"}'\n description: Spawn a review subagent against the PR diff, capture its verdict, then persist a ledger entry tagged with the PR number. The content should be self-contained enough for an auditor to read without re-opening the chat.\n\n - name: dogfood-before-release\n description: Block npm publish / git tag v* without a recent dogfood ledger entry.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*(npm publish\\b|git( -C \\S+)* tag v)'\n requires:\n ledger_tag: \"dogfood:${SESSION_ID}\"\n within: 24h\n hook: require-dogfood-evidence\n enforcement: block\n producers:\n - kind: mcp\n verb: mcp__agent-grounding__ledger_add\n example: '{type:\"fact\", content:\"dogfood:${SESSION_ID} \u2014 <end-to-end smoke summary against the live system>\", source:\"manual smoke test\"}'\n description: Before tagging or publishing, run the release path end-to-end against the live system (not just unit tests) and persist the result as a session-tagged ledger entry. Document what you exercised (install, CLI happy path, MCP handshake, etc.) so a future auditor can tell whether the smoke covered the change.\n\n - name: two-reviewers-required\n description: At least two distinct reviewer ledger entries must exist for the PR.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_merge\"\n extract:\n PR_NUMBER: \"toolArgs.prNumber\"\n requires:\n ledger_tag: \"review:${PR_NUMBER}\"\n count:\n min: 2\n hook: require-review-evidence\n enforcement: warn\n producers:\n - kind: mcp\n verb: mcp__agent-grounding__ledger_add\n example: '{type:\"fact\", content:\"review:${PR_NUMBER} \u2014 <verdict + key findings + nits>\", source:\"Agent(general-purpose) review (reviewer 2)\"}'\n description: Same shape as review-before-merge but TWO DISTINCT reviewer entries must exist before the gate is satisfied (count.min 2). Distinguish reviewers by source so the count is honest. Warn-level enforcement, so the agent CAN merge with one reviewer but should consider spawning a second for load-bearing changes.\n\n - name: preflight-before-investigation\n description: Block investigative git reads (status/log/diff/branch) when agent-preflight has not run recently with ready:true for the current repo.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* (status|log|diff|branch)\\b'\n requires:\n ledger_tag: \"preflight:${REPO}\"\n within: 1h\n hook: require-preflight-evidence\n enforcement: block\n producers:\n - kind: bash\n command: harness session-start preflight\n description: Runs agent-preflight against the current cwd; on ready:true, records preflight:${REPO} to the ledger. Standard producer.\n - kind: mcp\n verb: mcp__agent-grounding__ledger_add\n example: '{type:\"fact\", content:\"preflight:${REPO}\", source:\"manual\"}'\n description: Direct ledger write. Use when the Bash hook is locked down (e.g. understanding-gate active) or when the standard producer is unavailable.\n\n - name: review-subagent-before-pr-create\n description: Block agent-tasks PR creation unless a review-subagent ledger entry tagged for this task already exists. Forces the rigorous review BEFORE the PR opens, not after.\n trigger:\n event: PreToolUse\n match: \"mcp__agent-tasks__pull_requests_create\"\n extract:\n TASK_ID: \"toolArgs.taskId\"\n requires:\n ledger_tag: \"review-subagent:${TASK_ID}\"\n hook: require-review-subagent-evidence\n enforcement: block\n producers:\n - kind: mcp\n verb: mcp__agent-grounding__ledger_add\n example: '{type:\"fact\", content:\"review-subagent:${TASK_ID} \u2014 <verdict + key findings + nits>\", source:\"Agent(general-purpose) review\"}'\n description: After running a review subagent against the staged diff, persist its verdict + load-bearing findings as a ledger entry tagged with the task UUID. The content should be self-contained enough to audit later without re-reading the chat.\n\n - name: preflight-before-push\n description: Block git push unless a fresh preflight ledger entry exists for the current branch. Catches the stale-checkout class of incident at the last reversible step.\n trigger:\n event: PreToolUse\n match: \"Bash\"\n bash_match: '(^|\\n|;|\\||&&|\\()\\s*(\\w+=\\S+\\s+)*git( -C \\S+)* push\\b'\n requires:\n ledger_tag: \"preflight:${BRANCH}\"\n within: 10m\n hook: require-preflight-push-evidence\n enforcement: block\n producers:\n - kind: bash\n command: harness session-start preflight\n description: Runs agent-preflight against the current cwd; on ready:true, records preflight:${BRANCH} to the ledger. Standard producer.\n - kind: mcp\n verb: mcp__agent-grounding__ledger_add\n example: '{type:\"fact\", content:\"preflight:${BRANCH} \u2014 <summary of what is on the branch + smoke results>\", source:\"manual\"}'\n description: Direct ledger write. The branch is the WIP review surface; the content should summarise what is staged + the smoke evidence so a reviewer can audit later without re-reading the chat.\n\n# Full inherits the Solo/Team understanding-gate stack: the Stop hook\n# persists each Understanding Report and the PreToolUse pre-tool-use\n# blocker refuses Edit/Write/Bash until the report is approved. Drop\n# this block if you want the reference policies above without the\n# baseline gate.\npolicy_packs:\n - name: understanding-before-execution\n source: builtin\n enabled: true\n description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.\n config:\n mode: grill_me\n # Producers (agent-tasks/25bced52): rendered into the gate's deny\n # envelope by the same engine as policy producers. Constraint at\n # this layer: at-least-one `ask`. Post-v0.14.0 the gate signal\n # is a filesystem marker and the mcp ledger_add path no longer\n # satisfies the gate; the canonical unblock surface is the\n # operator-approval prompt.\n producers:\n - kind: ask\n command: harness approve understanding\n 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.\"\n - kind: bash\n command: harness approve understanding\n 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}.\n";
3
3
  export type TemplateName = "minimal" | "full" | "solo" | "team";
4
4
  export declare function getTemplate(name: TemplateName): string;
@@ -34,8 +34,7 @@ export const FULL_TEMPLATE = `# ~/.claude/harness.yaml
34
34
  #
35
35
  # What you still need on PATH (the wizard offers to \`npm i -g\` these on
36
36
  # init): agent-tasks-mcp-bridge, grounding-mcp, memory-router-*,
37
- # understanding-gate-claude-*. Optional add-on: a local codebase-oracle
38
- # MCP server (see comment under tools.mcp below).
37
+ # understanding-gate-claude-*.
39
38
 
40
39
  version: 1
41
40
 
@@ -51,13 +50,16 @@ grounding:
51
50
  tools:
52
51
  mcp:
53
52
  # codebase-oracle (the Pandora RAG MCP server) is intentionally NOT
54
- # in this default. The npm name \`codebase-oracle\` is already taken
55
- # by an unrelated CLI, and the Pandora variant is not yet published
56
- # under a non-colliding scope. Operators who run from a local
57
- # checkout can add it back with (note: \`harness add\` splits the
58
- # command on commas, not whitespace):
59
- # harness add mcp codebase-oracle \\
60
- # --command 'npx,tsx,~/git/pandora/codebase-oracle/src/mcp-server.ts'
53
+ # in the Full default. It is published as
54
+ # \`@lannguyensi/codebase-oracle\` and works fine standalone, but it
55
+ # is an opinionated workflow add-on (multi-repo semantic search)
56
+ # rather than infrastructure harness itself assumes. Operators who
57
+ # want it wire it explicitly:
58
+ # npm i -g @lannguyensi/codebase-oracle
59
+ # harness add mcp codebase-oracle --command codebase-oracle,mcp
60
+ # Set ORACLE_SCAN_ROOT (absolute path; tilde is not expanded by the
61
+ # MCP env block) and OPENAI_API_KEY (or switch providers via
62
+ # ORACLE_LLM_PROVIDER) before the first call.
61
63
  - name: agent-tasks
62
64
  # Zero-setup entry: \`@agent-tasks/mcp-bridge\` exposes the
63
65
  # \`agent-tasks-mcp-bridge\` binary on PATH. The bridge owns token
@@ -194,6 +196,11 @@ policies:
194
196
  ledger_tag: "review:\${PR_NUMBER}"
195
197
  hook: require-review-evidence
196
198
  enforcement: block
199
+ producers:
200
+ - kind: mcp
201
+ verb: mcp__agent-grounding__ledger_add
202
+ example: '{type:"fact", content:"review:\${PR_NUMBER} — <verdict + key findings + nits>", source:"Agent(general-purpose) review"}'
203
+ description: Spawn a review subagent against the PR diff, capture its verdict, then persist a ledger entry tagged with the PR number. The content should be self-contained enough for an auditor to read without re-opening the chat.
197
204
 
198
205
  - name: dogfood-before-release
199
206
  description: Block npm publish / git tag v* without a recent dogfood ledger entry.
@@ -206,6 +213,11 @@ policies:
206
213
  within: 24h
207
214
  hook: require-dogfood-evidence
208
215
  enforcement: block
216
+ producers:
217
+ - kind: mcp
218
+ verb: mcp__agent-grounding__ledger_add
219
+ example: '{type:"fact", content:"dogfood:\${SESSION_ID} — <end-to-end smoke summary against the live system>", source:"manual smoke test"}'
220
+ description: Before tagging or publishing, run the release path end-to-end against the live system (not just unit tests) and persist the result as a session-tagged ledger entry. Document what you exercised (install, CLI happy path, MCP handshake, etc.) so a future auditor can tell whether the smoke covered the change.
209
221
 
210
222
  - name: two-reviewers-required
211
223
  description: At least two distinct reviewer ledger entries must exist for the PR.
@@ -220,6 +232,11 @@ policies:
220
232
  min: 2
221
233
  hook: require-review-evidence
222
234
  enforcement: warn
235
+ producers:
236
+ - kind: mcp
237
+ verb: mcp__agent-grounding__ledger_add
238
+ example: '{type:"fact", content:"review:\${PR_NUMBER} — <verdict + key findings + nits>", source:"Agent(general-purpose) review (reviewer 2)"}'
239
+ description: Same shape as review-before-merge but TWO DISTINCT reviewer entries must exist before the gate is satisfied (count.min 2). Distinguish reviewers by source so the count is honest. Warn-level enforcement, so the agent CAN merge with one reviewer but should consider spawning a second for load-bearing changes.
223
240
 
224
241
  - name: preflight-before-investigation
225
242
  description: Block investigative git reads (status/log/diff/branch) when agent-preflight has not run recently with ready:true for the current repo.
@@ -232,6 +249,14 @@ policies:
232
249
  within: 1h
233
250
  hook: require-preflight-evidence
234
251
  enforcement: block
252
+ producers:
253
+ - kind: bash
254
+ command: harness session-start preflight
255
+ description: Runs agent-preflight against the current cwd; on ready:true, records preflight:\${REPO} to the ledger. Standard producer.
256
+ - kind: mcp
257
+ verb: mcp__agent-grounding__ledger_add
258
+ example: '{type:"fact", content:"preflight:\${REPO}", source:"manual"}'
259
+ description: Direct ledger write. Use when the Bash hook is locked down (e.g. understanding-gate active) or when the standard producer is unavailable.
235
260
 
236
261
  - name: review-subagent-before-pr-create
237
262
  description: Block agent-tasks PR creation unless a review-subagent ledger entry tagged for this task already exists. Forces the rigorous review BEFORE the PR opens, not after.
@@ -244,6 +269,11 @@ policies:
244
269
  ledger_tag: "review-subagent:\${TASK_ID}"
245
270
  hook: require-review-subagent-evidence
246
271
  enforcement: block
272
+ producers:
273
+ - kind: mcp
274
+ verb: mcp__agent-grounding__ledger_add
275
+ example: '{type:"fact", content:"review-subagent:\${TASK_ID} — <verdict + key findings + nits>", source:"Agent(general-purpose) review"}'
276
+ description: After running a review subagent against the staged diff, persist its verdict + load-bearing findings as a ledger entry tagged with the task UUID. The content should be self-contained enough to audit later without re-reading the chat.
247
277
 
248
278
  - name: preflight-before-push
249
279
  description: Block git push unless a fresh preflight ledger entry exists for the current branch. Catches the stale-checkout class of incident at the last reversible step.
@@ -256,6 +286,14 @@ policies:
256
286
  within: 10m
257
287
  hook: require-preflight-push-evidence
258
288
  enforcement: block
289
+ producers:
290
+ - kind: bash
291
+ command: harness session-start preflight
292
+ description: Runs agent-preflight against the current cwd; on ready:true, records preflight:\${BRANCH} to the ledger. Standard producer.
293
+ - kind: mcp
294
+ verb: mcp__agent-grounding__ledger_add
295
+ example: '{type:"fact", content:"preflight:\${BRANCH} — <summary of what is on the branch + smoke results>", source:"manual"}'
296
+ description: Direct ledger write. The branch is the WIP review surface; the content should summarise what is staged + the smoke evidence so a reviewer can audit later without re-reading the chat.
259
297
 
260
298
  # Full inherits the Solo/Team understanding-gate stack: the Stop hook
261
299
  # persists each Understanding Report and the PreToolUse pre-tool-use
@@ -269,6 +307,19 @@ policy_packs:
269
307
  description: Force agents to expose their task interpretation and wait for explicit human approval before any write-capable tool fires.
270
308
  config:
271
309
  mode: grill_me
310
+ # Producers (agent-tasks/25bced52): rendered into the gate's deny
311
+ # envelope by the same engine as policy producers. Constraint at
312
+ # this layer: at-least-one \`ask\`. Post-v0.14.0 the gate signal
313
+ # is a filesystem marker and the mcp ledger_add path no longer
314
+ # satisfies the gate; the canonical unblock surface is the
315
+ # operator-approval prompt.
316
+ producers:
317
+ - kind: ask
318
+ command: harness approve understanding
319
+ 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."
320
+ - kind: bash
321
+ command: harness approve understanding
322
+ 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}.
272
323
  `;
273
324
  import { SOLO_TEMPLATE, TEAM_TEMPLATE } from "./profiles.js";
274
325
  export function getTemplate(name) {
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/cli/init/templates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyP5B,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI7D,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC;IAC5B,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../../src/cli/init/templates.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqB/B,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4S5B,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAI7D,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,MAAM;YACT,OAAO,aAAa,CAAC;QACvB,KAAK,SAAS;YACZ,OAAO,gBAAgB,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { type LedgerEntry } from "../../policies/index.js";
2
+ import type { Manifest } from "../../schema/index.js";
3
+ import { type LoaderOptions } from "../loader.js";
4
+ export interface PackHookBranchProtectionOptions extends LoaderOptions {
5
+ /** Defaults to process.stdin. */
6
+ stdin?: NodeJS.ReadableStream;
7
+ /** Defaults to process.stdout. */
8
+ stdout?: NodeJS.WritableStream;
9
+ /** Defaults to process.stderr. */
10
+ stderr?: NodeJS.WritableStream;
11
+ /** Override "now" for deterministic freshness-window tests. */
12
+ now?: Date;
13
+ /** Override the cwd resolution (test injection). */
14
+ cwd?: string;
15
+ /** Per-call ledger timeout in ms. */
16
+ ledgerTimeoutMs?: number;
17
+ /** Inject a manifest (test). */
18
+ manifest?: Manifest;
19
+ /** Inject a fake ledger query (test). */
20
+ ledgerQuery?: (sessionId: string) => Promise<LedgerEntry[] | {
21
+ degraded: string;
22
+ }>;
23
+ }
24
+ export interface PackHookBranchProtectionResult {
25
+ exitCode: number;
26
+ blocked: boolean;
27
+ /** Diagnostic line emitted to stderr (always, even on allow). */
28
+ diagnostic: string;
29
+ }
30
+ export declare function runPackHookBranchProtectionCli(opts?: PackHookBranchProtectionOptions): Promise<PackHookBranchProtectionResult>;
@@ -0,0 +1,279 @@
1
+ // `harness pack hook branch-protection` — PreToolUse blocker for the
2
+ // `branch-protection` policy pack.
3
+ //
4
+ // Receives Claude Code's PreToolUse event JSON on stdin and emits a
5
+ // `{ decision: "block" }` envelope when the agent is about to mutate
6
+ // source on a protected branch without a satisfying ledger tag.
7
+ //
8
+ // Two paths satisfy the gate:
9
+ //
10
+ // 1. **Producer path** — a `branch:non-protected` tag exists in the
11
+ // ledger from within the last 5 minutes (set by
12
+ // `harness session-start branch-check` when the session opened on
13
+ // a non-protected branch).
14
+ //
15
+ // 2. **Override path** — a `branch-protection-ack:` tag exists in the
16
+ // ledger (any age). The operator writes this from outside the
17
+ // gated shell via `mcp__agent-grounding__ledger_add` to bless a
18
+ // deliberate protected-branch edit (version bumps, CI workflow
19
+ // patches, hotfixes). The `:<reason>` suffix is free-form so the
20
+ // audit log can read WHY the override fired.
21
+ //
22
+ // Failure mode: any error in load / parse / ledger query resolves to
23
+ // BLOCK. This is the inverse of understanding-before-execution's
24
+ // fail-open contract: branch-protection's whole job is to prevent
25
+ // edit-on-master incidents, so a bug in the blocker that silently
26
+ // allowed Writes through would defeat the purpose. The block envelope
27
+ // always names a recovery path so the operator is never wedged.
28
+ import { queryLedgerByTag, } from "../../policies/index.js";
29
+ import { ACK_TAG_PREFIX, DEFAULT_PROTECTED_BRANCHES, NON_PROTECTED_TAG_PREFIX, PACK_NAME, PRODUCER_FRESHNESS_MS, resolveProtectedBranches, } from "../../policy-packs/builtin/branch-protection-runtime.js";
30
+ import { resolveGitContext } from "../../runtime/git-context.js";
31
+ import { POLICY_DECISION_TYPE } from "../../runtime/ledger-record.js";
32
+ import { loadManifest } from "../loader.js";
33
+ async function readStdin(stream) {
34
+ return new Promise((resolve, reject) => {
35
+ let data = "";
36
+ stream.setEncoding("utf8");
37
+ stream.on("data", (chunk) => {
38
+ data += chunk;
39
+ });
40
+ stream.on("end", () => resolve(data));
41
+ stream.on("error", (err) => reject(err));
42
+ });
43
+ }
44
+ function findGroundingMcp(manifest) {
45
+ return manifest.tools.mcp.find((m) => m.name === "grounding-mcp") ?? null;
46
+ }
47
+ function evaluateEntries(entries, now) {
48
+ const cutoff = now.getTime() - PRODUCER_FRESHNESS_MS;
49
+ let hasFreshProducer = false;
50
+ let hasAck = false;
51
+ let freshProducerContent = null;
52
+ let ackContent = null;
53
+ for (const e of entries) {
54
+ // Skip policy_decision audit rows: their serialized payload
55
+ // incidentally contains the tag they're about (e.g. a denied
56
+ // decision the engine recorded for THIS pack would carry the
57
+ // literal "branch:non-protected" or "branch-protection-ack" in
58
+ // its JSON, falsely satisfying the gate). Two-tier filter
59
+ // mirrors `src/policies/requires.ts:75-83`: by-type for current
60
+ // ledger rows, by-content-prefix as a backstop for legacy rows
61
+ // a pre-Phase-5-#4 ledger may still carry.
62
+ if (e.type === POLICY_DECISION_TYPE)
63
+ continue;
64
+ if (e.content.startsWith(`${POLICY_DECISION_TYPE}:`))
65
+ continue;
66
+ if (e.content.includes(ACK_TAG_PREFIX)) {
67
+ hasAck = true;
68
+ if (ackContent === null)
69
+ ackContent = e.content;
70
+ continue;
71
+ }
72
+ if (!e.content.includes(NON_PROTECTED_TAG_PREFIX))
73
+ continue;
74
+ const ts = e.createdAt instanceof Date ? e.createdAt : new Date(e.createdAt);
75
+ if (Number.isNaN(ts.getTime()))
76
+ continue;
77
+ if (ts.getTime() >= cutoff) {
78
+ hasFreshProducer = true;
79
+ if (freshProducerContent === null)
80
+ freshProducerContent = e.content;
81
+ }
82
+ }
83
+ return {
84
+ hasFreshProducer,
85
+ hasAck,
86
+ freshProducerContent,
87
+ ackContent,
88
+ totalEntries: entries.length,
89
+ degraded: null,
90
+ };
91
+ }
92
+ async function probeLedger(manifest, sessionId, opts) {
93
+ if (opts.ledgerQuery) {
94
+ const r = await opts.ledgerQuery(sessionId);
95
+ if ("degraded" in r) {
96
+ return {
97
+ hasFreshProducer: false,
98
+ hasAck: false,
99
+ freshProducerContent: null,
100
+ ackContent: null,
101
+ totalEntries: 0,
102
+ degraded: r.degraded,
103
+ };
104
+ }
105
+ return evaluateEntries(r, opts.now ?? new Date());
106
+ }
107
+ if (!manifest) {
108
+ return {
109
+ hasFreshProducer: false,
110
+ hasAck: false,
111
+ freshProducerContent: null,
112
+ ackContent: null,
113
+ totalEntries: 0,
114
+ degraded: "manifest unavailable",
115
+ };
116
+ }
117
+ const server = findGroundingMcp(manifest);
118
+ if (!server) {
119
+ return {
120
+ hasFreshProducer: false,
121
+ hasAck: false,
122
+ freshProducerContent: null,
123
+ ackContent: null,
124
+ totalEntries: 0,
125
+ degraded: "grounding-mcp not declared in manifest",
126
+ };
127
+ }
128
+ const command = Array.isArray(server.command)
129
+ ? server.command
130
+ : server.command.trim().split(/\s+/);
131
+ const env = server.env ?? undefined;
132
+ const timeoutMs = opts.ledgerTimeoutMs ?? server.health?.timeout_ms ?? 5_000;
133
+ const result = await queryLedgerByTag({
134
+ mcpCommand: command,
135
+ ...(env && { mcpEnv: env }),
136
+ sessionId,
137
+ timeoutMs,
138
+ });
139
+ if (result.kind === "degraded") {
140
+ return {
141
+ hasFreshProducer: false,
142
+ hasAck: false,
143
+ freshProducerContent: null,
144
+ ackContent: null,
145
+ totalEntries: 0,
146
+ degraded: result.reason,
147
+ };
148
+ }
149
+ return evaluateEntries(result.entries, opts.now ?? new Date());
150
+ }
151
+ function blockJson(toolName, branch, detail, protectedList) {
152
+ const minutes = Math.round(PRODUCER_FRESHNESS_MS / 60000);
153
+ const reasonText = `branch-protection: refusing ${toolName} on protected branch "${branch}". ` +
154
+ `${detail}\n` +
155
+ `To proceed, cut a feature branch and re-run the producer:\n` +
156
+ ` git checkout -b <feature-slug>\n` +
157
+ ` harness session-start branch-check\n` +
158
+ `Once the gate sees a fresh ${NON_PROTECTED_TAG_PREFIX} tag (within ${minutes}m), this tool call will succeed.\n` +
159
+ `\n` +
160
+ `Override (use sparingly): write \`${ACK_TAG_PREFIX}:<reason>\` to the ledger via mcp__agent-grounding__ledger_add. ` +
161
+ `The override survives the session and bypasses this gate.\n` +
162
+ `\n` +
163
+ `Protected branches: ${protectedList.join(", ")}.`;
164
+ return JSON.stringify({
165
+ decision: "block",
166
+ reason: reasonText,
167
+ hookSpecificOutput: {
168
+ hookEventName: "PreToolUse",
169
+ permissionDecision: "deny",
170
+ permissionDecisionReason: reasonText,
171
+ },
172
+ });
173
+ }
174
+ export async function runPackHookBranchProtectionCli(opts = {}) {
175
+ const stdin = opts.stdin ?? process.stdin;
176
+ const stdout = opts.stdout ?? process.stdout;
177
+ const stderr = opts.stderr ?? process.stderr;
178
+ const note = (msg) => {
179
+ stderr.write(`harness pack hook branch-protection: ${msg}\n`);
180
+ };
181
+ // Defensive stdin parse. Empty / malformed input resolves to BLOCK
182
+ // (the inverse of understanding-before-execution's allow-on-malformed
183
+ // default): we'd rather block a Write we couldn't classify than let
184
+ // it through silently.
185
+ const raw = await readStdin(stdin);
186
+ let event = {};
187
+ try {
188
+ event = JSON.parse(raw.trim() || "{}");
189
+ }
190
+ catch {
191
+ /* event stays {} — handled by the sessionId check below */
192
+ }
193
+ const sessionId = (typeof event.session_id === "string" ? event.session_id : undefined) ??
194
+ process.env.CLAUDE_SESSION_ID ??
195
+ "";
196
+ const toolName = typeof event.tool_name === "string" ? event.tool_name : "(unknown)";
197
+ const cwd = typeof opts.cwd === "string" && opts.cwd.length > 0
198
+ ? opts.cwd
199
+ : typeof event.cwd === "string" && event.cwd.length > 0
200
+ ? event.cwd
201
+ : process.cwd();
202
+ // Load manifest to resolve the protected-branches list AND the
203
+ // grounding-mcp wiring. A manifest load failure forces BLOCK with a
204
+ // clear hint — we can't know if the gate should fire if we can't
205
+ // read its config.
206
+ let manifest = null;
207
+ if (opts.manifest) {
208
+ manifest = opts.manifest;
209
+ }
210
+ else {
211
+ try {
212
+ manifest = loadManifest(opts).manifest;
213
+ }
214
+ catch (err) {
215
+ const reason = `manifest load failed (${err.message}); refusing on failsafe`;
216
+ const diagnostic = `BLOCK — ${reason}`;
217
+ note(diagnostic);
218
+ stdout.write(`${blockJson(toolName, "(unresolvable)", reason, DEFAULT_PROTECTED_BRANCHES)}\n`);
219
+ return { exitCode: 0, blocked: true, diagnostic };
220
+ }
221
+ }
222
+ const pack = manifest.policy_packs.find((p) => p.name === PACK_NAME);
223
+ if (!pack) {
224
+ const diagnostic = `pack "${PACK_NAME}" not declared in manifest, allowing`;
225
+ note(diagnostic);
226
+ return { exitCode: 0, blocked: false, diagnostic };
227
+ }
228
+ if (!pack.enabled) {
229
+ const diagnostic = `pack "${PACK_NAME}" is enabled:false, allowing`;
230
+ note(diagnostic);
231
+ return { exitCode: 0, blocked: false, diagnostic };
232
+ }
233
+ const { branches: protectedList } = resolveProtectedBranches(pack);
234
+ const { branch } = resolveGitContext(cwd);
235
+ // Outside a git work tree (or detached HEAD) we can't tell what the
236
+ // edit would land on. We choose to allow here — the alternative is
237
+ // blocking every Write in non-git workspaces, which would be hostile
238
+ // to standalone-script workflows. A detached HEAD on an in-repo cwd
239
+ // also lands here; arguably should block, but git-detached-HEAD
240
+ // edits don't auto-push to a protected ref so the downstream
241
+ // `preflight-before-push` gate still catches the actual hazard.
242
+ if (branch === "") {
243
+ const diagnostic = `cwd is not on a named branch (detached HEAD or outside a git work tree); allowing`;
244
+ note(diagnostic);
245
+ return { exitCode: 0, blocked: false, diagnostic };
246
+ }
247
+ if (!protectedList.includes(branch)) {
248
+ const diagnostic = `branch "${branch}" is not in the protected list (${protectedList.join(", ")}); allowing`;
249
+ note(diagnostic);
250
+ return { exitCode: 0, blocked: false, diagnostic };
251
+ }
252
+ // On a protected branch: probe the ledger for either gate path.
253
+ if (sessionId === "") {
254
+ const reason = `no session_id resolvable from stdin or $CLAUDE_SESSION_ID; cannot consult ledger`;
255
+ const diagnostic = `BLOCK — ${reason}`;
256
+ note(diagnostic);
257
+ stdout.write(`${blockJson(toolName, branch, reason, protectedList)}\n`);
258
+ return { exitCode: 0, blocked: true, diagnostic };
259
+ }
260
+ const check = await probeLedger(manifest, sessionId, opts);
261
+ if (check.hasAck) {
262
+ const diagnostic = `ACK override active (${check.ackContent ?? ACK_TAG_PREFIX}); allowing`;
263
+ note(diagnostic);
264
+ return { exitCode: 0, blocked: false, diagnostic };
265
+ }
266
+ if (check.hasFreshProducer) {
267
+ const diagnostic = `fresh producer tag (${check.freshProducerContent ?? NON_PROTECTED_TAG_PREFIX}); allowing`;
268
+ note(diagnostic);
269
+ return { exitCode: 0, blocked: false, diagnostic };
270
+ }
271
+ const why = check.degraded !== null
272
+ ? `ledger degraded (${check.degraded}); refusing on failsafe`
273
+ : `no fresh ${NON_PROTECTED_TAG_PREFIX} tag (${check.totalEntries} entries scanned) and no ${ACK_TAG_PREFIX} override`;
274
+ const diagnostic = `BLOCK — ${why}`;
275
+ note(diagnostic);
276
+ stdout.write(`${blockJson(toolName, branch, why, protectedList)}\n`);
277
+ return { exitCode: 0, blocked: true, diagnostic };
278
+ }
279
+ //# sourceMappingURL=hook-branch-protection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-branch-protection.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-branch-protection.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ import { queryLedgerByTag } from "../../policies/index.js";
23
23
  import { checkApprovalMarker, checkPersistedReport, defaultReportsDir, matchLedgerEntries, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
24
24
  import { resolveGeneratedDir } from "../../runtime/pending-approval.js";
25
25
  import { loadManifest } from "../loader.js";
26
+ import { renderReportSchemaHint } from "./understanding-report-schema-hint.js";
26
27
  const PACK_NAME = "understanding-before-execution";
27
28
  const EXIT_BLOCK = 2;
28
29
  async function readStdin(stream) {
@@ -163,7 +164,8 @@ export async function runPackHookCodexPreToolUseCli(opts = {}) {
163
164
  ? `no approval marker for session ${sessionId}; ${report.detail}; ${ledger.detail}`
164
165
  : `generatedDir not resolvable (test/injection path); ${report.detail}; ${ledger.detail}`;
165
166
  const diagnostic = `harness pack hook codex: BLOCK: ${reason}. Tool: ${toolName}. ` +
166
- "Run `harness approve understanding` once you have produced and confirmed an Understanding Report.";
167
+ "Run `harness approve understanding` once you have produced and confirmed an Understanding Report.\n" +
168
+ renderReportSchemaHint();
167
169
  stderr.write(`${diagnostic}\n`);
168
170
  return {
169
171
  exitCode: EXIT_BLOCK,
@@ -1 +1 @@
1
- {"version":3,"file":"hook-codex-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-codex-pre-tool-use.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-codex-pre-tool-use.js","sourceRoot":"","sources":["../../../src/cli/pack/hook-codex-pre-tool-use.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type LedgerEntry } from "../../policies/index.js";
2
2
  import { type ApprovalCheckResult } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
3
- import type { Manifest } from "../../schema/index.js";
3
+ import { type Manifest } from "../../schema/index.js";
4
4
  import { type LoaderOptions } from "../loader.js";
5
5
  export interface PackHookPreToolUseOptions extends LoaderOptions {
6
6
  /** Pack name to evaluate. Defaults to understanding-before-execution. */