Gabe Next — zero-logic lifecycle router
Usage: /gabe-next [--dry-run]
Gabe execution contract (E1–E7)
This skill runs under the suite execution contract — E1 EVIDENCE · E2 RUN-BEFORE-✅ · E3 NO SILENT DOWNGRADE · E4 REUSE FIRST · E5 STATE SYNC · E6 MISSING ANCHOR = STOP · E7 REPORT WHERE — floors, not ceilings; a skill's own gate may be stricter, never looser. Full text: ../gabe-docs/references/execution-contract.md (if that file is missing, E6 applies — STOP).
Thin router. Reads plan state, finds the next unticked cell, and dispatches to the matching gabe-* command. Zero LLM cost. No state writes of its own (except the Current Phase advance defined below).
Design principle. This command does not execute tasks, reason about them, or modify files. It answers one question: "Given PLAN state, what's the next gabe command to run?" Then it runs that command (or prints it on --dry-run).
Procedure
Step 0: Validate preconditions
.kdbp/exists → else print⚠ No KDBP. Run /gabe-init first.and exit..kdbp/PLAN.mdexists and contains<!-- status: active -->→ else printℹ No active plan. Run /gabe-plan [goal] to create one.and exit.
Step 0.5: Deterministic route via scripts/next.mjs (preferred path)
Run node <this skill dir>/scripts/next.mjs (add --json for machine output). It reads .kdbp/PLAN.json and prints the full decision — prior-row sweep warnings, any advance instruction, PHASE/STATE/NEXT/REASON — implementing Steps 1–2 below deterministically (cell tokens deferred/obsolete count as settled rows and are skipped/advanced over with a printed notice).
- Exit 0 → take its decision verbatim: perform any
advance Current Phase to <id>instruction it printed (rewrite## Current Phase+ bumpLast Updatedin PLAN.md AND mirrorcurrent_phase/last_updatedinto PLAN.json — same turn, E5), then go to Step 3 (dispatch). - Exit 1 → it printed the terminal message (no active plan / plan complete); surface it and stop.
- Exit 2 → PLAN.json missing or unusable: print its notice, then fall back to the prose routing below (Steps 1–2) over PLAN.md. Never block on the mirror.
Step 1: Parse PLAN.md (prose fallback — only when next.mjs exited 2)
Read .kdbp/PLAN.md. Extract:
- Current Phase pointer. Line matching
## Current Phase→ next non-blank line → leading integerNfromPhase N: .... If missing or unparseable → print⚠ PLAN.md: Current Phase section missing or malformed.and exit. - Phases table columns. Detect column names from header row. Expected:
# | Phase | Description | Types | Tier | Complexity | Red | Exec | Review | Commit | Push | Center. Three columns are optional: legacy plans may lackExec; only TDD-adopting projects carryRed(before Exec); only command-center projects carryCenter— treat any missing column as always-✅ (skip that step).Redpresent-and-⬜ means the phase's failing cases are not yet committed;Centerpresent-and-⬜ means the shipped phase is not yet covered in the command center. - Target row. Row where first data column equals
N. - Project type. Parse top-of-file HTML comment
<!-- project_type: code | mockup | hybrid -->. If absent → defaultcode. Used by Step 1.5 Exec dispatch. - Target row types. Parse
Typescolumn (or## Phase Details → Phase N → types:YAML) for target row. List like[design-system, ui-kit]. Empty →[]. Used by Step 1.5 hybrid dispatch.
Step 1.5: Resolve Exec command (project_type-aware)
Determines which command handles the Exec step for the target phase. Pure lookup, no state writes.
Mockup-tag set: {design-system, ui-kit, mockup-flows, mockup-index, mockup-docs, mockup-validation}.
project_type |
Target row types intersect mockup-tag set? | Exec command |
|---|---|---|
mockup |
any | /gabe-mockup |
code or missing |
any | /gabe-execute |
hybrid |
yes AND types ⊆ mockup-tag set | /gabe-mockup |
hybrid |
no (mixed or pure code tags) | /gabe-execute |
Store the resolved command as EXEC_CMD for Step 2 use. Review / Commit / Push commands are unchanged regardless of project type.
Step 1.7: Prior-row sweep (always print, never block)
Scan Phases rows 1..N-1. If any Red/Exec/Review/Commit/Push/Center cell ≠ ✅ (Red and Center count as debt only when their column is present), print before the routing decision:
⚠ INCOMPLETE PRIOR PHASES: [12: Review ⬜, Push ⬜ · 34: Center ⬜] — routing continues on Phase N; clear the debt with /gabe-red, /gabe-review, /gabe-push, or /gabe-cc-update on the listed phases.
Step 2: Decide next action (zero LLM)
Apply this decision table, top-to-bottom. First match wins.
| Condition | Next command | Why |
|---|---|---|
Target row's Exec = 🔄 |
EXEC_CMD |
Phase exec in progress (resume — a pending Red never retro-blocks a started exec) |
Target row's Red = ⬜/🔄 (column present only) |
/gabe-red <N> |
Phase planned — failing cases first (TDD); red-before-execute is a machine predicate |
Target row's Exec = ⬜ |
EXEC_CMD |
Tasks not yet implemented |
Target row's Review = ⬜ |
/gabe-review |
Code written and Exec gate complete; runtime-gated phases should only reach this after staging proof |
Target row's Commit = ⬜ |
/gabe-commit |
Reviewed, not committed |
Target row's Push = ⬜ |
/gabe-push |
Committed, not pushed |
Target row's Center = ⬜ (column present only) |
/gabe-cc-update <N> |
Shipped, not yet covered in the command center |
| All lifecycle cells = ✅ on target row AND more phases below | Advance Current Phase to N+1, re-run Step 2 |
Phase done, move on |
| All lifecycle cells = ✅ on target row AND no phases below | /gabe-plan complete |
Plan complete — prompt archive |
The lifecycle cells are Exec · Review · Commit · Push, plus Red before Exec when present (TDD-adopting projects — /gabe-red flips it ✅ when the red checkpoint/guard/skip record lands) and Center after Push when present (command-center projects — /gabe-cc-update flips it ✅ at the REVIEWED stamp, E5). A phase with neither column has the classic four-cell lifecycle, exactly as before.
Advance mechanics. When advancing Current Phase, do NOT write any other file. Only rewrite the ## Current Phase section to point to N+1 and bump Last Updated in Context to today's date. Advancing past a non-✅ prior row is allowed but MUST re-print the Step 1.7 sweep warning — never advance silently over owed Review/Push work.
Step 3: Dispatch
- If
--dry-runin$ARGUMENTS→ print the decision and stop. Format:GABE NEXT (dry-run) PHASE: N — [name] STATE: Exec ⬜ | Review ⬜ | Commit ⬜ | Push ⬜ NEXT: /gabe-execute REASON: Tasks not yet implemented - Else → print the one-line summary, then dispatch the chosen command. Pass through any remaining
$ARGUMENTSafter--dry-runis stripped.
Downstream command contract.
- Prefer the host's native slash-command invocation for the chosen command, e.g. run
/gabe-commitas a command when that is available. - If the host cannot directly invoke nested slash commands, load the chosen capability's skill from the active install (
~/.claude/skills/<command>/SKILL.md) and follow it — including its instruction to read the binding spec under that skill'sreferences/. - Do not replace the chosen command with a hand-rolled equivalent. In particular, when
NEXTis/gabe-commit, do not stop after running rawgit commit; the/gabe-commitnormal-flow output contract must still be satisfied, including the visible**Gabe-Lens brief**, PLAN auto-tick output, and existing LEDGER behavior. /gabe-nextowns only routing and phase advancement. Commit message generation, verification, ledger writes, briefs, pushes, and other side effects belong to the downstream command.
Step 4: Optional-column compatibility
Three columns are optional; a missing one is treated as always-✅ and its routing branch is silently skipped. Never auto-migrate — human migration only.
Execabsent (legacy plans pre-v2.9): decision table collapses to Review → Commit → Push → advance. Printℹ Legacy plan schema — Exec column missing. Add manually or recreate plan via /gabe-plan to adopt it.Redabsent (any project that hasn't adopted the TDD beat):/gabe-redis never routed. No notice — absence is normal. Adopt via/gabe-plan updateadding theRedcolumn (⬜ per remaining phase).Centerabsent (any project without a command center, the common case): the lifecycle is the classic four cells and/gabe-cc-updateis never routed. No notice — absence is normal, not a defect. A command-center project adopts routed coverage by adding theCentercolumn (/gabe-plan update, or by hand); until then the router simply never nags for coverage.
Step 5: Error surfaces
Exit silently (no error) in these cases:
- No
.kdbp/→ printed message per Step 0 - No active plan → printed message per Step 0
- Malformed Current Phase → printed warning per Step 1
- Row N not found in table → print
⚠ Current Phase N has no matching row in Phases table.and exit
Never rewrite PLAN.md on error. Never invoke downstream commands on error.
Example output
$ /gabe-next
ℹ PLAN: Phase 2 — PydanticAI triage agent
→ /gabe-execute
[... gabe-execute runs inline ...]
$ /gabe-next --dry-run
GABE NEXT (dry-run)
PHASE: 2 — PydanticAI triage agent
STATE: Exec ⬜ | Review ⬜ | Commit ⬜ | Push ⬜
NEXT: /gabe-execute
REASON: Tasks not yet implemented
$ /gabe-next
ℹ PLAN: Phase 1 complete — advancing to Phase 2
ℹ PLAN: Phase 2 — PydanticAI triage agent
→ /gabe-execute
$ /gabe-next --dry-run
GABE NEXT (dry-run)
PROJECT_TYPE: mockup
PHASE: 2 — Atomic components
TYPES: design-system, ui-kit
STATE: Exec ⬜ | Review ⬜ | Commit ⬜ | Push ⬜
NEXT: /gabe-mockup
REASON: Tasks not yet implemented (mockup dispatch via project_type)
$ /gabe-next --dry-run # command-center project: shipped phase not yet covered
GABE NEXT (dry-run)
PHASE: 35 — CE · Consent honesty
STATE: Exec ✅ | Review ✅ | Commit ✅ | Push ✅ | Center ⬜
NEXT: /gabe-cc-update 35
REASON: Shipped, not yet covered in the command center
Non-goals
- Does NOT run lints, tests, type checks — those belong to
gabe-review/gabe-commit - Does NOT generate commit messages, briefs, or code — those belong to
gabe-execute/gabe-commit - Does NOT read git state — decisions come purely from PLAN.md cells
- Does NOT modify LEDGER.md, PENDING.md, KNOWLEDGE.md
- Does NOT emulate downstream command internals after routing
- Does NOT call LLMs under any circumstance
$ARGUMENTS