| name | inbox |
| description | Conversational review of unread decisions in a roster workspace. Lists pending HITL items (roster/<function>/pending/ and <agent>/pending/), shows each in chat, collects approve/reject/defer by reply, and applies each via `roster review --approve/--reject <id>`. No TTY needed — this is the chat-native front door for `roster review`. Triggers on /inbox or when the user asks to review their inbox / pending decisions / HITL items. |
| version | 1.1.0 |
| trigger_conditions | ["User invokes /inbox","User asks to review unread decisions / pending HITL items / their inbox in a roster workspace"] |
inbox
The chat-native way to clear your roster decision queue. roster review's interactive TUI needs a real terminal; /inbox does the same job conversationally — it lists the decisions, you reply in plain language, and it applies each through the non-interactive roster review backend. Works identically in Claude Code and Codex.
The skill is stateless — it re-reads the queue on every invocation.
Working directory
Operate from the workspace root and classify it before running any command:
- If both
roster.yaml and config/project.yaml exist, stop. This is a mixed workspace; preserve both markers and use the v2 migration flow when #363 lands.
- If
roster.yaml exists, stop with: This is a Roster v2 workspace. /inbox is a legacy queue workflow; do not run roster review or inspect legacy pending/ trees. Portable Brain evidence and Dreamer candidate decisions replace it in #356 and #358.
- Otherwise,
config/project.yaml alone identifies a legacy v1 workspace and the procedure below remains available. A missing roster/ directory just means the legacy queue is empty (roster review --json returns []), not an error.
- If neither identity file exists, stop and say:
Run /inbox from a legacy Roster workspace root (must contain config/project.yaml); Roster v2 workspaces use roster.yaml and do not expose this queue.
(.roster/ — dotted — is scaffold/schedule-spec metadata, not the runtime roster/ queue; never treat one as the other.)
Use that root as <root> for every command below (pass it explicitly with --cwd <root>).
Procedure
-
List. Run:
roster review --json --cwd <root>
Parse the JSON array. Each entry has id, function, class, filename, path (workspace-relative), target_on_approve (resolved — may be null), frontMatter, and agent on lesson-class items. If the roster CLI is not on PATH, tell the user to install it (npm i -g @firatcand/roster) or run roster review in a terminal, and stop.
The queue spans two surfaces, and --json returns both:
class: "error" — roster/<function>/pending/, synthesized by roster pending sync from failed or stale scheduled fires. The approve target comes from target_on_approve front-matter.
class: "lesson" — <function>/<agent>/pending/ (and <agent>/pending/ for the cross-cutting peers dreamer/ and chief-of-staff/), holding dreamer-drafted lesson candidates. These carry no target_on_approve: approving promotes the file to <agent>/playbook/<filename>, per conventions.md § "Lesson lifecycle". An explicit front-matter target still wins if present.
-
Empty queue. If the array is empty, reply Inbox zero — no unread decisions. and stop.
-
Present. For each item, show a compact, numbered block:
N. [<agent or function>] <filename> · id <id> · <class>
on approve → <target_on_approve> (or, when it is null, warn ⚠ no target — can't be approved, only rejected/deferred)
- the first ~6 lines of the body — read it yourself from
<path> (you have Read access; --json returns front-matter only).
-
Collect decisions. Ask the user what to do, accepting free-form replies like "approve 1 and 3, reject 2, leave the rest." Map each to approve / reject / defer. If the user is unsure, summarize what approve (moves the item to its ) vs reject (deletes it) vs defer (leaves it for later) does. For an error-class item (, synthesized by from immutable failed-fire evidence), : also writes an acknowledgement sentinel () so the next sync does not re-create the item from the same evidence — a hand- alone would come back.
Rules
- Never move or delete decision files by hand. Always go through
roster review --approve/--reject so the path-safety checks (target must stay inside the workspace, no clobber) are enforced in one place.
- Never edit a decision's body.
/inbox reviews and routes; it does not author.
- One workspace at a time — the root you detected in the working-directory step.
- Identify by
id, fall back to path. The id is roster review's stable handle; if it ever reports an ambiguous id, re-run the apply with the exact workspace-relative path instead.
- The count must match the session-start banner. Both read the same two surfaces (error + lesson). If they ever disagree, that is a bug worth reporting — never work around it by touching decision files directly.
- Do not invoke any model billing path other than the host tool's native subscription, and do not spawn subagents —
/inbox only shells out to roster and converses.
What this skill does NOT do
- Synthesize new decisions (that's
roster pending sync, run by the session-start banner hook).
- Change the count logic or introduce read/seen state — "unread" simply means "still in the queue."
- Run the interactive
roster review TUI (it needs a terminal; this skill is its headless, conversational equivalent).