Signal/docs/delegation-router-design-2026-06-24.md

448 lines
17 KiB
Markdown

# 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:
1. Claude-side trigger (UserPromptSubmit hook)
2. Dispatch threshold sharpening
3. Pi-side mirror (extension + pi-subagents routing)
4. 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:
```json
{
"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`
```bash
#!/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
1. User submits a prompt in Claude Code
2. UserPromptSubmit hook fires → bash dispatch-trigger.sh "$PROMPT"
3. Script does cheap grep/regex — no LLM cost, ~5ms per check
4. If task-shaped AND not suppressed, script prints one line of text
5. That text appears in Claude's context as a user/assistant note
6. Claude sees the `[dispatch-check]` marker and checks the dispatch skill's When-to-Invoke section
7. Dispatch runs only when warranted — single-domain tasks proceed normally
8. **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:
```markdown
### 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`
```typescript
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`
```markdown
---
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`
```markdown
---
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.