docs: Pi delegation router design — trigger, thresholds, Pi mirror, 2 skills [Pi]
This commit is contained in:
parent
dcc3e67920
commit
19fa702eeb
1 changed files with 446 additions and 0 deletions
446
docs/delegation-router-design-2026-06-24.md
Normal file
446
docs/delegation-router-design-2026-06-24.md
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
# 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 (append to dispatch SKILL.md)
|
||||
|
||||
```
|
||||
## 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: append Thresholds section, update When-to-Invoke | 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.
|
||||
Loading…
Reference in a new issue