main.go answered an unknown or missing hook name with a non-zero exit. Claude
Code reads exit 2 from a PreToolUse hook as "block this tool call", so a
hooks.json naming a hook the compiled binary does not have took out the matched
tool in EVERY running session on the host, not just the one doing the rebuild.
This plugin wires one PreToolUse hook.
That skew is routine rather than exotic: bin/hooks is a committed prebuilt
binary CI does not rebuild, and oleks-local is a directory source, so a live
session sees an edited hooks.json the instant it is written, against whatever
binary is on disk.
- failopen.go: unknown/missing entry point prints a loud `unknown-entry-point:`
diagnostic to stderr naming the key and every registered name, then exits 0.
stderr is the right channel: surfaced to the user, blocks nothing.
- failopen.go: `list` subcommand prints the registered entry points, so tooling
can still detect a skew now that it cannot read one off a non-zero exit.
- failopen_test.go: end-to-end tests on the built binary — the property under
test is the process exit status, which a function-level test cannot see.
Third independent occurrence of this defect fleet-wide, after
oleks/claude-plugin-anxious#182 and kotkan/claude-plugin-decision-flow#85; the
shared root is the hooks-to-go template every port copied
(oleks/claude-plugin-hooks-to-go#30).
Verified before/after on the same probe: `bin/hooks not-a-real-hook` exited 2,
now exits 0 with the marker on stderr. go test passes.