Agent Architecture Patterns — CC 2.1 Reference¶
Audience: Skill and agent authors building on the V025-claude-toolkit. Scope: Patterns as implemented in this toolkit, using Claude Code 2.1 (as of March 2026). Attribution: Pattern names draw from Rick Hightower's interpretive design pattern series (Feb 2026). These are community-coined terms for patterns enabled by the CC 2.1 platform, not official Anthropic terminology. Agent-consumable version: For the compact constraint rules used by skill-creation workflows, see
skills/vt-c-create-agent-skills/references/architecture-constraints.md.
Introduction¶
Claude Code 2.1 introduced three features that transform it from a terminal assistant into a composable agent platform:
- Skill hot-reload — SKILL.md files inject domain knowledge on demand
- Lifecycle hooks — Shell scripts, HTTP calls, or LLM prompts fire at 17 event points
- Forked sub-agents —
context: forkcreates isolated execution contexts from skills
This document explains how the V025-claude-toolkit combines these features into five architectural patterns. Each pattern follows a consistent structure: What it is, Why it exists, How it works mechanically, a Toolkit Example with file paths, and known Constraints.
Pattern 1: Hook Hierarchy¶
Also known as: Hook hierarchy (Hightower)
What: Hooks fire at four nested levels, from broadest to narrowest scope.
Why: Governance is cumulative. A global policy (e.g., "never commit to main") must apply even when a project or skill defines its own hooks. No level overrides another — all matching hooks fire.
How: Claude Code resolves hooks from four locations, in order of scope:
graph TD
A["Level 1: Global<br/>~/.claude/settings.json<br/>~/.claude/hooks/"] --> B["Level 2: Plugin / Project<br/>plugins/*/hooks/hooks.json<br/>.claude/settings.json"]
B --> C["Level 3: Skill<br/>SKILL.md frontmatter<br/>hooks: field"]
C --> D["Level 4: Sub-Agent<br/>Agent .md frontmatter<br/>hooks: field"]
style A fill:#1a1a2e,stroke:#e94560,color:#fff
style B fill:#1a1a2e,stroke:#0f3460,color:#fff
style C fill:#1a1a2e,stroke:#16213e,color:#fff
style D fill:#1a1a2e,stroke:#533483,color:#fff
Additive model: When a PreToolUse event fires for the Write tool, all hooks at all levels that match Write execute. A global secret-scanner hook runs alongside a skill-scoped validation hook alongside an agent-scoped block-writes hook.
Priority and blocking: Each hook has a priority number (higher = runs first). If a hook exits with code 1, it blocks the tool call. If it exits with code 2, it provides feedback to the model but does not block.
Toolkit Example — plugins/core-standards/hooks/hooks.json:
{
"PreToolUse": [
{
"matcher": "Write|Edit",
"priority": 100,
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/secret-scanner.sh",
"timeout": 5000
}
]
}
]
}
This is a Level 2 (plugin) hook. It fires on every Write or Edit tool call across the entire project, scanning for hardcoded secrets before any file modification occurs. It runs alongside any global hooks (Level 1) the user has configured.
Constraints: - Hooks at the same level execute in parallel — there is no guaranteed ordering between hooks with different priorities at the same level. - You cannot suppress a higher-level hook from a lower level. Governance is strictly additive.
Pattern 2: Portable Governance (Skill-Scoped Hooks)¶
Also known as: Portable governance (Hightower)
What: Hooks defined in a SKILL.md frontmatter that are active only while that skill is running. When the skill completes, the hooks are cleaned up automatically.
Why: Some validation logic is only relevant during a specific workflow step. A PRD delta check after every file write makes sense during usability validation but would be noise during normal coding. Skill-scoped hooks let you attach governance to a workflow step without polluting the global hook space.
How: Add a hooks: field to the SKILL.md YAML frontmatter. The hooks follow the same format as hooks.json but are scoped to the skill's execution lifetime.
Toolkit Example — plugins/core-standards/skills/vt-c-pd-4-validate/SKILL.md:
---
name: pd-4-validate
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: "echo 'VALIDATION + PRD DELTA CHECK: ...'"
description: Usability testing and validation phase...
---
When a user invokes /vt-c-pd-4-validate, this PostToolUse hook activates. Every Write or Edit during the validation phase triggers a reminder to check PRD deltas. When the skill finishes or the user moves to another skill, the hook is removed.
Use case: Validation logic tied to a specific workflow step. The hook travels with the skill — wherever the skill is installed, the governance follows.
Constraints:
- Skill hooks only fire while the skill is the active context. They do not persist after the skill completes.
- The type: command handler executes a shell command. For LLM-based evaluation, use type: prompt instead.
Pattern 3: Policy Islands (Sub-Agent Hooks)¶
Also known as: Policy island (Hightower)
What: A sub-agent configured with its own hooks, tool restrictions, and permission mode — creating an isolated governance environment. The agent can only do what its configuration explicitly allows.
Why: Review agents must analyze code but never modify it. Without enforcement, a capable LLM might "helpfully" fix issues it finds during review, contaminating the review with unreviewable changes. Policy islands create hard boundaries.
How: Agent .md files use YAML frontmatter to declare hooks, tools, and permissions. The combination of all three creates the "island":
- Hooks — Block specific tool calls (e.g.,
block-writes.shon Write/Edit/Bash) - Tool restrictions — Limit available tools to read-only operations
- Permission mode — Control the agent's autonomy level
Toolkit Example — plugins/core-standards/agents/review/security-sentinel.md:
---
name: security-sentinel
hooks:
PreToolUse:
- matcher: "Edit|Write|Bash"
hooks:
- type: command
command: "~/.claude/hooks/block-writes.sh"
description: Use this agent for security audits...
---
The block-writes.sh script is shared across all 10+ review agents in the toolkit:
#!/bin/bash
# block-writes.sh - Policy enforcement hook for read-only review agents
# Exit code 1 = block the tool call
echo "BLOCKED: This agent is read-only. Review agents must not modify files
or execute commands. Your role is to analyze and report findings only."
exit 1
How it works together: When the security-sentinel agent tries to call Edit, Write, or Bash, the block-writes.sh hook intercepts the call, prints a message the agent can read (explaining why it was blocked), and exits with code 1 (blocking the call). The agent can only use read-only tools like Read, Glob, and Grep.
Review agents using this pattern: All review agents in plugins/core-standards/agents/review/ use block-writes.sh, including security-sentinel, code-simplicity-reviewer, performance-oracle, pattern-recognition-specialist, architecture-strategist, data-integrity-guardian, agent-native-reviewer, angular-reviewer, nestjs-reviewer, kieran-typescript-reviewer, kieran-python-reviewer, julik-frontend-races-reviewer, spec-compliance-reviewer, tdd-compliance-reviewer, api-design-reviewer, and accessibility-reviewer.
Constraints:
- The block-writes.sh path must resolve from the agent's execution context. Use ~/.claude/hooks/ for global scripts or ${CLAUDE_PLUGIN_ROOT}/scripts/ for plugin-scoped scripts.
- Sub-agent hooks are Level 4 (narrowest scope). They stack on top of all broader hooks, never replace them.
Pattern 4: Fork Skills (context: fork)¶
Also known as: Sub-agent constructor (Hightower)
What: A SKILL.md with context: fork in its frontmatter. When invoked, it doesn't inject content into the current conversation — instead, it spawns a new sub-agent that receives the skill content as its system prompt.
Why: Some skills need to run complex multi-step workflows without polluting the main conversation context. A code review skill that dispatches 6 parallel reviewers should run in its own context, not inject all that orchestration logic into the user's chat.
How: The context: fork field in SKILL.md frontmatter changes invocation semantics:
| Field | Purpose |
|---|---|
context: fork |
Spawn a sub-agent instead of injecting into conversation |
agent: <name> |
(Optional) Name a specific agent file to use as the sub-agent |
hooks: |
(Optional) Attach hooks to the forked sub-agent |
allowed-tools: |
(Optional) Restrict which tools the sub-agent can use |
What the sub-agent receives: The full SKILL.md content (everything below the frontmatter) becomes the sub-agent's instructions. The sub-agent does not receive the parent conversation history.
Toolkit Example — plugins/core-standards/skills/workflow-4-review/SKILL.md:
---
name: 4-review
context: fork
description: Phase 4 - Comprehensive code review using the implementation-orchestrator.
---
# Phase 4: Review - Code Quality
Run comprehensive code review with 6 parallel specialized reviewers.
...
When a user runs /vt-c-4-review, Claude Code:
1. Reads the SKILL.md
2. Sees context: fork
3. Spawns a new sub-agent
4. Passes the skill content as the sub-agent's instructions
5. The sub-agent executes independently, then returns its output to the parent
Other fork skills in the toolkit:
- workflow-5-finalize — Final quality verification in isolated context
- mermaid-to-images — Diagram rendering without conversation noise
- pd-4-validate — Usability testing orchestration
- container-logistics-ux-expert — Domain-specific UX evaluation
Error handling pattern (from workflow-4-review): Fork skills should include clear output format instructions, because the parent conversation only sees the sub-agent's final output. Structure the output with delimiters so the parent can parse results reliably.
Constraints:
- Fork skills must never use AskUserQuestion. The sub-agent has no path back to the user for interactive questions. Calling AskUserQuestion from a fork causes the sub-agent to die silently — the parent receives no output. This is the most common fork skill mistake.
- A fork skill with only guidelines (no actionable task) produces empty output. The sub-agent needs a concrete task to execute.
- The sub-agent cannot spawn its own sub-agents (no nesting).
Pattern 5: Queen Agent / Orchestrator¶
Also known as: Queen agent / swarm (Hightower)
What: A central orchestrator agent that dispatches specialized sub-agents via the Agent tool, coordinates their results, and enforces sequential gates between parallel work phases.
Why: Complex workflows like code review require multiple specialized perspectives (security, performance, patterns, simplicity). Running them sequentially is slow. Running them in parallel without coordination is chaotic. The orchestrator pattern provides structured parallelism with quality gates.
How: The orchestrator agent: 1. Runs sequential gate agents first (must pass before proceeding) 2. Dispatches parallel specialist agents simultaneously 3. Collects and aggregates results 4. Makes pass/fail decisions based on combined findings
Toolkit Example — plugins/core-standards/agents/orchestrators/implementation-orchestrator.md:
Sequential gates (must pass):
1. test-runner → Run tests, fail = stop
2. spec-compliance → Check spec requirements, fail = stop
Parallel dispatch (run simultaneously):
3. kieran-typescript-reviewer
4. julik-frontend-races-reviewer
5. code-simplicity-reviewer
6. security-sentinel
7. performance-oracle
8. pattern-recognition-specialist
The SubagentStart and SubagentStop hook events fire when sub-agents are dispatched and complete. These can be used as coordination signals — for example, a hook could log which reviewers have completed.
Other orchestrators in the toolkit:
| Orchestrator | Workflow Phase | Purpose |
|---|---|---|
implementation-orchestrator |
/vt-c-3-build, /vt-c-4-review |
Code quality and review coordination |
product-design-orchestrator |
/pd-0 through /pd-6 |
Design workflow management |
conceptual-orchestrator |
/vt-c-2-plan |
Architecture and planning |
finalization-orchestrator |
/vt-c-5-finalize |
Final quality verification |
bugfix-orchestrator |
/vt-c-6-operate |
Bug investigation coordination |
incident-orchestrator |
/vt-c-6-operate |
Incident response coordination |
knowledge-work-orchestrator |
/kw-0 through /kw-4 |
Documentation and research |
Constraints:
- Sub-agents cannot spawn their own sub-agents. The orchestrator must be the single dispatch point.
- The orchestrator has access to the Agent tool (aliased as Task in frontmatter). Specialist sub-agents typically do not.
- Gate failures should halt the pipeline. The orchestrator is responsible for this logic — there is no built-in gate mechanism.
Pitfalls & Constraints¶
1. Fork + AskUserQuestion = Silent Death¶
Severity: Critical — produces no output, no error.
When a fork skill calls AskUserQuestion, the sub-agent has no communication channel back to the user. The call hangs or fails silently, and the parent receives no output at all. The user sees the skill "complete" with nothing to show.
Rule: Fork skills must never use AskUserQuestion. Design fork skills to be fully autonomous — all parameters must come from the skill content or the codebase, not from user interaction.
2. Hook Ordering is Parallel, Not Sequential¶
Severity: Medium — can cause unexpected behavior.
Hooks at the same level with different priorities do not execute in a guaranteed sequential order. A hook with priority 100 is not guaranteed to complete before a hook with priority 90 starts.
Rule: Do not write hooks that depend on side effects from other hooks at the same level. Each hook should be self-contained.
3. No Sub-Agent Nesting¶
Severity: Medium — blocks multi-level delegation.
Sub-agents cannot spawn their own sub-agents. If an orchestrator dispatches a reviewer, that reviewer cannot dispatch its own helper agents.
Rule: Design orchestrators as flat dispatch points. If you need multi-level delegation, chain sub-agent calls from the orchestrator, not from within sub-agents.
4. Guidelines-Only Fork = Empty Output¶
Severity: Low — confusing but not harmful.
A fork skill that contains only general guidelines without a concrete task (e.g., "follow best practices for X") produces empty output. The sub-agent has instructions but nothing specific to do.
Rule: Fork skills must include actionable execution instructions — a specific task the sub-agent should perform and clear output format expectations.
5. Permission Cascade: bypassPermissions Flows Downward¶
Severity: High — can unintentionally grant broad autonomy.
If a parent agent or skill uses permissionMode: bypassPermissions, all sub-agents it spawns inherit this permission level. You cannot restrict a sub-agent's permissions below the parent's level through the permission system alone.
Rule: Enforce restrictions at the hook level, not the permission level. This is exactly why the block-writes.sh pattern exists — it provides hard enforcement regardless of permission mode.
6. Background Sub-Agent Auto-Deny¶
Severity: Medium — causes unexpected failures.
Sub-agents running in the background automatically deny any permission prompts that are not pre-approved. If a background sub-agent needs to use a tool that requires user approval, it will be denied.
Rule: Either pre-approve necessary tools via bypassPermissions or run the sub-agent in the foreground. If a background agent fails, try resuming it in the foreground.
7. Stop → SubagentStop Conversion¶
Severity: Low — can confuse hook authors.
Stop hooks declared in an agent's frontmatter are automatically converted to SubagentStop events. This is because the agent itself runs as a sub-agent — the Stop event in the sub-agent context is semantically a SubagentStop from the parent's perspective.
Rule: When writing hooks for agent files, be aware that Stop in the frontmatter means "when this sub-agent stops," not "when the parent conversation stops."
Terminology Reference¶
| Hightower Term | Official CC Concept | Toolkit Implementation |
|---|---|---|
| Portable governance | Hooks in SKILL.md frontmatter | hooks: YAML field in SKILL.md (Level 3) |
| Policy island | Agent with scoped hooks + tool restrictions | Agent .md frontmatter + block-writes.sh |
| Sub-agent constructor | context: fork + agent fields in SKILL.md |
SKILL.md frontmatter context: fork |
| Hook hierarchy | Hook locations at multiple scopes | 4 levels: Global → Plugin → Skill → Agent |
| Queen agent / swarm | Orchestrator dispatching via Agent tool | plugins/core-standards/agents/orchestrators/ |
| Inter-agent event bus | SubagentStart/SubagentStop + PostToolUse hooks | Hook events on sub-agent lifecycle |
| Approval fatigue | Default permission prompting on every tool call | CC permission system |
| Zero-prompt execution | permissionMode: bypassPermissions |
Agent frontmatter field |
Note: Hightower's terms are interpretive design pattern names, not official Anthropic terminology. They describe patterns enabled by the CC platform, not prescribed by it.
Further Reading¶
Official Claude Code Documentation¶
- Hooks Reference — 17 hook event types, handler formats, exit code semantics
- Custom Sub-Agents — Agent file format, frontmatter fields, scope/priority
- Skills — SKILL.md format,
context: fork, dynamic context injection
Hightower Articles (Feb 2026)¶
- "Build Agent Skills Faster with Claude Code 2.1 Release"
- "From Approval Hell to Just Do It: How Agent Skills Fork Governed Sub-Agents"
- "Stop Clicking 'Approve': How I Killed Approval Fatigue with Claude Code 2.1"
Toolkit Files Referenced¶
| File | Pattern |
|---|---|
plugins/core-standards/hooks/hooks.json |
Hook Hierarchy (Level 2) |
plugins/core-standards/scripts/block-writes.sh (plugin-scoped) or ~/.claude/hooks/block-writes.sh (global) |
Policy Islands |
plugins/core-standards/scripts/secret-scanner.sh |
Hook Hierarchy (Level 2) |
plugins/core-standards/agents/review/security-sentinel.md |
Policy Islands |
plugins/core-standards/skills/workflow-4-review/SKILL.md |
Fork Skills |
plugins/core-standards/skills/vt-c-pd-4-validate/SKILL.md |
Portable Governance |
plugins/core-standards/skills/vt-c-mermaid-to-images/SKILL.md |
Fork Skills |
plugins/core-standards/agents/orchestrators/implementation-orchestrator.md |
Queen Agent |