Status — one-glance work readout
Flow
Read TASKS.md at the repo root. If missing, report "no TASKS.md yet — run /repo-onboarding or /task <description> to create one" and stop.
Count checkbox states across the file:
[ ] → pending
[~] → in progress
[x] → done
Identify the active task: the first [~] row, or if none, the first [ ] row.
Identify the last completed: the most recent [x] row (top of the Done section, or last [x] before it).
Parse optional metadata markers on each row (additive — absent fields are fine):
_started_at: YYYY-MM-DD_
_completed_at: YYYY-MM-DD_
_blocked_reason: <short reason>_
Treat missing fields as "unknown" rather than as errors. Do not warn.
Compute summaries:
- Cycle time per
[x] row = completed_at − started_at in days, when both
are present. Surface the median across the most recent ~10 done rows; skip
rows where either field is unknown.
- Blocked-reason rollup: count distinct
_blocked_reason: …_ values under
the Blocked section.
Scan pipeline run-state (the discipline signal). Follow
skills/sdlc/templates/envelope-staleness.md — the shared scan, including its
false-positive guards (skip on main_branch, at most one report, silence when
nothing changed). Read-only here: surface non-terminal and stale runs, don't
rewrite them. --prune-stale below is the only mutating path.
Print a 3–7 line summary:
TASKS: N pending · M in_progress · K done · B blocked
Active: (P<pri>) <title> — plans/tasks/task-<N>-<slug>.md
Last done: <title> (cycle: <D> days, or "unknown")
Median cycle (last 10): <D> days (omit if all unknown)
Blocked reasons: <reason1> ×N · <reason2> ×M (omit if no blocked rows)
Pipeline: <slug> @ <stage> (<pipeline>, in_progress 3d — reconcile) (omit if none non-terminal)
If there's no active task, say "no active task — next up: ".
A non-terminal pipeline run is the one thing worth making loud — it's how a
skipped/abandoned pipeline becomes visible instead of lingering in JSON.
Next step (absorbed from the former /next)
After the summary, print one recommended next command with a one-line reason. Highest
match wins; stop at the first hit:
- Paused/failed run on this branch →
/sdlc <input> --resume. Read the failing
stage's sidecar and name the class in the reason — flaky (a test flips across loops) ·
code-defect (a consistent assertion failure) · plan-wrong (the failure contradicts
a plan step) · config-missing (a command/env the runner needs). For a code defect,
recommend /task fix: <one-line failure> first, then the resume.
- Non-terminal run whose work looks landed (
base_commit is an ancestor of HEAD) →
/sdlc-status --prune-stale to reconcile.
- Pending sentinel (
.claude/.next-action non-empty) → surface each line's cmd
verbatim. Never consume the sentinel here; this skill is read-only.
- A plan file with no pipeline run →
/sdlc <plan>.
[~] in-progress TASKS.md row → /sdlc task-<N>.
[ ] pending rows → the top one: /task if small and bounded, /sdlc if it
needs the full pipeline.
- Nothing queued →
/brainstorm for ideation, or /repo-health for a hygiene sweep.
Print it as Next: <command> — <reason>. Recommend only; never execute. The classes in
rung 1 are what the former /triage did — the diagnosis is a paragraph, not a skill.
--prune-stale (opt-in cleanup — the one write exception)
Detection alone leaves stale envelopes flagged forever. /sdlc-status --prune-stale
lets you actually clear them — confirm-gated, never automatic:
- Find pipeline runs that are non-terminal (
in_progress/paused) and
either older than discipline.staleness_hours (default 24) or whose
base_commit is not a real git object (git cat-file -e <base_commit> fails
— a synthetic/placeholder base that nothing will ever reconcile).
- List them and ask for one confirmation before touching anything: show
each slug, stage, age, and why it qualifies.
- On confirm, for each: if its
base_commit is an ancestor of HEAD (work
landed), set run.json.status = "abandoned" and append a one-line note; if
it's a synthetic/garbage envelope, remove the .claude/pipeline/<slug>/
directory. Report what was pruned.
Without --prune-stale, /sdlc-status is pure read (default). The flag is the
documented, confirm-gated exception — it's the only path that writes.
Rules
/sdlc-status is both the readout and the recommendation. It absorbed the former
/next ladder and /triage classes, so there is one command for "where am I" and
"what next". It never executes — it recommends.
Pure read by default, no file writes. The sole exception is --prune-stale
above, which is explicit and confirm-gated.
No subagent calls, no multi-step workflows.
Keep the output under 6 lines unless the user asks for detail.
If the user wants more (e.g., "show all pending"), list them in a compact table but still no subagent.
Missing _started_at_ / _completed_at_ / _blocked_reason_ markers are
reported as "unknown"; never raise an error or refuse to summarize.
1---2name: sdlc-status3description: Show a quick readout of the current work queue: task counts by state, the active task, and the most recently completed task. Also surfaces any non-terminal pipeline runs (so a stalled /sdlc run can't hide). Reads TASKS.md and .claude/pipeline/ directly — no subagents, no dashboards. Invoke via /sdlc-status or when the user asks "what's left?", "current task?", "status". Read-only by default; `--prune-stale` is an opt-in, confirm-gated cleanup of stale/orphaned pipeline envelopes.4---56# Status — one-glance work readout78## Flow9101. **Read `TASKS.md`** at the repo root. If missing, report "no TASKS.md yet — run `/repo-onboarding` or `/task <description>` to create one" and stop.112. **Count checkbox states** across the file:12 - `[ ]` → pending13 - `[~]` → in progress14 - `[x]` → done153. **Identify the active task**: the first `[~]` row, or if none, the first `[ ]` row.164. **Identify the last completed**: the most recent `[x]` row (top of the `Done` section, or last `[x]` before it).175. **Parse optional metadata markers** on each row (additive — absent fields are fine):18 - `_started_at: YYYY-MM-DD_`19 - `_completed_at: YYYY-MM-DD_`20 - `_blocked_reason: <short reason>_`2122 Treat missing fields as **"unknown"** rather than as errors. Do not warn.236. **Compute summaries**:24 - Cycle time per `[x]` row = `completed_at − started_at` in days, when both25 are present. Surface the median across the most recent ~10 done rows; skip26 rows where either field is unknown.27 - Blocked-reason rollup: count distinct `_blocked_reason: …_` values under28 the `Blocked` section.297. **Scan pipeline run-state** (the discipline signal). Follow30 `skills/sdlc/templates/envelope-staleness.md` — the shared scan, including its31 false-positive guards (skip on `main_branch`, at most one report, silence when32 nothing changed). Read-only here: surface non-terminal and stale runs, don't33 rewrite them. `--prune-stale` below is the only mutating path.348. **Print a 3–7 line summary**:3536 ```37 TASKS: N pending · M in_progress · K done · B blocked38 Active: (P<pri>) <title> — plans/tasks/task-<N>-<slug>.md39 Last done: <title> (cycle: <D> days, or "unknown")40 Median cycle (last 10): <D> days (omit if all unknown)41 Blocked reasons: <reason1> ×N · <reason2> ×M (omit if no blocked rows)42 Pipeline: <slug> @ <stage> (<pipeline>, in_progress 3d — reconcile) (omit if none non-terminal)43 ```4445 If there's no active task, say "no active task — next up: <first pending>".46 A non-terminal pipeline run is the one thing worth making loud — it's how a47 skipped/abandoned pipeline becomes visible instead of lingering in JSON.4849## Next step (absorbed from the former `/next`)5051After the summary, print **one** recommended next command with a one-line reason. Highest52match wins; stop at the first hit:53541. **Paused/failed run on this branch** → `/sdlc <input> --resume`. Read the failing55 stage's sidecar and name the class in the reason — **flaky** (a test flips across loops) ·56 **code-defect** (a consistent assertion failure) · **plan-wrong** (the failure contradicts57 a plan step) · **config-missing** (a command/env the runner needs). For a code defect,58 recommend `/task fix: <one-line failure>` first, then the resume.592. **Non-terminal run whose work looks landed** (`base_commit` is an ancestor of HEAD) →60 `/sdlc-status --prune-stale` to reconcile.613. **Pending sentinel** (`.claude/.next-action` non-empty) → surface each line's `cmd`62 verbatim. Never consume the sentinel here; this skill is read-only.634. **A plan file with no pipeline run** → `/sdlc <plan>`.645. **`[~]` in-progress TASKS.md row** → `/sdlc task-<N>`.656. **`[ ]` pending rows** → the top one: `/task` if small and bounded, `/sdlc` if it66 needs the full pipeline.677. **Nothing queued** → `/brainstorm` for ideation, or `/repo-health` for a hygiene sweep.6869Print it as `Next: <command> — <reason>`. **Recommend only; never execute.** The classes in70rung 1 are what the former `/triage` did — the diagnosis is a paragraph, not a skill.7172## `--prune-stale` (opt-in cleanup — the one write exception)7374Detection alone leaves stale envelopes flagged forever. `/sdlc-status --prune-stale`75lets you actually clear them — confirm-gated, never automatic:76771. Find pipeline runs that are **non-terminal** (`in_progress`/`paused`) **and**78 either older than `discipline.staleness_hours` (default 24) **or** whose79 `base_commit` is not a real git object (`git cat-file -e <base_commit>` fails80 — a synthetic/placeholder base that nothing will ever reconcile).812. **List them and ask for one confirmation** before touching anything: show82 each slug, stage, age, and why it qualifies.833. On confirm, for each: if its `base_commit` is an ancestor of HEAD (work84 landed), set `run.json.status = "abandoned"` and append a one-line note; if85 it's a synthetic/garbage envelope, remove the `.claude/pipeline/<slug>/`86 directory. Report what was pruned.8788Without `--prune-stale`, `/sdlc-status` is **pure read** (default). The flag is the89documented, confirm-gated exception — it's the only path that writes.9091## Rules9293- **`/sdlc-status` is both the readout and the recommendation.** It absorbed the former94 `/next` ladder and `/triage` classes, so there is one command for "where am I" and95 "what next". It never executes — it recommends.9697- Pure read by default, no file writes. The sole exception is `--prune-stale`98 above, which is explicit and confirm-gated.99- No subagent calls, no multi-step workflows.100- Keep the output under 6 lines unless the user asks for detail.101- If the user wants more (e.g., "show all pending"), list them in a compact table but still no subagent.102- Missing `_started_at_` / `_completed_at_` / `_blocked_reason_` markers are103 reported as "unknown"; never raise an error or refuse to summarize.