The plugin now carries the two hooks Mathias owns and the brain/gitea/infra
MCP server definitions, not just skills.
Why this matters more than tidiness: both hooks existed ONLY in koala's
~/.claude/, which is host-local and unsynced. flamingo and iguana have been
running with no secret-guard at all — that is the control which blocks the
decrypt-and-print shape behind the 2026-08-05 ntfy-token leak, the op-item-get
shape behind 2026-07-30, and the base64-bypass shape behind 2026-06-11. Its
absence on two of three machines is a security gap, not a config gap. Shipping
it in the plugin means installing the plugin installs the guard.
.mcp.json references tokens as ${BRAIN_MCP_TOKEN} / ${GITEA_MCP_TOKEN} only —
env indirection, never literal values, so the manifest is safe to commit.
tests/secret_guard_test.sh pins 14 cases. It asserts on
hookSpecificOutput.permissionDecision, NOT exit status: the guard always exits
0 by contract, so an exit-status assertion would pass vacuously while the guard
silently allowed everything. Each deny case names the incident that produced it.
gsd-* hooks are deliberately NOT migrated — GSD owns and updates those in place.
Bump-Type: minor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m
28 lines
518 B
JSON
28 lines
518 B
JSON
{
|
|
"hooks": {
|
|
"UserPromptSubmit": [
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/pre-task-ritual.sh\"",
|
|
"timeout": 5
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"PreToolUse": [
|
|
{
|
|
"matcher": "Bash",
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/secret-guard.sh\"",
|
|
"timeout": 5
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|