17 KiB
Delegation Router + Skill Model — Pi Design
Date: 2026-06-24 Design by: Pi Builds by: Claude (Claude side) + Pi (Pi side, extensions) Approves: Kisa Frame: Hybrid 3-tier skill model is locked. This design covers:
- Claude-side trigger (UserPromptSubmit hook)
- Dispatch threshold sharpening
- Pi-side mirror (extension + pi-subagents routing)
- Two cross-readable process skills: delegation discipline + design-review/persist
1. Claude-Side Trigger (UserPromptSubmit Hook)
Keyword / Heuristic Set
The hook does a single grep/regex pass over the user's prompt. Fires when a prompt is task-shaped — meaning it asks for construction, analysis, change, or investigation — while NOT firing on conversation, one-liners, simple lookups, or casual chat.
Trigger patterns (any one match fires the check):
# Build / deploy / implement
\b(build|create|write|implement|deploy|set up|add|make|generate|produce)\b
# Fix / change / refactor
\b(fix|change|update|refactor|rewrite|migrate|convert|replace|remove|delete|rename|restructure)\b
# Design / plan / architecture
\b(design|plan|architect|redesign|propose|spec|blueprint|outline)\b
# Research / audit / analyze
\b(research|audit|review|analyze|investigate|evaluate|assess|compare|diagnose)\b
# Multi-step indicators
(and then|first.+then|step \d|phase \d|stage \d|sequence|workflow)
# Multiple files or cross-domain
(multiple files|several files|across|spans|both|multi-step)
Suppression patterns (prevents false positives):
# Pure conversation
^(hi|hey|hello|thanks|ok|good|yes|no|sure|got it|understood)[.!]?$
# One-line lookup
\b(what is|who is|where is|when is|define|meaning of)\b.+\?$
# Simple confirmations
\b(ok|sounds good|works for me|make sense|let's do it|go ahead|proceed|approved)\b$
Logic: If trigger patterns match AND no suppression pattern matches, inject the dispatch reminder. Return value false by default.
Injected Text (one line)
⏺ [dispatch-check] This prompt looks task-shaped. Run the dispatch When-to-Invoke check before responding.
The dispatch skill already tells the model exactly how to decide. This one line is just a nudge — no duplication, no extra instructions.
Hook Config
Add a UserPromptSubmit hook to ~/.claude/settings.json, already confirmed valid by the existing Stop hook pattern:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "bash /Users/sttil-solutions/.claude/hooks/dispatch-trigger.sh",
"timeout": 5,
"statusMessage": "Checking for dispatch..."
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash /Users/sttil-solutions/.claude/hooks/state-autopush.sh",
"timeout": 30,
"statusMessage": "Syncing current-state.md to git"
}
]
}
]
}
}
The Script
File: ~/.claude/hooks/dispatch-trigger.sh
#!/bin/bash
# dispatch-trigger.sh — keyword heuristic for UserPromptSubmit
# Injects a one-line dispatch-check reminder when the prompt looks task-shaped.
# Reversible: remove the hook block from settings.json to disable.
PROMPT="$1"
# Trigger keywords (any one match fires)
TRIGGER='\b(build|create|write|implement|deploy|set up|add|make|generate|produce|fix|change|update|refactor|rewrite|migrate|convert|replace|remove|delete|rename|restructure|design|plan|architect|redesign|propose|spec|blueprint|outline|research|audit|review|analyze|investigate|evaluate|assess|compare|diagnose)\b'
# Multi-step indicators
MULTI='(and then|first.+then|step [0-9]|phase [0-9]|stage [0-9]|sequence|workflow)'
# Suppression patterns
SUPPRESS='^(hi|hey|hello|thanks|ok|good|yes|no|sure|got it|understood)[.!]?$'
# Exit early if suppression pattern matches
echo "$PROMPT" | grep -qiE "$SUPPRESS" && exit 0
# Check trigger
echo "$PROMPT" | grep -qiE "$TRIGGER|$MULTI" || exit 0
# If we get here, prompt is task-shaped — inject the reminder
echo "⏺ [dispatch-check] This prompt looks task-shaped. Run the dispatch When-to-Invoke check before responding."
Make executable: chmod +x ~/.claude/hooks/dispatch-trigger.sh
How It Works End-to-End
- User submits a prompt in Claude Code
- UserPromptSubmit hook fires → bash dispatch-trigger.sh "$PROMPT"
- Script does cheap grep/regex — no LLM cost, ~5ms per check
- If task-shaped AND not suppressed, script prints one line of text
- That text appears in Claude's context as a user/assistant note
- Claude sees the
[dispatch-check]marker and checks the dispatch skill's When-to-Invoke section - Dispatch runs only when warranted — single-domain tasks proceed normally
- Reversible: remove the hook block from settings.json
2. Dispatch Threshold Sharpening
The existing dispatch skill is solid. These edits sharpen when to delegate vs solo, and what depth of dispatch to use.
Threshold Rules (replace section in dispatch SKILL.md)
Important: Do NOT append. Delete the existing Auto-invoke bullet entirely and replace it with the new text below. The old section says "Auto-invoke (even without being typed)" which relies on the model's own judgment. The new section says "When you see the [dispatch-check] marker" which relies on an external hook. If both survive, the model gets mixed signals.
## Thresholds — Delegate vs Solo vs Orchestrate
### Solo (no dispatch needed)
- Single domain: one division, straightforward execution
- Known answer: the model knows the answer from prior work or project files
- Pure conversation or lookup: Q&A, definition, explanation with no output artifact
- Small fix: one file, one change, deterministic scope
### Direct specialist (one agent, no chief-of-staff)
- Single domain but needs specialist depth (architecture, compliance, legal, audit)
- The specialist is clear from the task description
- Brief fits one specialist's scope without cross-domain coordination
### Chief-of-staff orchestration (multi-agent)
- Two or more divisions involved
- Task requires sequential handoffs between specialists
- Cross-domain coordination needed (changes in one area affect another)
### Parallel fan-out (chief-of-staft, concurrent)
- Two or more independent workstreams with no cross-dependency
- Each workstream has a clear owner and scope boundary
- Results can be synthesized independently (e.g., compliance audit + UX review + content draft)
### Decision Flow
Prompt arrives → dispatch check fires? ├─ NO → proceed as solo └─ YES → classify: ├─ Single domain + generalist depth → SOLO ├─ Single domain + specialist depth → DIRECT SPECIALIST ├─ Multi-domain + sequential deps → CHIEF-OF-STAFF (sequential) └─ Multi-domain + independent paths → PARALLEL FAN-OUT
The "do NOT invoke" list stays intact. These thresholds live inside dispatch as a decision guide, not a separate document.
Changes to Dispatch Skill: When-to-Invoke Section
Replace the current "Auto-invoke" bullet with the thresholded version:
### Auto-invoke (dispatch check fired by UserPromptSubmit hook)
When you see the `[dispatch-check]` marker in context, run the **Thresholds** decision flow. Dispatch is warranted when:
- A task spans two or more of the four STTIL divisions
- A task needs specialist depth beyond generalist judgment, and the specialist is not you
- A barrier requires specialist expertise to resolve
3. Pi-Side Mirror
Pi doesn't have UserPromptSubmit hooks. Pi has an extension event system — specifically the before_agent_start event, which fires after user input and can inject messages and modify the system prompt.
Pi Trigger (Extension)
File: ~/.pi/agent/extensions/dispatch-trigger.ts
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export default function (pi: ExtensionAPI) {
// Keyword set mirrors the Claude-side script
const TRIGGER = /\b(build|create|write|implement|deploy|set.?up|add|make|generate|produce|fix|change|update|refactor|rewrite|migrate|convert|replace|remove|delete|rename|restructure|design|plan|architect|redesign|propose|spec|blueprint|outline|research|audit|review|analyze|investigate|evaluate|assess|compare|diagnose)\b/i;
const MULTI = /(and then|first.+then|step \d|phase \d|stage \d|sequence|workflow)/i;
const SUPPRESS = /^(hi|hey|hello|thanks|ok|good|yes|no|sure|got it|understood)[.!]?$/i;
pi.on("before_agent_start", async (event, ctx) => {
const prompt = event.prompt.trim();
// Skip suppressed patterns
if (SUPPRESS.test(prompt)) return;
// Check for task-shaped prompt
if (!TRIGGER.test(prompt) && !MULTI.test(prompt)) return;
// Inject dispatch reminder message
return {
message: {
customType: "dispatch-trigger",
content: "⏺ [dispatch-check-pi] This prompt looks task-shaped for Pi subagents. Check the pi-subagents skill for fan-out opportunities (research, review, parallel exploration, design) vs solo work.",
display: true,
},
};
});
}
Install: Save to ~/.pi/agent/extensions/dispatch-trigger.ts and reload Pi (/reload).
Pi Dispatch Thresholds
The same threshold logic applies, adapted for Pi's subagents:
## Pi Dispatch Thresholds (pi-subagents mirror)
### Solo (no subagent needed)
- Simple answer or known fact from project files
- One-file edit with clear scope
- Conversation or clarification
- Direct execution of a skill in current context
### Single subagent (one specialist)
- One research question → researcher
- One review pass → reviewer
- One codebase recon → scout
- One design exploration → planner or oracle
### Parallel fan-out (concurrent subagents)
- Research question + codebase impact → researcher + scout
- Multi-angle review → 2-3 reviewer agents with distinct angles
- Design exploration + feasibility check → planner + oracle
- Context build + plan → context-builder + planner
### Chain (sequential subagents)
- Scout → plan → review → implement
- Research → design → review
- Context-build → plan → worker → reviewer
Pi Activation
The extension auto-injects the [dispatch-check-pi] marker. Pi checks against the dispatch thresholds above and uses the pi-subagents skill to route work.
No parallel worktree isolation needed for Pi subagents — Pi subagents are separate agent sessions, not forking the same filesystem state like Claude's crew. Each subagent is isolated by the subagent runtime.
4. Cross-Readable Process Skills (Tier 2)
4a. Delegation Discipline Skill
Purpose: Shared operational skill for both Pi and Claude. Guides when to delegate, how to brief, how to synthesize. Lives in ~/.claude/skills/delegation-discipline/SKILL.md (shared with Pi via their skill paths).
File: ~/.claude/skills/delegation-discipline/SKILL.md
---
name: delegation-discipline
description: Guides when and how to delegate to specialist agents. Shared operational skill for both Pi (pi-subagents) and Claude (dispatch + crew). Ensures delegation is content-driven, well-briefed, and synthesized — never a dump of raw agent output.
metadata:
type: process
---
# Delegation Discipline
## When to Delegate
Always read the **dispatch thresholds** before deciding. The decision tree:
1. Is this single-domain with a known answer or straightforward execution? → Solo.
2. Is this single-domain but needs specialist depth (architecture, compliance, legal, audit)? → One specialist.
3. Does this span two or more divisions? → Dispatch / chief-of-staff.
4. Does this need parallel independent workstreams? → Parallel fan-out.
Never delegate because "a specialist exists for this." Delegate because the task genuinely needs it.
## How to Brief
Every delegation needs a brief with all five elements:
1. **Objective** — measurable, not vague. What needs to be produced or decided?
2. **Scope** — what the specialist owns AND what it must NOT touch
3. **Context** — minimum facts the specialist needs (not the full conversation)
4. **Format** — what to return (plan, draft, recommendation, findings, file edit)
5. **Stopping point** — when is the specialist done?
Write the brief before invoking. A vague brief returns vague work.
## How to Synthesize
When the specialist returns:
1. Did it answer the objective? If not, re-brief or escalate.
2. Check for conflicts with brand facts (MemPalace KG for Signal), compliance rules, or prior decisions.
3. Present one integrated answer — not raw agent output.
4. State the recommended next action.
One clear answer is worth more than two parallel memos.
## Interaction with dispatch skill
- Claude: the `dispatch` skill is the router. This skill is the discipline around using it.
- Pi: pi-subagents is the router. This skill is the discipline around using it.
- Both: the discipline (briefing, synthesis) is identical.
## Do NOT
- Delegate a task you can do trivially yourself
- Delegate to avoid reading relevant files
- Pass raw agent output to Kisa without synthesis
- Assume a specialist knows conversation history — brief them
4b. Design-Review / Persist Deliverable Skill
Purpose: Pi-only (though cross-readable). Forces a self-review pass before Pi declares a design done. Fixes the drift pattern where Pi finishes a design in chat but never writes the file.
File: ~/.claude/skills/design-review-persist/SKILL.md
---
name: design-review-persist
description: Pi runs this before declaring any design artifact complete. Self-review pass, then persist the deliverable to a file. Prevents the drift pattern where design finishes in chat but never reaches a file.
metadata:
type: process
---
# Design Review + Persist Deliverable
Run this skill BEFORE declaring a design or specification task complete.
## Step 1 — Self-Review
Review your completed design against these checks:
- [ ] **Completeness**: Does it cover all requirements from the brief? No gaps?
- [ ] **Clarity**: Could a builder (Claude, another agent) implement from this document alone? Or does it depend on unwritten context from this conversation?
- [ ] **Precision**: Are decisions, thresholds, and constraints specific? No vague phrases like "reasonable thresholds" or "handle edge cases" without specifics.
- [ ] **Actionability**: Does the document end with a clear "what to build next" section? Does the builder know exactly what to implement?
- [ ] **Traceability**: Does it reference the source brief or requirement doc? Can someone later understand WHY this decision was made?
If any check fails, fix the design before persisting.
## Step 2 — Persist to File
Write the design to a file. Location conventions:
- `signal/docs/` for Signal-specific designs
- `docs/` at project root for cross-project designs
- `<project>/docs/` for other repos
File naming: `<topic>-design-YYYY-MM-DD.md`
Front matter (optional but recommended):
```markdown
# Title
**Date:** YYYY-MM-DD
**Design by:** Pi
**Builds by:** Claude (or specific agent)
**Approves:** Kisa
Step 3 — Verify Persistence
Confirm the file exists and is readable. Read it back to verify:
- The file contains the complete design (not a stub or notes)
- All sections survived the write
- No placeholder text or unexpanded templates
Step 4 — Declare Done
Only after Steps 1-3 pass can you mark the design task complete. If any step fails, fix and re-verify.
Context
This skill exists because of the 2026-06-24 drift: Pi finished a workflow-consolidation design entirely in chat but wrote zero files. Claude had to recover it from session logs. This skill prevents that pattern going forward.
---
## 5. Implementation Sequence
| Step | Who | What | Depends On |
|------|-----|------|------------|
| 1 | Claude | Create dispatch-trigger.sh + chmod | Nothing |
| 2 | Claude | Edit settings.json: add UserPromptSubmit hook block | Step 1 |
| 3 | Claude | Edit dispatch SKILL.md: **replace** old Auto-invoke section with new thresholded version, then append Thresholds section | Step 2 |
| 4 | Claude | Create delegation-discipline SKILL.md | Step 3 |
| 5 | Pi | Create dispatch-trigger.ts extension in ~/.pi/agent/extensions/ | Nothing |
| 6 | Pi | Run /reload in Pi to activate the extension | Step 5 |
| 7 | Pi | Create design-review-persist SKILL.md | Nothing |
| 8 | Pi | Verify the extension triggers correctly on task-shaped prompts | Step 6 |
| 9 | Both | Test: submit task-shaped / non-task prompts, confirm dispatch fires / doesn't fire | Steps 1-8 |
---
## 6. Reversibility
- **Claude side**: Remove the `UserPromptSubmit` block from `settings.json`. Delete `dispatch-trigger.sh`.
- **Pi side**: Remove `dispatch-trigger.ts` from `~/.pi/agent/extensions/` and run `/reload`.
- **Skills**: Delete the SKILL.md files from `~/.claude/skills/`.
- **No state affected**: The trigger is stateless by design. No cached data, no registry, no config files outside settings.json.