@lannguyensi/harness 0.39.0 → 0.41.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 (127) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/cli/approve/stdin-report.d.ts +42 -0
  3. package/dist/cli/approve/stdin-report.js +143 -0
  4. package/dist/cli/approve/stdin-report.js.map +1 -0
  5. package/dist/cli/approve/understanding.d.ts +20 -0
  6. package/dist/cli/approve/understanding.js +44 -0
  7. package/dist/cli/approve/understanding.js.map +1 -1
  8. package/dist/cli/diff/git.d.ts +5 -0
  9. package/dist/cli/diff/git.js +25 -3
  10. package/dist/cli/diff/git.js.map +1 -1
  11. package/dist/cli/doctor/codex.d.ts +8 -0
  12. package/dist/cli/doctor/codex.js +8 -1
  13. package/dist/cli/doctor/codex.js.map +1 -1
  14. package/dist/cli/doctor/format.js +23 -11
  15. package/dist/cli/doctor/format.js.map +1 -1
  16. package/dist/cli/doctor/index.d.ts +36 -0
  17. package/dist/cli/doctor/index.js +131 -29
  18. package/dist/cli/doctor/index.js.map +1 -1
  19. package/dist/cli/doctor/types.d.ts +26 -0
  20. package/dist/cli/dry-run.js +5 -0
  21. package/dist/cli/dry-run.js.map +1 -1
  22. package/dist/cli/explain.js +16 -3
  23. package/dist/cli/explain.js.map +1 -1
  24. package/dist/cli/index.js +109 -6
  25. package/dist/cli/index.js.map +1 -1
  26. package/dist/cli/init/composer.js +10 -31
  27. package/dist/cli/init/composer.js.map +1 -1
  28. package/dist/cli/init/index.d.ts +18 -0
  29. package/dist/cli/init/index.js +28 -2
  30. package/dist/cli/init/index.js.map +1 -1
  31. package/dist/cli/init/interactive.d.ts +8 -0
  32. package/dist/cli/init/interactive.js +22 -1
  33. package/dist/cli/init/interactive.js.map +1 -1
  34. package/dist/cli/init/profiles.d.ts +2 -2
  35. package/dist/cli/init/profiles.js +11 -2
  36. package/dist/cli/init/profiles.js.map +1 -1
  37. package/dist/cli/init/templates.d.ts +1 -1
  38. package/dist/cli/init/templates.js +174 -4
  39. package/dist/cli/init/templates.js.map +1 -1
  40. package/dist/cli/list.js +3 -1
  41. package/dist/cli/list.js.map +1 -1
  42. package/dist/cli/pack/approve-escape.d.ts +19 -0
  43. package/dist/cli/pack/approve-escape.js +120 -0
  44. package/dist/cli/pack/approve-escape.js.map +1 -0
  45. package/dist/cli/pack/hook-bootstrap.d.ts +24 -0
  46. package/dist/cli/pack/hook-bootstrap.js +47 -1
  47. package/dist/cli/pack/hook-bootstrap.js.map +1 -1
  48. package/dist/cli/pack/hook-branch-protection.js +9 -1
  49. package/dist/cli/pack/hook-branch-protection.js.map +1 -1
  50. package/dist/cli/pack/hook-codex-post-tool-use.d.ts +25 -0
  51. package/dist/cli/pack/hook-codex-post-tool-use.js +160 -0
  52. package/dist/cli/pack/hook-codex-post-tool-use.js.map +1 -0
  53. package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +1 -0
  54. package/dist/cli/pack/hook-codex-pre-tool-use.js +43 -10
  55. package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
  56. package/dist/cli/pack/hook-codex-stop.js +1 -8
  57. package/dist/cli/pack/hook-codex-stop.js.map +1 -1
  58. package/dist/cli/pack/hook-post-tool-use.js +16 -131
  59. package/dist/cli/pack/hook-post-tool-use.js.map +1 -1
  60. package/dist/cli/pack/hook-pre-tool-use.js +69 -26
  61. package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
  62. package/dist/cli/pack/hook-stay-in-scope.js +63 -20
  63. package/dist/cli/pack/hook-stay-in-scope.js.map +1 -1
  64. package/dist/cli/pack/hook-track-active-claim.js +33 -9
  65. package/dist/cli/pack/hook-track-active-claim.js.map +1 -1
  66. package/dist/cli/pack/index.d.ts +2 -1
  67. package/dist/cli/pack/index.js +2 -1
  68. package/dist/cli/pack/index.js.map +1 -1
  69. package/dist/cli/pack/mutate.d.ts +19 -0
  70. package/dist/cli/pack/mutate.js +38 -0
  71. package/dist/cli/pack/mutate.js.map +1 -1
  72. package/dist/cli/pack/reseed.d.ts +19 -0
  73. package/dist/cli/pack/reseed.js +118 -0
  74. package/dist/cli/pack/reseed.js.map +1 -0
  75. package/dist/cli/pack/understanding-report-schema-hint.js +12 -1
  76. package/dist/cli/pack/understanding-report-schema-hint.js.map +1 -1
  77. package/dist/cli/pause/index.js +12 -3
  78. package/dist/cli/pause/index.js.map +1 -1
  79. package/dist/cli/session-start/index.d.ts +14 -0
  80. package/dist/cli/session-start/index.js +42 -2
  81. package/dist/cli/session-start/index.js.map +1 -1
  82. package/dist/cli/validate/checks.js +8 -0
  83. package/dist/cli/validate/checks.js.map +1 -1
  84. package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -2
  85. package/dist/policy-packs/builtin/branch-protection-runtime.js +4 -2
  86. package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
  87. package/dist/policy-packs/builtin/branch-protection.d.ts +10 -1
  88. package/dist/policy-packs/builtin/branch-protection.js +17 -0
  89. package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
  90. package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +197 -24
  91. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +342 -40
  92. package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -1
  93. package/dist/policy-packs/builtin/understanding-before-execution.d.ts +26 -1
  94. package/dist/policy-packs/builtin/understanding-before-execution.js +302 -17
  95. package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
  96. package/dist/policy-packs/registry.d.ts +22 -1
  97. package/dist/policy-packs/registry.js +19 -2
  98. package/dist/policy-packs/registry.js.map +1 -1
  99. package/dist/policy-packs/ux-compare.d.ts +14 -0
  100. package/dist/policy-packs/ux-compare.js +58 -0
  101. package/dist/policy-packs/ux-compare.js.map +1 -0
  102. package/dist/policy-packs/ux-drift-check.d.ts +27 -0
  103. package/dist/policy-packs/ux-drift-check.js +78 -0
  104. package/dist/policy-packs/ux-drift-check.js.map +1 -0
  105. package/dist/probes/mcp.d.ts +13 -0
  106. package/dist/probes/mcp.js +57 -0
  107. package/dist/probes/mcp.js.map +1 -1
  108. package/dist/runtime/approval-signing.d.ts +82 -0
  109. package/dist/runtime/approval-signing.js +275 -0
  110. package/dist/runtime/approval-signing.js.map +1 -0
  111. package/dist/runtime/intercept.js +62 -5
  112. package/dist/runtime/intercept.js.map +1 -1
  113. package/dist/runtime/ledger-add.js +5 -1
  114. package/dist/runtime/ledger-add.js.map +1 -1
  115. package/dist/runtime/pause-sentinel.js +14 -3
  116. package/dist/runtime/pause-sentinel.js.map +1 -1
  117. package/dist/runtime/recovery-git-commit.d.ts +22 -0
  118. package/dist/runtime/recovery-git-commit.js +284 -0
  119. package/dist/runtime/recovery-git-commit.js.map +1 -0
  120. package/dist/runtime/tool-name-aliases.d.ts +1 -0
  121. package/dist/runtime/tool-name-aliases.js +7 -1
  122. package/dist/runtime/tool-name-aliases.js.map +1 -1
  123. package/dist/schema/index.d.ts +53 -42
  124. package/dist/schema/policies.d.ts +56 -44
  125. package/dist/schema/policies.js +79 -9
  126. package/dist/schema/policies.js.map +1 -1
  127. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,65 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.41.0] - 2026-07-16
11
+
12
+ ### Security
13
+
14
+ - **The understanding-gate approval marker (and its branch-protection twin) is now HMAC-signed, closing the "existence is enough" filesystem-marker forgery hole — the persisted-report approval path is a separate, still-unsigned residual, see below** (task f9485cc7, M10 / Feature idea #7, promised in the `[0.32.0]` entry's "cryptographic marker signing... is a tracked follow-up" note). The marker's integrity used to rest entirely on an UNENFORCED invariant — "no configured MCP exposes a filesystem-write primitive" — checked nowhere; one future MCP tool with local file-write would silently reopen it, since its tool name wouldn't match the `Edit|Write|Bash` blocker matcher, and the marker's contract was "existence is enough" (a bare filesystem-write forged it). `harness approve understanding` now writes an HMAC-SHA256 signature over `(markerId, approvedAt, approvedBy, reportContentHash)` — `reportContentHash` is the sha256 of the persisted Understanding Report bound to this approval; this is groundwork only, NOT yet enforced at gate-check time (the live cross-check against the currently-selected report is the C1 staleness follow-up, task fa423e9b) — using an operator-side key lazily generated (`crypto.randomBytes(32)`, mode `0600`) at `<generatedDir>/.approval-signing.key`. `checkApprovalMarker` (shared by the session marker, task-scoped markers, and `checkBranchProtectionMarker`) now REJECTS a marker with a missing or invalid signature — matched:false, same as no marker, but with a distinct `forged/unsigned marker rejected` diagnostic surfaced through both the Claude and Codex PreToolUse hooks and the branch-protection hook, so an operator/auditor can tell an active forgery attempt (or a pre-signing legacy marker) apart from the routine "never approved" case. Binding `markerId` into the signature also means the "copy a marker onto a new session id" admin trick this doc used to describe no longer works — a copied marker fails verification. **Back-compat is strict, no migration window**: a marker written before this shipped has no `signature` field and is rejected exactly like a forgery; re-run `harness approve understanding` (and/or `harness approve branch-protection`) once after upgrading a machine with a live approval.
15
+ - **What is NOT closed by this task (read before assuming more than it delivers).** (1) The **persisted-report approval path** (`checkPersistedReport`, consulted by both PreToolUse hooks with EQUAL authority immediately after a forged marker is correctly rejected) is **not signed at all** and, under this task's own threat model (a future write primitive the `Edit|Write|Bash` matcher doesn't cover), is an **equal-or-easier** forgery target than the marker used to be: no signing key to read, no sessionId match required (the gate-read path's tolerant fallback is `"any"`, unrestricted by age), just a JSON file with `approvalStatus: "approved"` dropped into the reports dir. Tracked as follow-up **task `7402301d-14bb-4b03-8d88-a2bb8bad8084`**. (2) The `solution-acceptance` pack's verdict marker remains unsigned (tracked separately, `[0.32.0]` note). (3) An agent with BOTH arbitrary local file-read (true today, by design — the blocker never gates `Read`) AND a write primitive the `Edit|Write|Bash` matcher doesn't cover can still forge a validly-signed marker: read the key, compute the HMAC, write the result through the uncovered path — signing does not close that combined case, only the narrower, previously totally-undefended write-only-forgery case, and it makes any attempt materially more expensive and forensically visible. Given the agent and operator share one OS user account, this is deliberate defense-in-depth, not a hard authorization boundary; full write-up in `src/runtime/approval-signing.ts` and `docs/policy-packs/understanding-before-execution.md` "Marker signing". (4) An interim MCP-catalog write-capability warning at `init`/smoke time was considered but did not fall out naturally from this change and is left as a candidate follow-up.
16
+ - New tests: `tests/runtime/approval-signing.test.ts` (key generation/persistence/corruption-recovery/rotation, sign/verify round-trip, tamper + wrong-markerId + missing-field rejections), forgery + tamper-mutation regressions in `tests/policy-packs/runtime.test.ts`, `tests/io/read-regular-file-unreadable.test.ts`, `tests/cli/pack-hook-pre-tool-use.test.ts`, `tests/cli/pack-hook-codex-pre-tool-use.test.ts`, and `tests/cli/pack-hook-branch-protection.test.ts`.
17
+
18
+ ### Added
19
+
20
+ - **Warn-only OKF staleness watch on every PR** (`.github/workflows/okf-staleness.yml`, PR #350): runs `okf-kit check` (exact pin 0.3.1) against `docs/okf`, surfaces STALE/structural findings as per-doc annotations plus a full job summary, never blocks a merge; tool errors fail red so a broken check cannot look green. Canonical pattern for the five OKF bundle repos; never mark it required in branch protection.
21
+ - **`harness pack reseed <name>` pulls a pack's shipped `config.ux` (and `config.producers`) into an already-installed manifest** (task 68b9ad9c). Before this, a deny-message wording fix in the init templates (e.g. the heredoc submission form, `agent-tasks/e48e3b45`) only reached manifests generated by a fresh `harness init` AFTER the fix shipped: `harness apply` only ever projects the manifest OUT to `settings.json`, nothing propagated a template fix back INTO an operator's existing `policy_packs[].config.ux`, so an already-installed manifest kept teaching stale wording indefinitely, even after the CLI itself was upgraded. `harness doctor` now also warns when an enabled pack's `config.ux` / `config.producers` textually diverges from the CLI's shipped default for that pack — compared against the pack's OWN configured `mode` (`understanding-before-execution`'s `required:` line varies by mode), not a hardcoded one, so switching modes is never mistaken for drift. Both the warning and the reseed write share one canonical source per pack (`defaultUx()` / `defaultProducers()` in `src/policy-packs/builtin/understanding-before-execution.ts` and `src/policy-packs/builtin/branch-protection.ts`, wired through the new `resolveBuiltinDefaultConfig` in `src/policy-packs/registry.ts`), so the check and the fix can never independently drift on what "the shipped template" means; the `init` Custom composer (`src/cli/init/composer.ts`) now reads from the same source instead of carrying its own copy of the literal text. `reseed` is deliberately explicit-only — never invoked by `apply`, `doctor`, or any automatic path — and only ever touches `config.ux` / `config.producers`, leaving every other key on the pack entry (`mode`, `approval_lifecycle`, `permission_profile`, `min_version`, ...) untouched, so an operator's own deliberate ux customisation is never silently clobbered by an upgrade (the same reasoning `harness adopt` exists for in the opposite direction). `--dry-run` prints the diff without writing; a pack whose `config.ux` already matches the shipped default is a no-op. `solution-acceptance` has no registered shipped default (ships `enabled: false` with no `config:` block in any template) and is reported clearly as such rather than silently reseeded with nothing. A new parity test, `tests/cli/init-templates-ux-parity.test.ts`, pins FULL_TEMPLATE / SOLO_TEMPLATE / TEAM_TEMPLATE (`src/cli/init/templates.ts`, `src/cli/init/profiles.ts`) and the Custom composer's `config.ux` / `config.producers` against `defaultUx()` / `defaultProducers()`, so a future wording fix landed in a template WITHOUT updating those functions (which would make `reseed` silently pull operators back to the stale wording — the same bug class one layer removed) fails the build instead of shipping unnoticed; matching "KEEP IN SYNC" comments were added at each template's `ux:` / `producers:` block. New tests: `tests/policy-packs/ux-compare.test.ts`, `tests/policy-packs/ux-drift-check.test.ts`, `tests/policy-packs/builtin-default-config.test.ts`, `tests/cli/pack-reseed.test.ts`, `tests/cli/init-templates-ux-parity.test.ts`, plus new `doctor` coverage in `tests/cli/doctor.test.ts`. Docs: `docs/policy-packs/understanding-before-execution.md` ("Refreshing `config.ux` after a harness upgrade"), `docs/policy-packs/branch-protection.md`, `docs/CLI.md`. `check:duplication`'s `MAX_CLONES` pin raised 82→86 with a recorded justification (`scripts/check-duplication.mjs`): the new `cli/pack/reseed.ts` necessarily clones the validate/lock/diff/write shape already repeated undeduped across `add`/`remove`'s CLI and `pack add`/`pack remove`.
22
+ - **Codex sessions now get the active-claim tracker and the stay-in-scope reminder too** (task cf4cdc93, closes `docs/okf/codex-adapter-parity-gaps.md` gap #3, the last hook-parity gap between the two runtimes). Before this, `harness pack hook track-active-claim` (writes/clears `harness.generated/active-claim` on `task_start`/`task_finish`/`task_abandon` so `harness approve understanding` can auto-resolve `--task`) and `harness pack hook stay-in-scope` (soft reminder + audit row on a review-derived follow-up task) were Claude-only: a Codex session could honor an existing task-scoped marker but could never produce the active-claim file itself, and got no stay-in-scope reminder at all.
23
+ - **No new Codex-specific CLI verb needed, unlike the other Codex hooks.** Both hook bodies (`src/cli/pack/hook-track-active-claim.ts`, `src/cli/pack/hook-stay-in-scope.ts`) needed no session-id resolution and no shell-command extraction the way `codex-post-tool-use`/`codex-pre-tool-use` need. `harness apply --runtime codex` now emits two more `[[hooks.PostToolUse]]` groups running the SAME commands (`harness pack hook track-active-claim` / `harness pack hook stay-in-scope`) as the Claude branch — the Codex adapter now contributes 6 hooks total, matching the Claude branch's hook roster.
24
+ - **Same two-layer alias fix task a1348c89 established, applied to these two hooks.** The existing Claude matchers (`TRACK_ACTIVE_CLAIM_MATCH`, `STAY_IN_SCOPE_MATCH`) are anchored `^(?:...)$` regexes that `expandCodexHookMatchPattern`'s "simple token" guard passes through UNCHANGED at TOML-emit time, so a Codex session sending an MCP tool-name variant (server hyphen/underscore swap, the `mcp__server__.tool` dotted form) would never reach the hook at all. Fixed with new Codex-specific bare `|`-joined sibling constants (`TRACK_ACTIVE_CLAIM_MATCH_CODEX`, `STAY_IN_SCOPE_MATCH_CODEX`, same shape as `codexPostToolUseMatchPattern`'s output). Both hook bodies' tool-name comparisons were also switched from raw `===`/`.includes` to the shared alias-aware `toolNameMatchesAny` (`understanding-before-execution-runtime.ts`) so a variant `tool_name` the widened matcher now routes to the hook is also recognized once inside it — closing the same class of dispatcher-vs-body gap task a1348c89 fixed once already for the marker-expiry hook.
25
+ - **Review finding, same task, empirically confirmed (MEDIUM): the two hooks read ONLY `tool_name`/`tool_input`, silently no-op-ing on the field-name synonyms the Codex envelope also tolerates.** `hook-codex-post-tool-use.ts` already accepts `tool` as a `tool_name` synonym and `raw_input` as a `tool_input` synonym (`pickString(event.tool_name, event.tool)`, `resolveToolInput`); `track-active-claim` and `stay-in-scope` did not, so a probe of `{ tool_name, raw_input: { taskId } }` or `{ tool, tool_input: { taskId } }` silently no-op'd in the two new hooks while the sibling hook worked. Fixed by extracting `pickString` (already shared) and a new `resolveToolInput` into `src/cli/pack/hook-bootstrap.ts` and consuming both from the two new hooks, rather than a third/fourth hand-copy. `stay-in-scope`'s `tool_response` taskId fallback (a Claude-side convention the Codex envelope may not carry) was deliberately left reading the field as-is, not folded into the `tool_input`/`raw_input` resolution. New tests cover the `raw_input`-only shape, the `tool`-only shape, `tool_input`-over-`raw_input` precedence, the still-working `tool_response` fallback, and a negative control (neither name field present still skips).
26
+ - New tests: dispatcher-layer pins in `tests/policy-packs/expand.test.ts` (hook count/roster, matcher values, alias-expansion, always-on-regardless-of-`approval_lifecycle`-config parity with the Claude opt-out) and `tests/cli/apply/generate-codex-config.test.ts` (real `expandPolicyPacks` + `generateCodexConfig` output, positive + negative control on the actual emitted TOML matchers — the must-pass control this task's brief asked for); hook-body alias-variant AND wire-format-synonym tests in `tests/cli/pack-hook-track-active-claim.test.ts` and `tests/cli/pack-hook-stay-in-scope.test.ts` (canonical + dotted + underscore-server tool-name forms, a `tasks_transition` status-filter-under-aliasing negative control mirroring the a1348c89 regression guard, plus the `tool`/`raw_input` synonym coverage above). Docs updated: `docs/policy-packs/understanding-before-execution.md`, `docs/CLI.md`, `docs/okf/codex-adapter-parity-gaps.md`.
27
+ - **Codex sessions now expire the understanding-gate approval marker on task-completion boundaries** (task a1348c89, follow-up to the `[0.39.0]` task e7c2ec3c TTL/task-marker parity fix, whose entry named this exact residual). Before this, a Codex approval marker survived every `task_finish` / `task_abandon` / `pull_requests_merge` and only died via `approval_lifecycle.max_age` or a manual `rm`.
28
+ - `harness apply --runtime codex` now also emits a `[[hooks.PostToolUse]]` group running the new `harness pack hook codex-post-tool-use`, sharing its match/clear/diagnostic logic with the existing Claude `post-tool-use` hook through three functions extracted into `understanding-before-execution-runtime.ts` (`matchPostToolUseBoundary`, `applyPostToolUseExpiry`, `describePostToolUseExpiry`) — the same drift-avoidance pattern task e7c2ec3c used on the PreToolUse side. Advisory only (never blocks; every error path is exit 0 + stderr). The Codex `[[hooks.PostToolUse]]` TOML schema support already existed in the generator (PR #211, real Codex 0.131.0 schema); this task contributes the pack-side hook and CLI verb that consume it.
29
+ - **Also fixes (review finding, same task): MCP tool-name variants a runtime may emit for the identical tool** (server hyphen/underscore swap, the `mcp__server__.tool` dotted form) **are now handled at BOTH layers this feature needs.** (1) Dispatcher layer: the Codex `PostToolUse` `match` field is now built by a new `codexPostToolUseMatchPattern` (bare `|`-joined list) instead of the Claude `postToolUseMatchPattern` helper (anchored `^(?:...)$` regex) — the anchor characters silently defeated `generate-codex-config.ts`'s `expandCodexHookMatchPattern` alias expansion, so Codex's own dispatcher would never have invoked the hook at all for a variant `tool_name`. (2) Hook-body layer: `toolNameMatchesAny` (`understanding-before-execution-runtime.ts`) now expands the incoming `tool_name` through the same `expandToolNameAliases` normalization `harness policy intercept`'s `policyMatchesEvent` already applies, so the body's `expire_on_tool_match` comparison recognizes a variant too. The legacy v1 `tasks_transition` status filter is alias-aware now as well, closing a status-filter-bypass the body-only half of this fix would otherwise have introduced (a variant `tasks_transition` call would have matched generally but skipped the `status === "done"` check entirely). Verified both fixes independently via mutation testing (each reverts to the pre-fix behavior red before the fix, green after).
30
+ - **Known limitation at the time of task a1348c89, shared with Claude Code, not Codex-specific** (since closed in this same Unreleased batch by task bea04a03, see Fixed below): `approval_lifecycle.expire_on_bash_match` was not yet routed to the PostToolUse hook on either runtime — the hook's trigger matched only `expire_on_tool_match` verbs, so a real `Bash`/`shell`/`exec_command` call did not invoke the hook on Codex OR Claude. Was tracked as a follow-up (agent-tasks bea04a03); see `docs/okf/codex-adapter-parity-gaps.md` gap 12.
31
+ - 29 new tests in `tests/cli/pack-hook-codex-post-tool-use.test.ts` (Claude-suite parity coverage, Codex-specific synonyms/aliases, MCP tool-name-variant matching, a `tasks_transition`-under-aliasing regression guard, an integration must-pass control proving the expiry re-locks the PreToolUse blocker), plus new dispatcher-layer pins in `tests/policy-packs/expand.test.ts` and `tests/cli/apply/generate-codex-config.test.ts` (real `expandPolicyPacks` + `generateCodexConfig` output, positive + negative control on the actual emitted TOML matcher). Docs updated: `docs/policy-packs/understanding-before-execution.md`, `docs/CLI.md`, `docs/okf/codex-adapter-parity-gaps.md`.
32
+
33
+ ### Fixed
34
+
35
+ - **`harness doctor` exits 1 when the report contains errors** (PR #342), so CI and scripts can gate on it instead of parsing text.
36
+ - **`harness doctor` survives a spawn ENOENT on a missing MCP/CLI binary** (PR #340) and reports the missing binary as a finding instead of crashing the whole report.
37
+ - **`harness pause` no longer recommends the broken `!`-prefix advice** (PR #341): a `!`-shell inherits the session env, so the operator-only guardrail fired anyway; the agent-shell bypass is now denied at the policy layer instead (see the operator_only entry above for the policy primitive that grew out of this).
38
+ - **Four reference-doc statements that had drifted from code were corrected** (PR #339, task 6a79738e, found by the OKF wave-1 fact-check).
39
+ - **`harness preflight` no longer reports a false `failing: npm-test` when the operator has non-empty real harness state** (task 6ffa5672; third incident of the operator-state-isolation class PR #199 pinned, after the v0.21.1 preflight-stage and v0.22.0 approveUnderstanding leaks). The launcher (`src/cli/main.ts`) sets `HARNESS_ALLOW_REAL_GENERATED_DIR=1` for the real binary; `spawnPreflight` passed no `env` to `execFile`, so agent-preflight and its nested `npm test` vitest run inherited the flag, re-enabling the implicit real-homedir fallback INSIDE the test processes. With a real `harness pause` sentinel present, 110 tests across 9 files failed (intercept tests receive "PAUSED since Nm ago" instead of policy output), the `npm-test` check went red, and the producer left the preflight tag unwritten with a misleading one-word reason, deterministically for as long as the sentinel existed. Reproduced safely via a fake `HOME` with a planted sentinel plus the flag (never against the real home dir). Fix: `spawnPreflight` now spawns the child with `preflightChildEnv()`, the parent env minus that single key; nothing else is scrubbed (PATH/HOME stay, preflight checks legitimately need the environment). Spawn-site audit alongside the fix: every other child harness starts is a git/version/install probe or a ledger/MCP client (none read the flag), or the deliberately operator-real `smoke` / runtime-reality commands, all left inheriting by design. Also fixed the diagnosability gap that made this expensive to find: `describeNotReady` now surfaces the failing check's own first `details` line (`failing: npm-test (<detail>)`, whitespace-collapsed, capped at 140 chars) instead of the bare check name, and the producer's `PreflightJson` slice learned the `details` field. New tests in `tests/cli/session-start/preflight.test.ts`: a pure `preflightChildEnv` unit (strips exactly the one key, does not mutate the parent env) and a real-spawn regression that drives `runSessionStartPreflight` WITHOUT the runner injection against a fake `preflight` binary on PATH recording its environment, asserting the flag is absent in the child while a sibling variable passes through, plus a pin on the enriched stderr detail. Mutation-verified: removing the `env:` option from the `execFile` call turns the spawn regression red.
40
+ - **SECURITY: policies can now express a genuine, unconditional operator-only deny — closing the self-satisfy hole PR #341 had to ship with permanent `harness validate` warnings** (task 2cc73f55). Every `block` policy previously had to carry a `requires.ledger_tag`, and the only satisfaction primitives the engine has — a ledger tag (writable in-session via `mcp__agent-grounding__ledger_add`) or a filesystem marker (operator-only only while a gate already locks Bash/Write down, circular on a default install) — are agent-satisfiable: whoever can write the ledger can open the gate (`docs/writing-custom-policies.md` tripwire 4). That left no honest way to say "the agent may NEVER do this and cannot self-satisfy it in-session"; PR #341's three pause/resume kill-switch policies (`deny-kill-switch-bypass`, `deny-session-env-strip`, `deny-pause-sentinel-forgery`) had to declare a `requires.ledger_tag` an agent could forge, ship with NO `producers:` on purpose, and accept 3 permanent self-attestation warnings as the honest signal. Fix: a new `operator_only: true` marker on `PolicySchema` (`src/schema/policies.ts`), mutually exclusive with `requires:` (declaring both is rejected) and valid only with `enforcement: block` (`warn` / `require_approval` already have their own always-evaluated evidence paths). `evaluateOnePolicy` (`src/runtime/intercept.ts`) short-circuits an `operator_only: true` policy to an unconditional `deny` BEFORE the requires pipeline runs at all — no ledger query, no template substitution — so no ledger write, marker file, or flag can ever flip it to allow, from ANY in-session evidence. `checkPolicySelfAttestation` (`src/cli/validate/checks.ts`) now recognises the form as correct-by-construction and emits neither the warning nor (under `--strict`) an error for it. All three PR #341 policies migrated onto the new form in both `src/cli/init/templates.ts` and `docs/examples/full-manifest.yaml` (kept in parity by `tests/cli/init-full-template-parity.test.ts`, which now also pins `operator_only` as a load-bearing field); the 3 permanent validate warnings are gone and `validate --strict` on the full template returns 0 errors. Existing `requires:`-carrying `block` policies are byte-for-byte unaffected (additive path only, pinned by the full pre-existing test suite passing unchanged). New tests: a dedicated `intercept()` suite (`tests/runtime/intercept.test.ts`) proving the ledger is never queried and a forge-all-signals case (exact tag content, spoofed `source: "operator"`, a `head:<sha>`-matching entry, a replayed `policy_decision` row) never flips the outcome, plus a defensive-branch test for a hand-built Policy object satisfying neither `requires:` nor `operator_only:` (degrades to `warn-degraded`, not a crash — unreachable through `parseManifest`, but not assumed unreachable at runtime); `tests/cli/init-full-template-kill-switch-deny.test.ts`'s former "SELF-SATISFY HOLE" cases are now "FORGE-ALL-SIGNALS" regression guards proving the hole stays closed; new `parseManifest` schema tests and three new invalid-fixture files (`docs/examples/invalid/24-26`) pin the `operator_only`/`requires` mutual-exclusion and enforcement restriction. Mutation-verified: temporarily removing the `operator_only` short-circuit in `evaluateOnePolicy` turns the forge-all-signals tests red — with the migrated no-`requires:` policies, disabling only the short-circuit lands them in the `requires === undefined` defensive branch, so the outcome becomes `warn-degraded` (`blockJson: null`) rather than `deny`, not an `allow`; the forged ledger entries never even participate, since nothing queries the ledger either way. Reproducing the actual pre-fix `allow` would require reverting the whole task (the short-circuit AND the `requires` → `operator_only` migration together), which is a stronger, not weaker, confirmation that the tests exercise the fix. Docs: new "Recipe C: operator-only unconditional deny" in `docs/writing-custom-policies.md`, updated field-reference tables there and in `docs/ARCHITECTURE.md` §6, and `docs/okf/pause-vs-gate-kill-switch.md` rewritten to describe the fix instead of the (now closed) gap. Explicitly out of scope, left as a follow-up: migrating the `understanding-before-execution` / `branch-protection` packs' filesystem-marker "operator-only" claims onto this primitive (they remain forgeable in-session on a default install unless a gate already blocks all Bash) — the primitive now exists to state that trust model honestly when someone picks that follow-up up; also out of scope: `bash_match`'s own regex-coverage gaps against exotic shell shapes (heredocs, `sh -c`, base64), which is a trigger-matching problem, not a requires-satisfaction one, and remains as documented in PR #341.
41
+ - **`approval_lifecycle.expire_on_bash_match` now actually expires the marker end-to-end, on both runtimes** (task bea04a03, closes the gap the `a1348c89` entry above named "NOT fixed here" and `docs/okf/codex-adapter-parity-gaps.md` gap 12). The PostToolUse hook's trigger — the `matcher` field `harness apply` writes into `settings.json` (Claude) / `config.toml` (Codex) — was built ONLY from `approval_lifecycle.expire_on_tool_match`; a real `Bash`/`shell`/`exec_command`/`functions.exec_command` call never reached the hook at all, no matter how `expire_on_bash_match` was configured, so `matchPostToolUseBoundary`'s bash-regex check (which DOES correctly evaluate `expire_on_bash_match` once invoked) was unreachable in practice — a `gh pr merge` never re-armed the gate. Fix: `postToolUseMatchPattern` (Claude) and `codexPostToolUseMatchPattern` (Codex) in `understanding-before-execution.ts` now widen the emitted matcher with the Bash tool name / the Codex shell-tool aliases whenever `expire_on_bash_match` carries at least one pattern (new `resolveExpireOnBashMatchConfigured` presence check); the hook is now also emitted (instead of silently suppressed) when `expire_on_tool_match` is explicitly empty but `expire_on_bash_match` is configured. The widened tool names are NEVER folded into `expire_on_tool_match`'s own semantics — the hook body still classifies a matched Bash/shell call as a bash-regex match, not a tool-name match, exactly as before. New tests in `tests/policy-packs/expand.test.ts` (matcher-widening + empty-tool-list emitHook pins, both runtimes), `tests/cli/apply/generate-codex-config.test.ts` (real config.toml generator-layer pin), and `tests/cli/pack-hook-post-tool-use.test.ts` / `tests/cli/pack-hook-codex-post-tool-use.test.ts` (end-to-end: the REAL emitted matcher routes a `gh pr merge` Bash/shell call to the hook, which expires the marker, plus a negative control on a non-boundary tool) — the existing hook-body test suites had exercised `expire_on_bash_match` only by calling the hook CLI directly, bypassing the matcher construction that was actually broken. Docs updated: `docs/policy-packs/understanding-before-execution.md`, `docs/okf/codex-adapter-parity-gaps.md`.
42
+ - **SECURITY: the quote-aware recovery-commit metachar screen had a backslash-escaped-quote command-injection bypass, found and fixed before this landed** (task 6e888423, same bug class the 0.40.0 entry above already documents once for the `harness approve` heredoc matcher). `hasUnsafeMetachar`/`tokenize` (`src/runtime/recovery-git-commit.ts`) toggled quote state on every raw `"`/`'` with no concept of backslash-escaping, but bash does: `\"` outside a quote is a LITERAL `"` that does not open a quote context. A payload like `git commit -am a\" ; echo INJECTED ; \"` was therefore misread as one safely-quoted message — the classifier "entered" a phantom quote span at the escaped `"` and treated the live `;` inside it as inert text — while bash itself never entered a quote at all and ran `echo INJECTED` as a separate command. Confirmed end-to-end (classifier ADMIT + a real shell executing the injected command) for `;`, `||`, and `|` riding this exact shape, reachable exactly at `markerExpired === true`, the state the gate is supposed to hard-block everything in. Fix: reject any backslash anywhere in the command outright, before the quote-aware scan runs, rather than modeling bash's actual escape grammar (deliberately not attempted — too risky to get subtly wrong twice in one security boundary). Without a backslash present the naive quote-toggling matches bash's real quoting exactly, so this closes the whole escape-based attack surface at the cost of not admitting a message that happens to contain a literal backslash; the documented main case (this repo's own `Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>` trailer) has none. New regression tests pin all three confirmed injection payloads as rejected in the classifier unit suite AND in both the Claude and Codex PreToolUse hook suites (Codex shares the classifier and inherited the same bypass), and confirm the real trailer still converges.
43
+ - **The understanding-gate no longer hard-wedges the recovery `git commit` when `approval_lifecycle.max_age` expires mid-task** (task 6e888423). `max_age` (4h in the full template) expires the operator-approval marker independently of any task-completion boundary — correct for genuinely stale sessions, but it can also land mid-task during a long reviewer-amendment loop (apply fixes, wait on CI, iterate again). Before this fix, an agent finishing such a loop had its recovery `git commit` — the one that consolidates already-approved Edit/Write output into a new HEAD so `preflight`/solution-acceptance can re-pin their verdict there — hard-blocked exactly like any other Bash call, recoverable only via an operator-run `harness approve understanding` (agent-grounding frictions #2/#9/#58/#71; distinct from, and downstream of, the solution-acceptance/preflight-before-push livelock task 5fb64db9 already fixed). Reproduced live: an expired marker plus a bare `git commit` blocked with `approvalCheck.source: "none"`. Fix is narrow by design, not a general Bash whitelist: `checkApprovalMarker` now distinguishes `expired` (a real marker existed and aged past `max_age`) from merely absent (never approved, or cleared by a task-completion boundary tool via `clearApprovalMarker` — that case must keep hard-blocking so the gate still re-arms for the next task), threaded through `checkOperatorApprovalMarkers` so both the Claude and Codex PreToolUse hooks share one decision (`expired` is computed only on the non-matched path, so a matched marker never also reads `expired:true` even when a sibling marker is stale). A new classifier (`src/runtime/recovery-git-commit.ts`, `isRecoveryGitCommit`) admits only a bare, unchained `git commit` (`-a`/`--all`/`--allow-empty`/`-m`/`--message`/`-am`, any number of message flags — `-ma` is deliberately excluded, since getopt would parse it as `-m` with inline value `"a"` rather than `-a` plus a real message). The metachar screen is quote-aware: `;`/`&`/`|`/`<`/`>` are only dangerous OUTSIDE a quoted span (bash treats them as literal text inside single or double quotes) and are rejected there; a backtick or `$(...)` is rejected outside a quote AND inside a double-quoted span (both still expand it) but admitted inside a single-quoted span (fully inert); ANY backslash anywhere rejects the whole command outright (see the SECURITY entry above). This is what lets a real quoted commit-message trailer — including this very repo's own `Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>` convention, which needs the angle brackets — through without opening a metachar hole; an UNQUOTED chain/redirect/substitution still fails closed exactly as before. Any unrecognised flag also fails closed — `--amend` and `--no-verify` included. The exemption fires ONLY when both signals hold: `expired:true` proves this exact session/task had a real prior approval, and the classifier proves the command cannot smuggle other work or introduce new file content (everything in the working tree was itself produced by previously-gated Edit/Write/Bash). Edit/Write and every other Bash shape stay hard-gated regardless; a never-approved session's identical `git commit` still blocks; a task_finish-cleared marker's next commit still blocks (re-arm preserved). Mutation-verified via control/fix/convergence triples (including an inert-test guard carrying the real `<email>` trailer, which fails against the pre-fix quote-blind screen) in both the Claude and Codex PreToolUse hook test suites, plus a dedicated `isRecoveryGitCommit` unit-test suite covering the admit/reject boundary and the quote-aware metachar rule specifically.
44
+
45
+ ## [0.40.0] - 2026-07-10
46
+
47
+ **Headline: `harness approve understanding` can finally persist the Understanding Report it approves.** Attach the report as a quoted heredoc on the command's stdin and the same run parses it, persists it session-bound, and flips it to `approved`, and the `report: ⚠ skipped` line that every approval printed is gone, and the audit trail is no longer structurally empty. The gate's escape matcher was rebuilt around a character whitelist after review found a shell-parse divergence that let a backslash-escaped redirect smuggle commands past it. Also: `init --template full` makes the runtime-reality hook discoverable, CI enforces coverage thresholds, the test suite runs on macOS, and the curated OKF knowledge bundle ships. Re-run `npm i -g @lannguyensi/harness` to upgrade.
48
+
49
+ ### Added
50
+
51
+ - **Report capture on `harness approve understanding` (task 61fd36db, PR #337).** The command now accepts the Understanding Report as a quoted heredoc on stdin, parses it with the canonical `@lannguyensi/understanding-gate` `parseReport` (new dependency, `^0.4.5`), persists it session-bound with `approvalStatus: "pending"` into the reports dir, and lets the existing selection → validation → flip path approve it in the same run. Why this channel and not the Stop hook: the Stop-hook producer fires at END of turn, i.e. after a same-turn `approve` has already looked for a report, and current Claude Code builds no longer reliably persist mid-turn assistant text to the transcript JSONL, so no transcript-based capture (Stop-hook fallback, tier-6 session-id fallback, PreToolUse harvest) can work. The approval command is the only reliable carrier, and as a bonus the operator reads the full report inside the permission prompt before approving. Unparseable stdin degrades loudly (a `stdin: ⚠` line plus a parse-error log in the standalone hook's format, so `findLatestParseError` surfaces the reason) but never blocks the approval itself; a parsed-but-hollow `grill_me` report still refuses the marker through the existing validation short-circuit; incomplete piped input (timeout, stream error, size cap) is refused rather than captured, so a truncated report can never be persisted and approved as if it were whole. The deny message, the `init` profiles/templates/composer `ux.run` texts, and `docs/okf/understanding-gate-lockout-recovery.md` all teach the heredoc form.
52
+ - **The runtime-reality PreToolUse hook is discoverable from `harness init --template full`** (task 9f10267e, PRs #333, #334). `grep runtime-reality src/cli/init/` used to return zero hits, so operators only found the hook through `docs/runtime-reality-hook.md`. FULL_TEMPLATE now carries a fully commented-out `hooks[]` entry with placeholder env values and a docs pointer: enable-in-place, but not an active default, because the hook is host-coupled and without `RUNTIME_REALITY_KEYWORD`, an expectations file, and `RUNTIME_REALITY_PROBE_CMD` it degrades to a silent allow that looks like protection. A parity test asserts `parseManifest(FULL_TEMPLATE).hooks` contains no active runtime-reality entry and that the commented block still exists; mutation-verified (uncommenting the block turns the guard red).
53
+ - **Curated OKF knowledge bundle for harness** (PR #336): eight cross-file concept docs under `docs/okf/` capturing semantics no single source file states: gate fail-posture matrix, evidence-ledger trust boundary, version-sensitive producer wiring, whole-manifest validation scope, understanding-gate lockout recovery, pause-vs-gate-disable kill switches, Codex adapter parity gaps, and debug verb selection. Every claim verified against sources at `f3c1727`; `okf-kit check --strict` clean.
54
+
55
+ ### Changed
56
+
57
+ - **The understanding-gate escape matcher moved to `src/cli/pack/approve-escape.ts`** (PR #337) and is now shared by the hook rather than defined inside it. Beyond the bare `harness approve …` line it accepts exactly one extra shape: a clean command part plus one single-quoted heredoc, terminated by the first line exactly equal to the delimiter (mirroring shell semantics), with nothing but whitespace after it. Single-line behavior is byte-for-byte unchanged.
58
+ - **CI enforces the coverage thresholds it declares** (PR #331). The Test step runs `npm run test:cov` instead of `npm test`, so the 90/90/90/75 lines/functions/statements/branches thresholds in `vitest.config.ts` gate merges instead of silently rotting. Master clears the gate (statements 91.69%, branches 82.57%, functions 93.46%, lines 93.41%); verified the gate trips by locally raising the lines threshold to 100.
59
+
60
+ ### Fixed
61
+
62
+ - **SECURITY: a backslash-escaped redirect could smuggle commands past the understanding gate** (PR #337, found by review before release). `harness approve understanding \<<'UR'` was accepted as a report heredoc by the escape matcher, but bash reads `\<` as a literal `<` followed by a file redirect: no heredoc exists and the "body" lines execute as ordinary shell commands. Reproduced live in bash. The matcher would then emit `permissionDecision: "ask"` on a command visually near-identical to the legitimate one, and under a `Bash(harness approve understanding:*)` allowlist it would have auto-approved the smuggled command with no prompt at all. The heredoc command part is now held to a character whitelist (`/^[A-Za-z0-9_\s,./=:@~-]*$/`) instead of a metacharacter blacklist, so no quoting or escaping trick can change how the shell tokenizes the line. Mutation-verified: removing the whitelist fails exactly the three new exploit tests. Negative tests cover `\<<`, `foo\<<`, `\\<<`, quote-obscured intros, `<(id)`, `>(cmd)`, unquoted/double-quoted/`<<-` delimiters, second redirects, trailing commands, early terminators, unterminated bodies, and CR-in-head.
63
+ - **`addLedgerFact` could lose the tail of a failing MCP server's stderr** (task 5839b59e, PR #329). stderr was captured in the child's `exit` handler, but Node does not guarantee the stderr `data` event fires before `exit`, so the surfaced reason could collapse to `(no stderr)`. Capture on `close` (fires only after all stdio pipes drain), mirroring `ledger-client.ts`'s `queryLedgerByTag`. Also adds a subprocess E2E case asserting the real block/deny envelope from `hook-pre-tool-use.ts`, which was previously only exercised on the allow path.
64
+ - **The test suite runs on macOS** (PR #335): four Darwin-only failure clusters (14 tests), with Linux CI staying green. Tests hardcoding `/bin/true` (absent on macOS) use `/usr/bin/true`; `locateGitContext` / `repoRelativePath` resolve paths to their physical form before relativizing against git's physical work-tree root, which fixes real symlinked-path usage (macOS `/var` → `/private/var`), not just the tests.
65
+ - **Two fixed-window test flakes replaced with readiness handshakes** (PRs #330, #332). The smoke SIGKILL-escalation test spawns its trap child directly and waits for the trap to be installed before handing it to `runSmoke`, so the runner's timeout window only starts once SIGTERM is guaranteed to be swallowed. The io lock concurrency test polls for worker A's `A:lock-acquired` marker instead of assuming a fixed 50ms head start, which under CPU contention let worker B win the first-acquire race and flip the `[A,B]` assertion.
66
+
8
67
  ## [0.39.0] - 2026-07-02
9
68
 
10
69
  **Headline: the 2026-07-01 deep-review remediation ships — enforcement no longer degrades under load, the `grounding:` section finally does something, and `apply --merge` stops eating operator edits.** The PreToolUse gate pools one grounding-mcp session per intercept (a hook timeout no longer silently fail-opens enforcement), `grounding.evidence_ledger.path` now actually configures the grounding-mcp entry, `apply --merge` preserves operator-added mcpServers with provenance, the Codex understanding-gate reaches approval-lifecycle parity with Claude Code, `diff --since` stops reporting override layers as phantom history, and CI gains two architecture fitness gates plus new `validate` lints (git-ignored OW knob, block policies without declared producers). Re-run `npm i -g @lannguyensi/harness` to upgrade.
@@ -0,0 +1,42 @@
1
+ export type StdinReportOutcome = {
2
+ ok: true;
3
+ filePath: string;
4
+ } | {
5
+ ok: false;
6
+ reason: string;
7
+ parseErrorLogPath?: string;
8
+ };
9
+ export interface PersistStdinReportArgs {
10
+ /** The heredoc body: Understanding Report markdown. */
11
+ markdown: string;
12
+ /** Directory the approve flow lists reports from. */
13
+ reportsDir: string;
14
+ /** Resolved session id; stamped onto the persisted JSON. */
15
+ sessionId: string;
16
+ /** Clock injection for deterministic tests. */
17
+ now: Date;
18
+ }
19
+ /** Reports are a few KB; anything beyond this is not a report. */
20
+ export declare const STDIN_REPORT_MAX_BYTES: number;
21
+ export interface PipedStdinResult {
22
+ text: string;
23
+ /**
24
+ * True only when the stream ended cleanly within the size cap. A
25
+ * timeout with partial data, a stream error, or a size-cap hit all
26
+ * yield `complete: false` — the caller must NOT feed such text into
27
+ * the capture path, or a truncated-but-still-parseable report could
28
+ * be persisted and approved as if it were whole (review 2026-07-10).
29
+ */
30
+ complete: boolean;
31
+ }
32
+ /**
33
+ * Read piped stdin fully, with a hang guard. The caller must already
34
+ * have established that stdin is NOT a TTY. The timeout exists because
35
+ * this read sits on the operator-approval path: if some harness wires
36
+ * the CLI to an open-but-idle pipe, a blocked read here would brick
37
+ * approvals — after `timeoutMs` we proceed with whatever arrived
38
+ * (a real heredoc is delivered immediately by the shell), flagged
39
+ * `complete: false`.
40
+ */
41
+ export declare function readPipedStdin(stream: NodeJS.ReadableStream, maxBytes?: number, timeoutMs?: number): Promise<PipedStdinResult>;
42
+ export declare function persistStdinReport(args: PersistStdinReportArgs): StdinReportOutcome;
@@ -0,0 +1,143 @@
1
+ // Report capture for `harness approve understanding` (task 61fd36db).
2
+ //
3
+ // The Understanding Report arrives as a heredoc on the approve command's
4
+ // stdin (see src/cli/pack/approve-escape.ts for why this is the only
5
+ // channel that reliably carries it: the Stop-hook producer fires after
6
+ // approve already ran, and current Claude Code builds do not reliably
7
+ // persist mid-turn assistant text to the transcript JSONL). This module
8
+ // parses the markdown with the canonical parser from
9
+ // `@lannguyensi/understanding-gate` and persists it — session-bound and
10
+ // `pending` — into the same reports directory the Stop hook targets, so
11
+ // the approve flow's existing selection / validation / flip path picks
12
+ // it up via a strict sessionId match.
13
+ //
14
+ // On parse failure it writes a parse-error log in the exact format the
15
+ // standalone Stop hook uses (JSON header incl. sessionId, `--- raw ---`
16
+ // separator, raw markdown), so `findLatestParseError` in
17
+ // approve/understanding.ts surfaces the reason on the `report:` line
18
+ // instead of a silent dead end.
19
+ import * as path from "node:path";
20
+ import { createHash } from "node:crypto";
21
+ import { parseReport } from "@lannguyensi/understanding-gate";
22
+ import { atomicWriteFile } from "../../io/atomic-write.js";
23
+ /** Mirror of the standalone package's slug rule (persistence.ts). */
24
+ function sanitizeSlug(raw) {
25
+ const cleaned = raw.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
26
+ return cleaned.slice(0, 40);
27
+ }
28
+ function summarizeParseError(error) {
29
+ if (error.message.length > 0)
30
+ return error.message;
31
+ const missing = error.missing.length > 0 ? ` (missing: ${error.missing.join(", ")})` : "";
32
+ return `${error.reason}${missing}`;
33
+ }
34
+ /** Reports are a few KB; anything beyond this is not a report. */
35
+ export const STDIN_REPORT_MAX_BYTES = 512 * 1024;
36
+ /**
37
+ * Read piped stdin fully, with a hang guard. The caller must already
38
+ * have established that stdin is NOT a TTY. The timeout exists because
39
+ * this read sits on the operator-approval path: if some harness wires
40
+ * the CLI to an open-but-idle pipe, a blocked read here would brick
41
+ * approvals — after `timeoutMs` we proceed with whatever arrived
42
+ * (a real heredoc is delivered immediately by the shell), flagged
43
+ * `complete: false`.
44
+ */
45
+ export function readPipedStdin(stream, maxBytes = STDIN_REPORT_MAX_BYTES, timeoutMs = 2_000) {
46
+ return new Promise((resolve) => {
47
+ const chunks = [];
48
+ let length = 0;
49
+ let done = false;
50
+ const finish = (complete) => {
51
+ if (done)
52
+ return;
53
+ done = true;
54
+ clearTimeout(timer);
55
+ resolve({
56
+ text: Buffer.concat(chunks).toString("utf8"),
57
+ complete: complete && length <= maxBytes,
58
+ });
59
+ };
60
+ const timer = setTimeout(() => finish(false), timeoutMs);
61
+ // Let a finished CLI exit even if the timer is still pending.
62
+ timer.unref?.();
63
+ stream.on("data", (chunk) => {
64
+ if (done)
65
+ return;
66
+ if (length < maxBytes) {
67
+ const remaining = maxBytes - length;
68
+ chunks.push(chunk.length > remaining ? chunk.subarray(0, remaining) : chunk);
69
+ }
70
+ length += chunk.length;
71
+ });
72
+ stream.on("end", () => finish(true));
73
+ stream.on("error", () => finish(false));
74
+ });
75
+ }
76
+ export function persistStdinReport(args) {
77
+ // Defaults mirror the standalone Stop hook (handle-stop.ts): the
78
+ // report's own `**Metadata**` block wins for any field it declares;
79
+ // these only fill gaps. approvalStatus is forced to "pending" by
80
+ // parseReport regardless of input.
81
+ const result = parseReport(args.markdown, {
82
+ taskId: args.sessionId,
83
+ createdAt: args.now.toISOString(),
84
+ mode: "fast_confirm",
85
+ riskLevel: "medium",
86
+ });
87
+ const stamp = args.now.toISOString().replace(/[:.]/g, "-");
88
+ if (!result.ok) {
89
+ const summary = summarizeParseError(result.error);
90
+ // Same side-channel location + format as the standalone Stop hook:
91
+ // <reportsDir>/../parse-errors/<stamp>.log with a JSON header that
92
+ // carries sessionId (findLatestParseError skips logs it cannot
93
+ // attribute to the approving session).
94
+ const parseErrorDir = path.join(path.dirname(args.reportsDir), "parse-errors");
95
+ const payload = `${JSON.stringify({
96
+ reason: result.error.reason,
97
+ missing: result.error.missing,
98
+ schemaErrors: result.error.schemaErrors,
99
+ message: result.error.message,
100
+ stamp,
101
+ sessionId: args.sessionId,
102
+ source: "harness-approve-stdin",
103
+ }, null, 2)}\n\n--- raw ---\n${args.markdown}\n`;
104
+ let parseErrorLogPath;
105
+ try {
106
+ parseErrorLogPath = path.join(parseErrorDir, `${stamp}.log`);
107
+ atomicWriteFile(parseErrorLogPath, payload);
108
+ }
109
+ catch {
110
+ // Best-effort side channel; the loud `stdin:` line still names the
111
+ // parse failure even when the log write itself fails.
112
+ parseErrorLogPath = undefined;
113
+ }
114
+ return {
115
+ ok: false,
116
+ reason: `report on stdin did not parse: ${summary}`,
117
+ ...(parseErrorLogPath !== undefined ? { parseErrorLogPath } : {}),
118
+ };
119
+ }
120
+ // The standalone package's saveReport cannot be used here: its
121
+ // canonical serializer whitelists the schema keys and would strip the
122
+ // sessionId binding, which is exactly what makes the approve flow's
123
+ // strict match (and the tier-6 session-id fallback) work. Persist the
124
+ // same JSON shape plus `sessionId`, with the package's filename
125
+ // convention (<isoStamp>-<slug>-<hash8>.json) so directory listings
126
+ // read uniformly.
127
+ const persisted = { ...result.report, sessionId: args.sessionId };
128
+ const json = `${JSON.stringify(persisted, null, 2)}\n`;
129
+ const hash = createHash("sha256").update(json).digest("hex").slice(0, 8);
130
+ const slug = sanitizeSlug(result.report.taskId) || "report";
131
+ const filePath = path.join(args.reportsDir, `${stamp}-${slug}-${hash}.json`);
132
+ try {
133
+ atomicWriteFile(filePath, json);
134
+ }
135
+ catch (err) {
136
+ return {
137
+ ok: false,
138
+ reason: `report parsed but could not be persisted to ${filePath}: ${err.message}`,
139
+ };
140
+ }
141
+ return { ok: true, filePath };
142
+ }
143
+ //# sourceMappingURL=stdin-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdin-report.js","sourceRoot":"","sources":["../../../src/cli/approve/stdin-report.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import type { Manifest } from "../../schema/index.js";
2
2
  import { type LoaderOptions } from "../loader.js";
3
+ import { type StdinReportOutcome } from "./stdin-report.js";
3
4
  export interface ApproveUnderstandingOptions extends LoaderOptions {
4
5
  /** Explicit session id (overrides $CLAUDE_CODE_SESSION_ID / $CLAUDE_SESSION_ID / $CODEX_SESSION_ID). */
5
6
  session?: string;
@@ -44,6 +45,16 @@ export interface ApproveUnderstandingOptions extends LoaderOptions {
44
45
  * entries are dropped and duplicates de-duplicated.
45
46
  */
46
47
  tasks?: string[];
48
+ /**
49
+ * Understanding Report markdown captured from the command's stdin
50
+ * (the report-heredoc shape, task 61fd36db). When set and non-blank,
51
+ * it is parsed and persisted as a pending, session-bound report BEFORE
52
+ * the report lookup below, so this very approve run validates and
53
+ * flips it. A parse failure degrades loudly (parse-error log + reason
54
+ * on the result) but does not abort the approval — the operator just
55
+ * approved interactively; a formatting nit must not brick that.
56
+ */
57
+ reportMarkdown?: string;
47
58
  /** Override the reports directory (test injection). */
48
59
  reportsDir?: string;
49
60
  /** Override the harness.generated/ directory (test injection). */
@@ -118,6 +129,15 @@ export interface ApproveUnderstandingResult {
118
129
  * a wrong claim file can be spotted before it lands in the marker.
119
130
  */
120
131
  taskMarkers: TaskMarkerOutcome[];
132
+ /**
133
+ * Outcome of capturing a report passed on stdin (`reportMarkdown`).
134
+ * Absent when no report was supplied. `ok: true` means the markdown
135
+ * parsed and was persisted pending + session-bound; the
136
+ * `persistedReport` result below then reports the flip of that same
137
+ * file. `ok: false` carries the parse/persist failure reason (and the
138
+ * parse-error log path when one was written).
139
+ */
140
+ stdinReport?: StdinReportOutcome;
121
141
  ledger: {
122
142
  ok: boolean;
123
143
  tag: string;
@@ -18,11 +18,13 @@ import * as os from "node:os";
18
18
  import * as path from "node:path";
19
19
  import { atomicWriteFile } from "../../io/atomic-write.js";
20
20
  import { approvedLedgerTagFor, defaultReportsDir, listPersistedReports, readActiveClaim, selectReportForSession, TOLERANT_FALLBACK_MAX_AGE_MS, writeApprovalMarker, writeTaskApprovalMarker, } from "../../policy-packs/builtin/understanding-before-execution-runtime.js";
21
+ import { sha256Hex } from "../../runtime/approval-signing.js";
21
22
  import { addLedgerFact } from "../../runtime/ledger-add.js";
22
23
  import { clearPendingApproval, resolveGeneratedDir, } from "../../runtime/pending-approval.js";
23
24
  import { resolveApprovalSessionId } from "../../runtime/session-id.js";
24
25
  import { EX_FAIL, HarnessExitError } from "../exit-codes.js";
25
26
  import { loadManifest, resolvePaths } from "../loader.js";
27
+ import { persistStdinReport } from "./stdin-report.js";
26
28
  /**
27
29
  * Human-scale age for operator messages: minutes up to two hours,
28
30
  * hours up to two days, then days. A 17-day-old report should read
@@ -358,6 +360,19 @@ export async function approveUnderstanding(opts = {}) {
358
360
  // operator with a bare `ledger: ok false` (no-silent-errors, M8).
359
361
  manifestLoadError = err instanceof Error ? err.message : String(err);
360
362
  }
363
+ // Report capture from stdin (task 61fd36db): persist BEFORE the
364
+ // lookup below so this very approve run selects, validates, and flips
365
+ // the report the agent just attached. Session-bound via the resolved
366
+ // sessionId, so the strict match wins over any stale leftovers.
367
+ let stdinReport;
368
+ if (typeof opts.reportMarkdown === "string" && opts.reportMarkdown.trim().length > 0) {
369
+ stdinReport = persistStdinReport({
370
+ markdown: opts.reportMarkdown,
371
+ reportsDir,
372
+ sessionId,
373
+ now: opts.now ?? new Date(),
374
+ });
375
+ }
361
376
  // Approve-time validation. Resolve the report we would flip BEFORE
362
377
  // writing the marker, so a validation failure can short-circuit every
363
378
  // downstream write. The `latest` + `reports` values are reused later;
@@ -413,6 +428,7 @@ export async function approveUnderstanding(opts = {}) {
413
428
  reason: `validation failed (${validation.field}): ${validation.reason}`,
414
429
  },
415
430
  taskMarkers: [],
431
+ ...(stdinReport !== undefined ? { stdinReport } : {}),
416
432
  ledger: {
417
433
  ok: false,
418
434
  tag: approvedLedgerTagFor(sessionId),
@@ -425,6 +441,31 @@ export async function approveUnderstanding(opts = {}) {
425
441
  validation,
426
442
  };
427
443
  }
444
+ // Report-content hash the marker's signature binds to (harness/f9485cc7):
445
+ // sha256 of the persisted report's raw bytes AT APPROVAL TIME, read
446
+ // BEFORE `rewriteReportApproved` below flips its status/approvedAt/
447
+ // approvedBy fields — this hashes what the operator actually reviewed,
448
+ // not the post-approval-flip artefact. null when no persisted report was
449
+ // resolved (ledger-only / --force paths have nothing to bind).
450
+ //
451
+ // This is GROUNDWORK ONLY, not yet enforced at gate-check time: nothing
452
+ // today cross-checks the hash carried in a signed marker against the
453
+ // CURRENTLY-selected persisted report, so on its own this does not stop
454
+ // a stale-report adoption. The live cross-check ("does this marker's
455
+ // reportContentHash match the report the gate is about to consult right
456
+ // now") is the C1 staleness follow-up (task fa423e9b), out of scope
457
+ // here; this just makes the binding exist and be forensically
458
+ // inspectable so that follow-up can add the comparison without a
459
+ // marker-format change.
460
+ let reportContentHash = null;
461
+ if (latest) {
462
+ try {
463
+ reportContentHash = sha256Hex(fs.readFileSync(latest.filePath, "utf8"));
464
+ }
465
+ catch {
466
+ reportContentHash = null;
467
+ }
468
+ }
428
469
  // Write the canonical approval marker first. The gate consults this
429
470
  // file (not the ledger) since agent-tasks/88ca4bb3 closed the self-
430
471
  // approval backdoor: the agent has direct MCP access to the ledger,
@@ -436,6 +477,7 @@ export async function approveUnderstanding(opts = {}) {
436
477
  const filePath = writeApprovalMarker(generatedDir, sessionId, {
437
478
  approvedAt: approvedAtMarker,
438
479
  approvedBy: approvedByMarker,
480
+ reportContentHash,
439
481
  });
440
482
  markerResult = { ok: true, filePath, approvedAt: approvedAtMarker };
441
483
  }
@@ -477,6 +519,7 @@ export async function approveUnderstanding(opts = {}) {
477
519
  const filePath = writeTaskApprovalMarker(generatedDir, taskId, {
478
520
  approvedAt: approvedAtMarker,
479
521
  approvedBy: approvedByMarker,
522
+ reportContentHash,
480
523
  });
481
524
  taskMarkers.push({
482
525
  ok: true,
@@ -598,6 +641,7 @@ export async function approveUnderstanding(opts = {}) {
598
641
  ...(newestReportPath !== undefined ? { newestReportPath } : {}),
599
642
  marker: markerResult,
600
643
  taskMarkers,
644
+ ...(stdinReport !== undefined ? { stdinReport } : {}),
601
645
  ledger: ledgerResult.ok
602
646
  ? { ok: true, tag }
603
647
  : { ok: false, tag, reason: ledgerResult.reason },
@@ -1 +1 @@
1
- {"version":3,"file":"understanding.js","sourceRoot":"","sources":["../../../src/cli/approve/understanding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"understanding.js","sourceRoot":"","sources":["../../../src/cli/approve/understanding.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,11 @@ export declare function readManifestAtRef(ctx: GitContext, ref: string): string;
8
8
  * Repo-relative path for `absPath` in git's forward-slash form, or null
9
9
  * when the file lives outside the repo work tree (e.g. an override layer
10
10
  * under a ~/.harness home that is not the manifest's repo).
11
+ *
12
+ * Callers pass paths that exist on disk (layers are existsSync-gated at
13
+ * resolve time). A nonexistent path under a symlinked parent would skip
14
+ * realpath resolution and could misreport as outside-repo (null) — null
15
+ * stays the safe, non-crashing failure mode either way.
11
16
  */
12
17
  export declare function repoRelativePath(ctx: GitContext, absPath: string): string | null;
13
18
  /**
@@ -1,6 +1,22 @@
1
1
  import { execFileSync } from "node:child_process";
2
+ import * as fs from "node:fs";
2
3
  import * as path from "node:path";
3
4
  import { EX_UNAVAILABLE, EX_USAGE, HarnessExitError } from "../exit-codes.js";
5
+ // `git rev-parse --show-toplevel` reports the PHYSICAL work-tree path
6
+ // (symlinks resolved), so every path we relativize against that root must
7
+ // be resolved the same way, or `path.relative` climbs out of the repo.
8
+ // Bites on macOS out of the box: os.tmpdir() is /var/folders/…, a symlink
9
+ // to /private/var/folders/…. Nonexistent paths stay merely resolved; the
10
+ // callers' existing not-found error paths own that case.
11
+ function toPhysicalPath(p) {
12
+ const resolved = path.resolve(p);
13
+ try {
14
+ return fs.realpathSync(resolved);
15
+ }
16
+ catch {
17
+ return resolved;
18
+ }
19
+ }
4
20
  function runGit(args, cwd) {
5
21
  return execFileSync("git", args, {
6
22
  cwd,
@@ -9,7 +25,8 @@ function runGit(args, cwd) {
9
25
  });
10
26
  }
11
27
  export function locateGitContext(manifestPath) {
12
- const dir = path.dirname(path.resolve(manifestPath));
28
+ const physicalManifestPath = toPhysicalPath(manifestPath);
29
+ const dir = path.dirname(physicalManifestPath);
13
30
  let root;
14
31
  try {
15
32
  root = runGit(["rev-parse", "--show-toplevel"], dir).trim();
@@ -17,7 +34,7 @@ export function locateGitContext(manifestPath) {
17
34
  catch (err) {
18
35
  throw new HarnessExitError(`git is not available or ${dir} is not inside a git work tree: ${err.message.trim()}`, EX_UNAVAILABLE);
19
36
  }
20
- const relPath = path.relative(root, path.resolve(manifestPath));
37
+ const relPath = path.relative(root, physicalManifestPath);
21
38
  return { root, manifestRelPath: relPath };
22
39
  }
23
40
  export function readManifestAtRef(ctx, ref) {
@@ -33,9 +50,14 @@ export function readManifestAtRef(ctx, ref) {
33
50
  * Repo-relative path for `absPath` in git's forward-slash form, or null
34
51
  * when the file lives outside the repo work tree (e.g. an override layer
35
52
  * under a ~/.harness home that is not the manifest's repo).
53
+ *
54
+ * Callers pass paths that exist on disk (layers are existsSync-gated at
55
+ * resolve time). A nonexistent path under a symlinked parent would skip
56
+ * realpath resolution and could misreport as outside-repo (null) — null
57
+ * stays the safe, non-crashing failure mode either way.
36
58
  */
37
59
  export function repoRelativePath(ctx, absPath) {
38
- const rel = path.relative(ctx.root, path.resolve(absPath));
60
+ const rel = path.relative(ctx.root, toPhysicalPath(absPath));
39
61
  if (rel.startsWith("..") || path.isAbsolute(rel))
40
62
  return null;
41
63
  return rel.split(path.sep).join("/");