From 9b77320580adc296aed017edd0550163ece72abb Mon Sep 17 00:00:00 2001 From: Carlos Cativo Date: Wed, 2 Sep 2026 06:04:37 -0600 Subject: [PATCH] fix(#4076): add missing gsd-hook-version header to gsd-node-runner.sh (#4092) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(#4076): add missing gsd-hook-version header to gsd-node-runner.sh gsd-node-runner.sh was registered in MANAGED_HOOKS but shipped without a gsd-hook-version header, so gsd-check-update-worker.js always classified it as 'definitely stale' (a missing header is indistinguishable from a pre-version-tracking file). Every install on an otherwise up-to-date version showed a permanent, unclearable '⚠ stale hooks — run /gsd-update' warning naming this one file. Root cause: the build-hooks.js comment claimed the file is 'not a registered hook' and 'staged verbatim — no templating', but it IS in MANAGED_HOOKS (managed-hooks-registry.cjs:34) and install.js already stamps {{GSD_VERSION}} into every .sh hook unconditionally, gsd-node-runner.sh included. The comment contradicted both the registry and the installer's actual behavior, and the header line itself was simply never added. Fix: add the header (matching every other managed .sh hook's format) and correct the comment so it no longer asserts the opposite of what the registry and installer actually do. Adds a regression test that iterates every MANAGED_HOOKS entry and asserts it carries a header matching the worker's own detection regex, so a future hook added to the registry without one fails CI instead of shipping silently. Fixes #4076 * chore(#4076): add changeset fragment for PR #4092 * fix(#4076): address review nits — drop unneeded exemption, fix blank line Per @trek-e's review on #4092: - tests/managed-hooks.test.cjs:96: the readFileSync call uses a loop variable (entry-derived hookPath), not a literal path, so local/no-source-grep's static literal-path detector never flags it — the allow-test-rule exemption comment was unnecessary. Replaced with a plain note explaining the source-read rationale. - tests/managed-hooks.test.cjs:121-122: dropped a stray extra blank line before the bug #2136 section divider. --------- Co-authored-by: Tom Boucher --- .changeset/graceful-finches-wake.md | 5 +++ hooks/gsd-node-runner.sh | 1 + scripts/build-hooks.js | 13 +++++--- tests/managed-hooks.test.cjs | 51 +++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 .changeset/graceful-finches-wake.md diff --git a/.changeset/graceful-finches-wake.md b/.changeset/graceful-finches-wake.md new file mode 100644 index 000000000..0a3643eac --- /dev/null +++ b/.changeset/graceful-finches-wake.md @@ -0,0 +1,5 @@ +--- +type: Fixed +pr: 4092 +--- +**`gsd-node-runner.sh` no longer triggers a permanent, unclearable "⚠ stale hooks" warning** — it was registered in `MANAGED_HOOKS` but shipped without its `gsd-hook-version` header, so up-to-date installs always flagged it as stale. diff --git a/hooks/gsd-node-runner.sh b/hooks/gsd-node-runner.sh index 77910efaa..787fae064 100755 --- a/hooks/gsd-node-runner.sh +++ b/hooks/gsd-node-runner.sh @@ -1,4 +1,5 @@ #!/bin/sh +# gsd-hook-version: {{GSD_VERSION}} # gsd-node-runner.sh — GSD portable node resolver (#3662). # # Managed JS hook commands under --portable-hooks route through this script: diff --git a/scripts/build-hooks.js b/scripts/build-hooks.js index 228d9aab9..59e4a97e3 100644 --- a/scripts/build-hooks.js +++ b/scripts/build-hooks.js @@ -71,10 +71,15 @@ const HOOKS_TO_COPY = [ 'gsd-session-state.sh', 'gsd-validate-commit.sh', 'gsd-phase-boundary.sh', - // Portable node resolver (#3662). Not a registered hook itself: managed JS - // hook commands under --portable-hooks route through it (bash - //