PreToolUse hooks route through kei-capability check when orchestrator registers a capability via KEI_CAPABILITY_NAME env var on agent spawn. hooks/agent-capability-check.sh (22 LOC): - Pass-through (exit 0) when KEI_CAPABILITY_NAME unset — no-op by default - Fail-open (exit 0) when kei-capability binary missing — kit convention - Sources _lib/gate.sh for KEI_DISABLED_HOOKS / KEI_HOOK_PROFILE respect - exec kei-capability check "$CAP_NAME" when active hooks/agent-capability-verify.sh (24 LOC): - Orchestrator-driven, NOT a Claude Code native hook - Carries env: AGENT_ID, TASK_TOML, WORKTREE_PATH, MAIN_REPO, RUN_MODE - exec kei-capability verify "$CAP_NAME" Registered in hooks/hooks.json + settings-snippet.json under both PreToolUse:Bash and PreToolUse:Edit|Write matchers. Internal NotApplicable returns exit 0 so non-matching tool calls cost nothing. install.sh unchanged — hooks/*.sh glob picks up both new files. tests/hook_wiring_integration.sh (64 LOC) — 3 contract assertions: (1) pass-through on unset KEI_CAPABILITY_NAME (2) deny+exit 2 on git-op pattern (3) allow+exit 0 on cargo-check pattern Multi-capability routing (for phase 5): KEI_CAPABILITY_NAME currently holds ONE name. When a role requires N capabilities, orchestrator will either iterate or kei-capability gains a compose subcommand. Design note left for phase 5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
27 lines
1.1 KiB
Bash
Executable file
27 lines
1.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# agent-capability-check.sh — 3-line hook glue (Agent Substrate v1, phase 4).
|
|
#
|
|
# Claude-Code hook adapter that routes a PreToolUse event (Bash|Edit|Write)
|
|
# to `kei-capability check <capability-name>`. The capability name is set
|
|
# per-agent by the orchestrator via env $KEI_CAPABILITY_NAME at Agent spawn
|
|
# time; Claude Code's hook protocol has no per-spawn scoping, so this script
|
|
# NO-OPs (exit 0, pass-through) when the env var is unset.
|
|
#
|
|
# Fail-open convention (RULE 0.13, kit-wide): a missing kei-capability
|
|
# binary MUST NOT block all tool use — it exits 0 with a stderr note.
|
|
# Block semantics come from the gate logic itself (exit 2 on Deny), never
|
|
# from adapter absence.
|
|
#
|
|
# See docs/AGENT-SUBSTRATE-SCHEMA.md §File layout / §Verify execution.
|
|
set -eu
|
|
|
|
_KEI_LIB="$(dirname "$0")/_lib/gate.sh"
|
|
if [ -r "$_KEI_LIB" ]; then . "$_KEI_LIB"; kei_hook_gate "agent-capability-check" || exit 0; fi
|
|
|
|
CAP="${KEI_CAPABILITY_NAME:-}"
|
|
[ -z "$CAP" ] && exit 0
|
|
command -v kei-capability >/dev/null 2>&1 || {
|
|
echo "[agent-capability-check] kei-capability binary not in PATH — fail-open pass-through" >&2
|
|
exit 0
|
|
}
|
|
exec kei-capability check "$CAP"
|