---
name: peaks-status
description: Universal status primitive for any in-flight Peaks-Loop workflow (orchestrator-agnostic). Reads the existing CLI primitives (peaks skill presence, peaks session list, peaks project dashboard, peaks request show) and renders a 1-screen status table. Use when the user asks "where are we", "现在到哪了", "what's the current state" for ANY bee (peaks-code, future peaks-research, …). Triggers on "/peaks-status", "现在到哪了", "what is the current state", "show me the dashboard". (Replaces peaks-status as a top-level primitive.)
---

<!-- peaks:loop-hygiene — HAND-MAINTAINED block, NOT generated; byte-identical in every SKILL.md, enforced by tests/unit/skills/loop-hygiene-block.test.ts. Edit one, edit all 23. -->

## Loop hygiene (every turn — MANDATORY)

**Skill header.** While this skill is active, open every turn with
`Peaks-Loop Skill: <skill> | Peaks-Loop Role: <role> | Peaks-Loop Gate: <gate> | Peaks-Loop Context: <ratio%> (<zone>) | Next: <one short action>`.
Every turn, not only the first — it is how the user knows which skill is driving.
`Role` and `Context` are machine facts: copy them from `peaks skill presence --json`
(`data.role`, `data.context.ratioPct`, `data.context.action`) — never invent them.

**Context is this skill's own business.** Run `peaks skill presence --json` every turn and
read its `context` block. When `action` is `auto-fire`, `pre-compact`, or `red-line`,
run `peaks code auto-compact --project .` **yourself**, then continue. Tell the user the
ratio in one line if it helps, but never hand them the compaction step: asking the user to
run `/compact` is the regression the zero-pause contract forbids. This holds in **every
mode** — standard *and* 24h. The mode moves the threshold, never the obligation.

**Read before you edit.** Read a file before your first `Edit` / `Write` / `MultiEdit` on
it — the normal way to work here — for every path outside `.peaks/**` (source, tests, docs,
config); `.peaks/**` writes are exempt.

**Expect one denial per file anyway — and do NOT pre-empt it.** A `PreToolUse` gate (ECC's
"Fact-Forcing Gate") denies the FIRST edit a session makes to any given path, once, by
design. Reading does NOT prevent it: the gate keys on the path's first touch, not on whether
you read it. **Do not recite its four questions before every edit** — it asks when it wants
them, and reciting unprompted burns a round-trip per file for nothing. Answer only when a
denial actually arrives.

**When one does arrive:** a denial is not a failure and the tool is not broken — your edit
was NOT applied. State the facts it asks for (importers, affected API, data schemas if any,
the user's verbatim instruction), then retry the SAME operation. The retry is allowed. Do not
switch tools, do not give up, do not retry blindly. One more thing worth knowing: an idle gap
of ~30 minutes clears the gate's "already passed" list, so a file you cleared earlier can be
denied again after a long pause. That is the gate resetting, not you regressing.
<!-- /peaks:loop-hygiene -->

# Peaks-Loop Code Status (wrapper)

Peaks-Loop Code Status is a thin wrapper that renders a compact status table for the current peaks-code orchestrator state. It is the answer to "I just want to know where we are" — no PRD, no RD, no QA, no full peaks-code orchestration. Just read the existing CLI state and render a 1-screen summary.

**This is a transparent wrapper.** The user does not stay in this skill — the status table is rendered, and control hands off (back to the user, or to `peaks-code` if the user wants to act on the status).

## Skill presence (MANDATORY first action)

```bash
peaks skill presence:set peaks-status --project <repo> --mode <mode> --gate startup
peaks project memories --project <repo> --json  # load durable memory
```

## Step 1: Read the current state

Use only existing primitives (no new commands). **Important contract note**: `peaks session list` does NOT support `--project` (verified by dogfood 2026-06-04); it returns all sessions globally. To scope to the current project, read `.peaks/.session.json` for the bound `sessionId`, then use `peaks session info <sid>` for the bound session's full state, and filter `peaks session list` output by `projectRoot` to find other sessions in the same project.

### 1a. The three paths that have an MCP tool — ONE call

`peaks_status` returns `peaks skill presence --json`, `peaks session list --json` and — when `rid` and `role` are given — `peaks request show <rid> --role <role> --json --project <project>`. Each CLI result comes back VERBATIM under its own key (`skill-presence`, `session-list`, `request-show`); a key is absent when that call was not run. Call it once and read the keys.

- Pass `rid` and `role` only when a specific request is in flight (the `rid` from Step 1c). When it is not, call with just `project` and read the two keys that come back.
- If the tool is not available, or the call fails, or the result carries `isError`, **fall back to Step 1b** — do not report a partial read as if it were the whole picture. A failed call is a failed call; the keys you did not get are not "nothing there".

### 1b. Bash fallback — the same three commands, always available

Run these when 1a did not answer (MCP not installed / not registered / call failed). They are the SAME argv the tool runs, so the output is identical:

```bash
# 1. Active skill presence
peaks skill presence --json

# 4. All sessions globally (then post-filter to current project)
peaks session list --json
# Note: this returns all sessions across all projects; the wrapper filters by
# matching `projectRoot` against the bound session's `projectRoot` to show only
# the sessions for THIS project. Sessions from other projects are ignored.

# 6. Per-request detail (if a specific rid is in flight) — one call per role
peaks request show <rid> --role <role> --json --project <project>
# e.g. --role rd for the RD artifact, --role qa for the QA report
```

### 1c. Paths with no MCP tool — always Bash

```bash
# 2. The bound session id (from .peaks/.session.json — local read, no CLI)
sid=$(cat .peaks/.session.json | python3 -c "import sys,json; print(json.load(sys.stdin)['sessionId'])")

# 3. The bound session's full state
peaks session info "$sid" --json

# 5. Per-request role state (PRD / RD / QA / TXT for the bound project)
peaks project dashboard --project <repo> --json
```

`peaks project dashboard` is deliberately **not** in the MCP surface: it shells out to `git` to resolve the project root, which the read-only definition forbids. It stays on Bash.

All of these calls are read-only. Total cost: sub-second.

## Step 2: Render the status table

Compact 1-screen format:

```
=== peaks-code status ===
Session:   2026-06-04-session-b60252
Active:    peaks-code (mode: full-auto, gate: qa-validation)
Workspace: /Users/yuanyuan/.../peaks-loop/.peaks/2026-06-04-session-b60252

| Role | State          | Artifact                |
|------|----------------|-------------------------|
| PRD  | handed-off     | prd/requests/003.md     |
| RD   | qa-handoff     | rd/requests/003.md      |
| QA   | running        | qa/requests/003.md      |
| TXT  | (not started)  | -                       |

QA verdict: pending
Last activity: 2026-06-04T17:00:00.000Z (12 min ago)
Standards: 5/5 existing (no delta)
Health: skill-doctor 35/35 pass
```

If the session is fresh (no in-flight slice), render a different layout:

```
=== peaks-code status ===
Session: 2026-06-04-session-b60252
Active:  peaks-code (mode: full-auto, gate: startup)
Workspace: /Users/yuanyuan/.../peaks-loop/.peaks/2026-06-04-session-b60252

No in-flight slice. Ready for a new request.
Health: skill-doctor 35/35 pass
```

## Step 3: Ask the user what to do next

| Option | What it does |
|---|---|
| Continue from the current gate | Hand off to `peaks-code` with the gate already at the current state. Existing artifacts are preserved. |
| Open a new slice in this session | Keep the workspace, treat the current request as a new slice (new `rid`). |
| Just summarize and exit | No further action; the user will decide later. |

## Step 4: Hand off (if user picked option 1 or 2)

Re-assert `peaks-code` presence so the status header reads correctly for the rest of the run:

```bash
peaks skill presence:set peaks-code --project <repo> --mode <mode> --gate <matching-gate>
```

Then yield control.

## Hard rules (do NOT skip)

- **Never write to `.peaks/_runtime/<sid>/`.** This skill is read-only on the workspace; it only reads existing CLI state.
- **Never add a new `peaks <cmd>`.** Use only the existing read-only CLI primitives: `peaks skill presence`, `peaks session list`, `peaks session info`, `peaks project dashboard`, `peaks request show` — plus the `peaks_status` MCP tool, which is those same argv behind one call. **Note**: `peaks session list` does not support `--project`; filter its output by `projectRoot` post-hoc.
- **A failed MCP call is not an empty answer.** If `peaks_status` is unavailable or returns `isError`, run the Step 1b commands. Never render a table from the keys that happened to come back while a failed key is silently missing.
- **Never auto-progress the workflow.** The status table is informational only. The user chooses what to do via `AskUserQuestion`. Never silent about what comes next — always present the 3 options.
- **Never expose sensitive data in the table.** Do NOT include full PRD bodies, full tech-doc bodies, or any test code in the table. Just state names, paths, and counts.

## Anti-patterns (do NOT do)

- Do NOT run `peaks workspace init` on the real session. The wrapper is read-only.
- Do NOT run `peaks request transition` (would change state). The wrapper is informational only.
- Do NOT write the status to a file (e.g. `.peaks/_runtime/<sid>/status.md`). The user can see it in the chat; persisting it adds noise to the workspace.
- Do NOT block on slow CLI calls. The 5 read-only calls are sub-second each. If any takes >5s, fail fast and report the slow command.

## Cross-references

- The "drives a CLI on the user's behalf" pattern (mirror of `peaks-sop`) is the closest existing precedent.
- `peaks-resume` (P2.1) and `peaks-test` (P2.2) are the sibling wrappers. `peaks-resume` focuses on workflow-state introspection + resume decision; `peaks-status` is the broader 5-CLI snapshot. The two are complementary, not redundant.
- The "read 5 CLI primitives, render 1 table" pattern is intentionally minimal — the wrapper does NOT add a new status-introspection CLI command (would violate the dev-preference.md "default-no on new CLI" rule).
