Problem
The post-commit hook's npx fallback runs without secret injection, so journal generation fails silently in any repo that does not have a local node_modules/commit-story entry.
scripts/install-hook.sh has two invocation paths. Line numbers below are as of 981b043 (2026-07-21) — match on the code rather than the line if it has moved.
The intended path wraps the call in vals:
# line 105
env -u ANTHROPIC_CUSTOM_HEADERS -u ANTHROPIC_BASE_URL vals exec -f "$REPO_ROOT/.vals.yaml" -- node "${NODE_ARGS[@]}"
The fallback does not:
# line 83
env -u ANTHROPIC_CUSTOM_HEADERS -u ANTHROPIC_BASE_URL npx commit-story
It strips the gateway variables but never injects ANTHROPIC_API_KEY, so it depends on that variable already being in the environment.
Why the fallback gets taken. find_package_dir checks three things: whether the current repo is commit-story, whether $repo_root/node_modules/commit-story is a symlink, and whether it is a directory. It does not check the global npm link. In wiggitywhitney/claude-config, commit-story was globally linked — npm root -g gives /opt/homebrew/lib/node_modules/commit-story -> commit-story-v2 — but there was no local node_modules entry, so PKG_DIR came back empty and the hook fell through to npx.
Why it stayed hidden. ANTHROPIC_API_KEY is present in an interactive terminal but absent inside a Claude Code session, where Datadog-managed settings authenticate via apiKeyHelper rather than a raw key. Hand-made commits journaled correctly; commits made from inside a session did not. The hook backgrounds its work and exits 0, so git reported success either way and no error surfaced.
Observed impact. In claude-config, src/utils/config.js:9 threw ANTHROPIC_API_KEY environment variable is required before anything was written — no journal/entries/2026-08/ directory existed at all. 48 commits since the last successful entry on 2026-07-06 have no journal entry.
Adding vals to the fallback is not sufficient on its own. vals exec hands its child an environment with no PATH:
$ vals exec -f .vals.yaml -- node -p "process.env.PATH"
undefined
A resolved binary like node runs fine, which is why line 105 works. But npx is a script with an env-based shebang, so under vals it fails with env: node: No such file or directory. Confirmed by running the vals-wrapped fallback directly.
Solution
Make the hook reach its working code path rather than depending on ambient environment variables, and consider whether generation failures should be visible.
Directions to choose between:
- Teach
find_package_dir to resolve a globally linked package, e.g. via npm root -g, so the working node + vals path is used when only a global link exists.
- Make the fallback independent of
PATH by invoking node on an absolute resolved path instead of npx. If the fallback keeps npx, it needs both vals and a restored PATH.
- Decide whether the hook should surface a generation failure rather than exiting 0. Silent success is what allowed this to persist for roughly a month across 48 commits.
Local workaround already applied in claude-config (not a fix for this repo): npm link commit-story, which creates the node_modules entry find_package_dir looks for. Verified — a journal entry generated, along with the backlogged daily, weekly, and monthly summaries.
Acceptance Criteria
Scope of what was actually verified
Only claude-config demonstrated this failure. Do not assume it is repo-wide.
spinybacked-orbweaver has no journal/entries/2026-08/ directory and looks affected, but it is not — there have been no commits there since 2026-07-29, so there was nothing to journal. That distinction cost time during diagnosis: a missing month directory is explained equally well by "generation is broken" and by "no commits in that month," and only the second is true there. Check commit activity before treating an absent directory as evidence.
No other repos were examined. Whether repos beyond claude-config lack the local package link is unknown.
Checklist
Problem
The post-commit hook's npx fallback runs without secret injection, so journal generation fails silently in any repo that does not have a local
node_modules/commit-storyentry.scripts/install-hook.shhas two invocation paths. Line numbers below are as of981b043(2026-07-21) — match on the code rather than the line if it has moved.The intended path wraps the call in vals:
The fallback does not:
# line 83 env -u ANTHROPIC_CUSTOM_HEADERS -u ANTHROPIC_BASE_URL npx commit-storyIt strips the gateway variables but never injects
ANTHROPIC_API_KEY, so it depends on that variable already being in the environment.Why the fallback gets taken.
find_package_dirchecks three things: whether the current repo is commit-story, whether$repo_root/node_modules/commit-storyis a symlink, and whether it is a directory. It does not check the global npm link. Inwiggitywhitney/claude-config, commit-story was globally linked —npm root -ggives/opt/homebrew/lib/node_modules/commit-story -> commit-story-v2— but there was no localnode_modulesentry, soPKG_DIRcame back empty and the hook fell through to npx.Why it stayed hidden.
ANTHROPIC_API_KEYis present in an interactive terminal but absent inside a Claude Code session, where Datadog-managed settings authenticate viaapiKeyHelperrather than a raw key. Hand-made commits journaled correctly; commits made from inside a session did not. The hook backgrounds its work and exits 0, so git reported success either way and no error surfaced.Observed impact. In claude-config,
src/utils/config.js:9threwANTHROPIC_API_KEY environment variable is requiredbefore anything was written — nojournal/entries/2026-08/directory existed at all. 48 commits since the last successful entry on 2026-07-06 have no journal entry.Adding vals to the fallback is not sufficient on its own.
vals exechands its child an environment with noPATH:A resolved binary like
noderuns fine, which is why line 105 works. Butnpxis a script with anenv-based shebang, so under vals it fails withenv: node: No such file or directory. Confirmed by running the vals-wrapped fallback directly.Solution
Make the hook reach its working code path rather than depending on ambient environment variables, and consider whether generation failures should be visible.
Directions to choose between:
find_package_dirto resolve a globally linked package, e.g. vianpm root -g, so the workingnode+ vals path is used when only a global link exists.PATHby invokingnodeon an absolute resolved path instead ofnpx. If the fallback keepsnpx, it needs both vals and a restoredPATH.Local workaround already applied in claude-config (not a fix for this repo):
npm link commit-story, which creates thenode_modulesentryfind_package_dirlooks for. Verified — a journal entry generated, along with the backlogged daily, weekly, and monthly summaries.Acceptance Criteria
node_modules/commit-storypresent.vals.yamlwhen that file is presentANTHROPIC_API_KEYbeing inherited from the ambient environmentScope of what was actually verified
Only
claude-configdemonstrated this failure. Do not assume it is repo-wide.spinybacked-orbweaverhas nojournal/entries/2026-08/directory and looks affected, but it is not — there have been no commits there since 2026-07-29, so there was nothing to journal. That distinction cost time during diagnosis: a missing month directory is explained equally well by "generation is broken" and by "no commits in that month," and only the second is true there. Check commit activity before treating an absent directory as evidence.No other repos were examined. Whether repos beyond
claude-configlack the local package link is unknown.Checklist