voyage/tests/hooks
Kjell Tore Guttormsen 2844400a00 test(cap-hook): cover the crash-time marker branches and EXECUTE the marker snippet
Two gaps, both test-side. No production behaviour changes here: the
branches were already correct, they were simply unpinned, so a later edit
could have broken them silently.

1. Crash-time states the hook header's TTL discussion anticipates and no
   test exercised: a partially written marker (valid prefix, no close - what
   an interrupted printf leaves), a marker with no runId, a marker whose
   runId is empty or not a string, and malformed ledger lines. All must
   ALLOW, because a marker we cannot read cannot say which run we are in,
   and a half-written ledger line is not a spent turn. One test pins the
   other direction too: skipping bad lines must not mean skipping the run's
   tombstone.

2. The marker snippet is now RUN, not asserted about. Every existing pin on
   the marker lifecycle (tests/lib/doc-consistency.test.mjs) is a substring
   assertion on prose, so a snippet emitting invalid JSON or writing to a
   path the hook never reads would keep the whole suite green while the hook
   allowed everything - the failure S82 had to find by hand with a
   scratchpad probe. Three tests now extract the real ```bash blocks from
   commands/trekresearch.md and execute them with CLAUDE_PLUGIN_DATA
   stripped and HOME sandboxed:
     - the write snippet lands parseable JSON at the exact path the hook
       looks up, with runId and a Date.parse-able startedAt;
     - an empty CLAUDE_CODE_SESSION_ID produces NO `.json` marker and says
       the cap stays inert;
     - write snippet -> real hook denies -> removal snippet -> real hook
       allows, which is the writer/reader agreement end to end.

On the non-string runId: it clears the falsy guard and then matches no
ledger record, so the run reads as 0 turns and is allowed. Allow is correct
either way and no writer emits one, so that stays a pin on the outcome
rather than an argument for a type guard on an unreachable state.

Review finding 823d8c28d7c993717606433fd6711d5a67877967 (MINOR).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LuGhWAbWyRFBFeemfhxoVv
2026-08-12 23:04:25 +02:00
..
agent-cap.test.mjs test(cap-hook): cover the crash-time marker branches and EXECUTE the marker snippet 2026-08-12 23:04:25 +02:00
bash-guard.test.mjs fix(hooks): close the bypasses anchoring opened in the destructive-command rule 2026-08-12 22:03:22 +02:00
hooks-json-stop-wired.test.mjs chore(voyage): W3 hardening (S2) — exec-form hooks, enforced disallowed-tools, F2 decision 2026-06-18 12:03:11 +02:00
otel-export-otlp.test.mjs feat(voyage): add lib/exporters/otlp-format.mjs — OTLP/JSON enum-integer SC #13 2026-05-09 09:32:29 +02:00
otel-export-textfile.test.mjs feat(trekresearch): emit and export the five STORM measurement fields 2026-08-09 15:01:15 +02:00
otel-export-token-capture.test.mjs feat(observability): opt-in token capture in Stop hook (VOYAGE_TOKEN_METER) 2026-06-26 14:42:58 +02:00
otel-export-validators.test.mjs fix(exporters): allowlist trekresearch engine field and pin schema fixture agreement 2026-08-09 13:04:47 +02:00
otel-export.test.mjs feat(voyage): add hooks/scripts/otel-export.mjs — Stop-hook orchestration SC #14, opt-in via VOYAGE_EXPORT_MODE 2026-05-09 09:44:13 +02:00
path-guard.test.mjs test(ultraplan-local): add path-guard + bash-guard baseline hook tests (SC8 baseline) 2026-05-04 08:55:49 +02:00
post-compact-flush.test.mjs feat(ultraplan-local): add PostCompact rehydrate hook to re-inject session-state after compaction 2026-05-04 07:57:42 +02:00
worktree-guard.test.mjs feat(ultraplan-local): harden Phase 2.6 wave executor (11 sub-changes for plugin-in-monorepo + gitignored-state topology) 2026-05-04 07:49:45 +02:00