feat(agents+installer): narrowing-role subagents (Phase 5) + spellbook-cco fork wiring (Phase 7)#284
Merged
Merged
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Ships Work Item 5 of the security architecture: 9 narrowing-role subagent definitions in
agents/plus a symlink-based discovery installer that bridges$SPELLBOOK_DIR/agents/to$CLAUDE_CONFIG_DIR/agents/, since Claude Code 2.1.x discovers agents only from the latter.Related issue
Checklist
What this branch ships
agents/:implementer,web-researcher,git-committer,git-pusher,pr-creator,pr-merger,jira-reader,jira-mutator,test-runner. Each declares a narrowingtools:list — the effective tool set is(parent_tools ∩ frontmatter_tools)— so a subagent can never gain a capability the parent does not already hold.installer/components/agents.py): idempotentinstall_agents/uninstall_agentsthat symlink$SPELLBOOK_DIR/agents/*.mdinto$CLAUDE_CONFIG_DIR/agents/. Wired intoinstaller/platforms/claude_code.pyper-config-dir loop. User-authored agent files at the target path are preserved; only spellbook-pointing symlinks (including broken ones) are removed on uninstall.tests/test_security/test_agent_frontmatter.py): enforces the canonical 5-section body contract (Purpose / Tools / Output Schema / Guardrails / Constraints) and SHA-256-snapshots the existing 7 agents to catch unintended modification.tests/installer/test_agents_symlink.py): all idempotence branches (unchanged / upgraded / skipped-user-symlink / skipped-user-regular-file / installed) and uninstall safety (only removes spellbook-pointing symlinks; preserves user files).Why the scope was reframed
Two pre-implementation verification spikes (Sec 9.1 and 9.2) corrected the original framing:
tools:in agent frontmatter is a narrowing list, not a capability granter. The original "capability escalation" framing was dead on arrival; this branch ships narrowing-role agents instead.$SPELLBOOK_DIR/agents/— discovery is rooted at$CLAUDE_CONFIG_DIR/agents/. Hence the symlink installer step.Drive-by fix (test isolation)
tests/test_hooks/test_memory_auto_store.pyhad a latent test-order bug:STOP_HARVEST_CACHE_PATHwas bound to a real~/.local/spellbook/cache/...file at import time, which let pytest tmp-dir reuse silently short-circuit_handle_stopvia the idempotency cache. Added anautouse=Trueclass fixture that rebinds the cache path per-test and forcesfeature_enabled("transcript_harvest")to False, immunizing the regex-path tests from worker-LLM config leakage.Deferred / out of scope
claudesmoke test in a freshCLAUDE_CONFIG_DIR=$(mktemp -d)— operator post-merge verification.web-researcheris authored with the correcttools:list but explicitly flagged in its body as requires WI-8 (devcontainer) before being safe to dispatch in production.code-reviewerandjustice-resolveragents intotools:-frontmatter compliance — separate cleanup task per the brief.Verification
tests/test_security/test_agent_frontmatter.py+tests/installer/test_agents_symlink.py.tools:mapping for all 9 new agents (parametrized overEXPECTED_NEW_AGENTS); byte-snapshot test guards the 7 existing agents.L4,tier classifier,tier-based,capability escalation,WI-4) and forbidden-claim scans (no over-attribution of git/gh subcommand blocks to the bash gate) both clean.