rail-build
Rail Build
Implement tasks from docs/monorail/<feature>/tasks/. One session, serial run: after a task goes green, continue to the next frontier task in the same session — no fresh session, no check-ins or questions between tasks. Defaults: run to queue-clear, one commit per task on the current branch. The skill never asks about run length or commit policy — the user states any deviation (review pause, no-commit, narrower run) in their command and the agent honors it.
Confirm with the shell before concluding it is missing (ls docs/monorail/work-tracker.md, or read the path directly) — search tools skip gitignored paths, so an empty Glob/Grep result is not evidence of absence. If it is missing on disk, tell the user to run /rail-setup and stop.
Process
- Load the task file and its parent
spec.md. Ifspec.mdis missing, stop and suggest/rail-spec. Confirm blockers are done (blocker tasks showStatus: done). If the task showsStatus: claimedbut its## Commentshas no matchingRun <date>: startline (a stale claim from a crashed run), recover it: revert toStatus: openwith a## Commentsnote before working — a staleclaimedsilently blocks the frontier. - If the task is too large for one context window, stop and suggest
/rail-slicere-split or/rail-align— do not hard-code a giant task. - Claim: set
Status: claimedon the task file before coding. - Explore on demand — read what the task needs (paths, types, call chains, nearby tests,
docs/monorail/CONTEXT.md/ ADRs), at the depth the task warrants; a small task needs no ceremony, often one or two file reads. Use the read-only sweep under Exploration only when the territory is genuinely unfamiliar or wide — never let it delay red-phase TDD. Before writing any test, open the file(s) the task'sSeams:line points at. If the code contradicts the spec's## Testing Decisions(a seam is missing, wrong, or overlaps unlisted code), do not re-derive seams and do not keep coding — stop per §4 and report; otherwise proceed on the spec's seams. - Drive
/rail-tddat the task'sSeams:line (set at slice time from the spec's code-anchored## Testing Decisions). - Run typecheck / relevant tests regularly; full suite once at the end.
- Set task
Status: donewhen the task's behaviour is covered (TDD complete at the task'sSeams:) and typecheck / relevant tests are green — and append the done-gate block under## Comments(see §3.2). Do not run/rail-reviewas part of build — review is opt-in (see/rail-review). - Commit once per task on the current branch (default policy — the task's single commit carries its claim and status changes); skip committing only when the user opted out for this run.
- Continue or stop. Another frontier task exists and the user's go-ahead covers it → continue serially (see Serial run). Otherwise stop and report where you left off. When the run ends with no open/unblocked tasks remaining, cross-check that every numbered
## User Storiesentry inspec.mdis covered by adonetask (or explicitly out of scope) — report any uncovered story instead of claiming the queue is clear — then say the feature's implementation queue is clear (human decides merge/ship; a new feature starts at/rail-align).
Frontier (implementation): Status: open, every listed blocker is Status: done, not claimed; lowest NN wins (see docs/monorail/work-tracker.md). Read task files by path, and list tasks/ with the shell (ls docs/monorail/<feature>/tasks/) — search tools skip gitignored paths, so an empty Glob/Grep result is not evidence the queue is empty.