|
| 1 | +# Council Surface Model |
| 2 | + |
| 3 | +> Developer-facing reference for the Tiny Actor / council UX across Claude Code surfaces. |
| 4 | +> Each surface has a distinct responsibility — mixing them leads to a cluttered experience. |
| 5 | +
|
| 6 | +## Overview |
| 7 | + |
| 8 | +The council UX spans five Claude Code surfaces. Each surface serves a specific role |
| 9 | +in the lifecycle of a user request: |
| 10 | + |
| 11 | +| Surface | Role | Output Style | |
| 12 | +|---------|------|-------------| |
| 13 | +| **SessionStart** | Greeting & bootstrap | Setup diagnostics | |
| 14 | +| **UserPromptSubmit** | Opening council scene | Full scene (instructions, mode header) | |
| 15 | +| **PreToolUse** | Live council cue | Compact badge (spinner text) | |
| 16 | +| **PostToolUse** | State transition tracking | Silent (side-effects only) | |
| 17 | +| **Status bar** | Persistent snapshot | Two-line compact strip | |
| 18 | + |
| 19 | +``` |
| 20 | + Request lifecycle |
| 21 | + ───────────────────────────────────────────────────────── |
| 22 | + SessionStart ──► UserPromptSubmit ──► PreToolUse ──► PostToolUse |
| 23 | + │ │ │ │ |
| 24 | + bootstrap full scene compact cue silent tracking |
| 25 | + │ |
| 26 | + Status bar ◄─────┘ |
| 27 | + (persistent snapshot) |
| 28 | +``` |
| 29 | + |
| 30 | +--- |
| 31 | + |
| 32 | +## 1. SessionStart — Greeting & Bootstrap |
| 33 | + |
| 34 | +**File:** `hooks/session-start.py` |
| 35 | + |
| 36 | +**Role:** One-time session setup. This is NOT the main council surface. |
| 37 | + |
| 38 | +**What it does:** |
| 39 | +- Installs the global UserPromptSubmit hook (`~/.claude/hooks/codingbuddy-mode-detect.py`) |
| 40 | +- Registers MCP server entry in `~/.claude/mcp.json` |
| 41 | +- Initializes HUD state file (`~/.codingbuddy/hud-state.json`) |
| 42 | +- Installs the statusLine command in settings.json |
| 43 | + |
| 44 | +**What it renders:** |
| 45 | +- Localized installation status messages (e.g., "CodingBuddy mode detection hook installed") |
| 46 | +- Permission hints and diagnostics on failure |
| 47 | + |
| 48 | +**Council contract:** None. SessionStart must not render council scenes, |
| 49 | +actor cards, or agent grids. Its job is infrastructure only. |
| 50 | + |
| 51 | +--- |
| 52 | + |
| 53 | +## 2. UserPromptSubmit — Opening Council Scene |
| 54 | + |
| 55 | +**File:** `hooks/user-prompt-submit.py` (installed globally at `~/.claude/hooks/`) |
| 56 | + |
| 57 | +**Role:** The primary surface for the opening council scene. Fires when the user |
| 58 | +submits a prompt, before Claude processes it. |
| 59 | + |
| 60 | +**What it does:** |
| 61 | +- Detects PLAN/ACT/EVAL/AUTO keywords (multilingual: en, ko, ja, zh, es) |
| 62 | +- Outputs mode-specific instructions (standalone or MCP-enhanced) |
| 63 | +- Resets workflow-related HUD fields (`focus`, `blockerCount`, `activeAgent`, etc.) |
| 64 | +- Updates HUD state with `currentMode` and `phase` |
| 65 | + |
| 66 | +**What it renders:** |
| 67 | +- Mode header with backend marker (standalone vs. MCP-enhanced) |
| 68 | +- Full enriched instructions from `.ai-rules/rules/core.md` when available |
| 69 | +- Fallback minimal instructions when MCP is unavailable |
| 70 | + |
| 71 | +**Council contract:** This is the one surface allowed to produce a full council |
| 72 | +scene — mode announcements, agent activation text, and workflow instructions. |
| 73 | +Future council "opening acts" (e.g., actor introductions, deliberation previews) |
| 74 | +belong here. |
| 75 | + |
| 76 | +--- |
| 77 | + |
| 78 | +## 3. PreToolUse — Compact Live Council Cue |
| 79 | + |
| 80 | +**File:** `hooks/pre-tool-use.py` |
| 81 | + |
| 82 | +**Role:** Lightweight, transient feedback during tool execution. |
| 83 | +Appears in the Claude Code spinner area. |
| 84 | + |
| 85 | +**What it does:** |
| 86 | +- Enforces quality gates on git commits |
| 87 | +- Suggests related tests for staged files (collapsed count) |
| 88 | +- Auto-selects relevant checklists (domain summary counts) |
| 89 | +- Displays active agent status in the spinner |
| 90 | + |
| 91 | +**What it renders (compact badge style per #1039):** |
| 92 | + |
| 93 | +| Cue | Example | |
| 94 | +|-----|---------| |
| 95 | +| Agent status | `🟡 ★‿★ Frontend Developer` | |
| 96 | +| Test suggestion | `3 related test(s) found — consider running before commit` | |
| 97 | +| Checklist warning | `[Checklist] security(2), performance(1)` | |
| 98 | +| TDD indicator | Progress marker from `build_tdd_indicator()` | |
| 99 | + |
| 100 | +**Return structure:** |
| 101 | +```python |
| 102 | +{ |
| 103 | + "hookSpecificOutput": { |
| 104 | + "statusMessage": "...", # Transient spinner text |
| 105 | + "additionalContext": "..." # Quality gate warnings |
| 106 | + } |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +**Council contract:** Compact only. No full scenes, no multi-line actor cards, |
| 111 | +no grids. Think "badge in a spinner" — one line, domain counts not item lists, |
| 112 | +agent glyph not agent biography. |
| 113 | + |
| 114 | +--- |
| 115 | + |
| 116 | +## 4. PostToolUse — State Transition Tracking |
| 117 | + |
| 118 | +**File:** `hooks/post-tool-use.py` |
| 119 | + |
| 120 | +**Role:** Silent bookkeeping. Records what happened and detects state transitions. |
| 121 | + |
| 122 | +**What it does:** |
| 123 | +- Records tool call statistics via `SessionStats` |
| 124 | +- Tracks tool calls in history database (`HistoryDB`) |
| 125 | +- Detects PR creation and sends notifications |
| 126 | +- Detects agent handoffs and mode changes from `parse_mode` results |
| 127 | +- Updates HUD state fields (`lastHandoff`, phase transitions) |
| 128 | + |
| 129 | +**What it renders:** Nothing visible. Returns `None`. |
| 130 | + |
| 131 | +**Council contract:** This surface must remain silent. All its work is |
| 132 | +side-effect based (file writes, database records, HUD state updates). |
| 133 | +Never add visible output here — the status bar will pick up state changes |
| 134 | +from the HUD state file on its next refresh. |
| 135 | + |
| 136 | +--- |
| 137 | + |
| 138 | +## 5. Status Bar — Compact Persistent Snapshot |
| 139 | + |
| 140 | +**File:** `hooks/codingbuddy-hud.py` |
| 141 | + |
| 142 | +**Role:** Always-visible, two-line summary strip at the bottom of the terminal. |
| 143 | +Refreshed continuously by Claude Code. |
| 144 | + |
| 145 | +**Layout:** |
| 146 | + |
| 147 | +``` |
| 148 | +Line 1 (always): |
| 149 | +◕‿◕ CB v5.3.0 | PLAN 🟢 | 12m | ~$0.42 | ♻800/1.5k | Ctx:45% |
| 150 | +
|
| 151 | +Line 2 (conditional — only when agent is active): |
| 152 | +[◮ secu] [auth flow] [✓] |
| 153 | +``` |
| 154 | + |
| 155 | +**Line 1 segments:** |
| 156 | + |
| 157 | +| Segment | Source | Example | |
| 158 | +|---------|--------|---------| |
| 159 | +| Buddy face | Constant | `◕‿◕` | |
| 160 | +| Version | `installed_plugins.json` / HUD state | `CB v5.3.0` | |
| 161 | +| Mode | `hud-state.currentMode` | `PLAN` | |
| 162 | +| Health | Context usage thresholds | `🟢` (<60%), `🟡` (60-85%), `🔴` (>85%) | |
| 163 | +| Duration | stdin `cost.total_duration_ms` / HUD state | `12m` | |
| 164 | +| Cost | stdin `cost.total_cost_usd` / estimate | `~$0.42` | |
| 165 | +| Cache | Last-call token counts (not session-wide) | `♻800/1.5k` | |
| 166 | +| Context | Context window usage % | `Ctx:45%` | |
| 167 | + |
| 168 | +**Line 2 segments (conditional):** |
| 169 | + |
| 170 | +| Segment | Source | Example | |
| 171 | +|---------|--------|---------| |
| 172 | +| Actor badge | Agent glyph + 4-char abbreviation | `[◮ secu]` | |
| 173 | +| Focus | Current file or action | `[auth flow]` | |
| 174 | +| State | Blocker count or checkmark | `[⚠2]` or `[✓]` | |
| 175 | + |
| 176 | +**Data source priority (three tiers):** |
| 177 | +1. **Stdin JSON** (highest): model, context, cost, rate limits from Claude Code |
| 178 | +2. **HUD state file**: version, mode, agent, timestamps (fcntl.flock protected) |
| 179 | +3. **Environment variables** (lowest): fallbacks |
| 180 | + |
| 181 | +**Crash fallback:** `◕‿◕ CodingBuddy` |
| 182 | + |
| 183 | +**Council contract:** Snapshot only. The status bar reflects the latest known |
| 184 | +state — it does not initiate transitions or produce scenes. It reads from |
| 185 | +HUD state that other hooks write to. |
| 186 | + |
| 187 | +--- |
| 188 | + |
| 189 | +## Design Principles |
| 190 | + |
| 191 | +### 1. One Full Scene Surface |
| 192 | + |
| 193 | +Only **UserPromptSubmit** may render full council scenes. All other surfaces |
| 194 | +use compact representations or remain silent. |
| 195 | + |
| 196 | +### 2. Compact Means Compact |
| 197 | + |
| 198 | +PreToolUse and status bar use collapsed counts, abbreviations, and glyphs. |
| 199 | +Never expand details that belong in the opening scene. |
| 200 | + |
| 201 | +### 3. Silent Bookkeeping |
| 202 | + |
| 203 | +PostToolUse never produces visible output. State changes propagate to the |
| 204 | +status bar via the shared HUD state file. |
| 205 | + |
| 206 | +### 4. Data Flows Downhill |
| 207 | + |
| 208 | +``` |
| 209 | +SessionStart (bootstrap) |
| 210 | + └──► UserPromptSubmit (writes HUD state: mode, phase) |
| 211 | + └──► PreToolUse (writes HUD state: agent, focus, strategy) |
| 212 | + └──► PostToolUse (writes HUD state: handoffs, transitions) |
| 213 | + └──► Status bar (reads HUD state, renders snapshot) |
| 214 | +``` |
| 215 | + |
| 216 | +### 5. Crash Resilience |
| 217 | + |
| 218 | +Every surface wraps its work in try/except. A failing hook must never block |
| 219 | +Claude Code execution. The status bar has a single-line crash fallback. |
| 220 | + |
| 221 | +--- |
| 222 | + |
| 223 | +## Cross-Reference |
| 224 | + |
| 225 | +| Document | Scope | |
| 226 | +|----------|-------| |
| 227 | +| [status-bar-model.md](status-bar-model.md) | Detailed status bar architecture and segment specs | |
| 228 | +| [bootstrap-architecture.md](bootstrap-architecture.md) | UserPromptSubmit global installation rationale | |
| 229 | +| [namespace-policy.md](namespace-policy.md) | File naming and namespace conventions | |
0 commit comments