fix(#4076): add missing gsd-hook-version header to gsd-node-runner.sh (#4092)

* 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 <trekkie@nomorestars.com>
This commit is contained in:
Carlos Cativo
2026-09-02 06:04:37 -06:00
committed by GitHub
parent b0572c0108
commit 9b77320580
4 changed files with 66 additions and 4 deletions

View File

@@ -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 <resolver>
// <baked-node> <script>) so node resolves at hook-fire time in every
// environment sharing the config root. Staged verbatim — no templating.
// Portable node resolver (#3662). Managed JS hook commands under
// --portable-hooks route through it (bash <resolver> <baked-node>
// <script>) so node resolves at hook-fire time in every environment
// sharing the config root. It IS registered in MANAGED_HOOKS
// (managed-hooks-registry.cjs) for staleness tracking like every other
// shipped .sh hook, and install.js stamps its {{GSD_VERSION}} header the
// same way (#4076 — the prior comment here claimed the opposite on both
// counts, which is why the header was missing and staleness detection was
// permanently broken for this file).
'gsd-node-runner.sh',
// Graphify auto-update hook (#3347 / PR #3557 / #3579). Opt-in via
// .planning/config.json graphify.auto_update; off by default.