Each admin handler called requireInstanceAdmin itself, some through adminRepo, and nothing caught a new one that forgot. Dispatch now refuses any admin command for a non-admin before the handler runs; the per-handler checks stay as belt and braces. The host-local gitbayd admin path dispatches as a synthetic admin and is unaffected.
Two registry tests: TestAdminNounGatedInDispatch dispatches every admin command as a non-admin and expects exit 4; TestStdinCommandsReadStdin asserts a command whose usage mentions stdin sets ReadsStdin, the gotcha from CLAUDE.md that nothing enforced.
Stacked on !195; no code dependency.
Closes #127
retargeted from git-end-of-options to main: !195 merged
2026-09-03 18:47 UTC