refactor(hooks): share one telemetry-sink test helper across the 14 inline suites - #5373
Conversation
…ct suite Refs #3412 lib/hook-test-sink.sh holds the make_sink and wait_for_sink pair that 14 hook suites each define inline, with the real HOOK_TELEMETRY_SINK contract in its header: one executable path, never a command with arguments. make_sink returns 2 with a message when $WORK is not a directory. wait_for_sink polls in 20ms steps and returns 1 when the tries bound runs out. lib/hook-test-sink.test.sh covers the contract: a single-path stub that captures stdin, a sink that never fires failing the wait within the bound, a command-with-args sink delivering nothing through hook::emit_telemetry while the stub delivers, and the tries bound. The suite runs in the hook-utils lane beside lib/hook-utils.test.sh. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ng plugins Refs #3412 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each suite drops its own make_sink/wait_for_sink pair (and the autonomy wait_sink alias) and sources the sibling hook-test-sink.sh. File-capturing call sites now pass an explicit body (`cat >"$FILE"`, append form in the autonomy suite); lib/hook-utils.test.sh passes its 750-poll bound at every wait_for_sink call and now owns a WORK directory it removes on exit, so its sink stubs no longer accumulate in TMPDIR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ll-test-helpers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test-only change: the suites use the shared telemetry-sink test helper vendored from lib/hook-test-sink.sh. No behavior change. Refs #3412 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @kyle-sexton's task in 58s —— View job Security review
No security issues found. This PR is a pure test-infrastructure refactor: it extracts the
No injection, authorization, credential-handling, or trust-boundary concerns identified in this diff. |
|
Claude finished @kyle-sexton's task in 3m 25s —— View job Code review complete
No blocking findings. This is a clean, well-executed mechanical refactor. Verified independently (not just author-claimed):
Two things noted but not worth blocking on:
Not independently verified here (sandbox denied running Branch: 🤖 Generated with Claude Code |
Closes #3410 ## Summary `envelope.schema.json` had no executing consumer, and eleven hook test suites each carried a hand-transcribed copy of its required-field list (12 loops). This makes the schema the single source of the field list and replaces every copy with one shared check. ## Fix - `lib/hook-test-sink.sh` (canonical, vendored byte-identical to `plugins/*/hooks/hook-test-sink.sh`) gains `check_envelope`, which reads the required fields and types from `docs/conventions/hook-telemetry/envelope.schema.json`. - `lib/hook-test-sink.test.sh` asserts the check is non-vacuous: deliberately malformed envelopes fail it. - All 12 transcribed `for field in schema_version ...` loops (`lib/hook-utils.test.sh` x2 and ten plugin suites) are replaced by one `check_envelope` assertion each; the per-suite stdout-parity assertions are untouched. - Docs (`hook-telemetry`, `shell-test-helpers` READMEs) state that the schema is executed by `check_envelope`. - Patch bump and CHANGELOG entry for each of the 12 touched plugins (test-only, no behavior change). ## Verification - `lib/hook-test-sink.test.sh`: PASS=57 FAIL=0 - `lib/hook-utils.test.sh`: PASS=576 FAIL=0 - Plugin suites (actionlint, bash-format, biome-format, desktop-notification, eol-normalizer, go-format, markdown-format, powershell-format, ruff-format, typos-format): all FAIL=0. ruff-format failed 1 assertion on one run and passed 61/0 on rerun; not reproduced. - `scripts/check-changelog-parity.sh --check --check-order`: pass - `scripts/validate-plugins.sh`: all manifests and catalog validated - `grep -rn "for field in schema_version"` over `*.sh`: no matches ## Related - Acceptance criteria met: schema executed by the shared check; transcribed loops replaced; malformed envelope fails the check. - Home for shared test code was settled by #3412 (merged in #5373), per the owner decision on #3410. - Failure mode motivating the change: #3394. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Closes #3412
Summary
Fourteen hook test suites in 12 plugins each defined their own
make_sink/wait_for_sinkpair. They now source one helper, canonical atlib/hook-test-sink.shand carried byte-identical atplugins/<p>/hooks/hook-test-sink.sh(plugins do not import siblings). A contract suite,lib/hook-test-sink.test.sh, pins the helper's behavior.Fix
lib/hook-test-sink.shandlib/hook-test-sink.test.sh; wire the suite in thehook-utilsCI job.scripts/cross-plugin-source-registry.txt, gated bycheck-cross-plugin-source-drift.sh.docs/conventions/shell-test-helpers/README.mdto the decided rule.Verification
lib/hook-test-sink.test.shpass with FAIL=0 and unchanged assertion counts, after merging currentmain.check-cross-plugin-source-drift.sh --check,check-changelog-parity.sh --checkand--check-bump origin/mainpass.ok/bad/failline is deleted in the suite diffs.test-windows.yml(Git Bashenv -icannot be verified here).Related
#3410, #3408, #3411, #5313
🤖 Generated with Claude Code