| name | gdd-bandit-status |
| description | Surface read-only per-(agent, bin, delegate) bandit posterior snapshot - alpha/beta/mean/stddev/count/last-used per arm. Phase 27.5 (v1.27.5) diagnostic. Use when investigating 'why did the bandit pick tier X for agent Y?' or when verifying posterior convergence after enabling adaptive_mode: full. |
| argument-hint | |
| tools | Read, Bash |
gdd-bandit-status
Role
You are a deterministic, read-only diagnostic skill. You do not spawn agents and do not modify the posterior. You read .design/telemetry/posterior.json (path declared by scripts/lib/bandit-router.cjs's DEFAULT_POSTERIOR_PATH), aggregate per-(agent, bin, delegate, tier) arm state, and emit a single Markdown table. Read-only per Phase 27.5 D-11 - to reset, use {{command_prefix}}bandit-reset (Phase 23.5). See ./reference/bandit-integration.md for setup, interpretation, and convergence guidance.
Invocation Contract
- Input: none.
- Output: a Markdown bandit-status table to stdout. The table is the entire output.
Procedure
1. Locate the posterior file
Read .design/telemetry/posterior.json. Missing → emit empty-state message:
## Bandit Posterior Snapshot
No posterior data yet — run a few pipeline cycles with `adaptive_mode: full` first.
No posterior data found at `.design/telemetry/posterior.json`.
Possible reasons:
- `adaptive_mode` is `static` or `hedge` (bandit silent — see `.design/budget.json`).
- No spawns have fired since Phase 27.5 wiring landed.
- Posterior was cleared via `{{command_prefix}}bandit-reset`.
- You are running in interactive Claude Code: the posterior is updated (learns) only on the SDK / headless `session-runner` path. In interactive `adaptive_mode: full` the bandit samples from configured priors but does not learn from in-session outcomes.
See `reference/bandit-integration.md` ("Where adaptive routing actually learns") for setup guidance.
Note: the posterior only moves (learns) on the SDK / headless session-runner path. In interactive Claude Code with adaptive_mode: full, the bandit samples from the configured priors but does not currently update them in-session. See reference/bandit-integration.md.
Skip to Section 4 (Record). Parse failure (truncated/corrupted) → emit Posterior file exists but is unparseable. Run {{command_prefix}}bandit-reset to start fresh, or restore from a backup.
2. Parse the posterior
Schema:
{
"schema_version": "1.0.0",
"generated_at": "<ISO>",
"arms": [{ "agent": "...", "bin": "...", "tier": "...", "delegate": "...", "alpha": N, "beta": N, "last_used": "...", "count": N }]
}
The delegate field is optional - absent = Phase 23.5 legacy slice (rendered as - in the table).
3. Render the table
Compute per arm: mean = alpha / (alpha + beta) (3 decimals), stddev = sqrt(alpha*beta / ((alpha+beta)^2 * (alpha+beta+1))) (3 decimals).
Sort by (agent ASC, bin ASC, delegate ASC where '-' first, tier ASC opus<sonnet<haiku, last_used DESC). Group by agent for readability.
Emit:
## Bandit Posterior Snapshot
Per-(agent, bin, delegate, tier) posterior state. Read-only — to reset use `{{command_prefix}}bandit-reset` (Phase 23.5).
Posterior file: `.design/telemetry/posterior.json` (last updated: <generated_at>)
Total arms: <count>
| Agent | Bin | Delegate | Tier | Alpha | Beta | Mean | Stddev | Count | Last Used |
|-------|-----|----------|------|-------|------|------|--------|-------|-----------|
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
> Mean = alpha / (alpha + beta). Stddev = sqrt(alpha*beta / ((alpha+beta)^2 * (alpha+beta+1))).
> Delegate '-' = Phase 23.5 legacy slice (equivalent to 'none').
> See `reference/bandit-integration.md` for interpretation.
> Read-only — use `{{command_prefix}}bandit-reset` to clear posterior state.
Precision: alpha/beta 2 decimals; mean/stddev 3 decimals; count integer; last_used truncated to minute (YYYY-MM-DDTHH:MM); null last_used renders -.
After the table, surface a per-(agent, bin) best-arm summary: for each unique pair, identify highest-mean arm (tie-broken by count DESC) - answers "why did the bandit pick tier X?" at a glance.
4. Record
Append one JSONL line to .design/skill-records.jsonl: {"skill":"gdd-bandit-status","ts":"<ISO>","arms_seen":<count>,"posterior_present":<bool>}. Skill writes ONLY to skill-records.jsonl (telemetry); never touches the posterior.
Cross-references
./reference/bandit-integration.md - operator guide; interpretation patterns.
scripts/lib/bandit-router.cjs (Phase 23.5) - posterior shape, DEFAULT_POSTERIOR_PATH, loadPosterior().
scripts/lib/bandit-router/integration.cjs (27.5-01), hooks/budget-enforcer.ts (27.5-02), scripts/lib/session-runner/index.ts (27.5-03), scripts/lib/bandit-arbitrage.cjs (27.5-04), {{command_prefix}}bandit-reset (Phase 23.5) - only surface that mutates the posterior.