| name | build |
| description | Use in the build session to ship a Linear FRE ticket from Approved to a master-ready PR (CI green + any bounce resolved) — fresh-start reset, plan with risk-tiered codex review (reviewer, not co-author), TDD, docs, PR, then self-complete via watcher/master pokes. Never merges or deploys. |
Build a Linear Ticket (build session)
Read .claude/skills/lifecycle-rules.md first. Argument: a stream selector (1 or 2), or an explicit Linear issue ID (e.g. FRE-471).
Stream selector (1/2) → resolve NEXT via the external dispatch resolver (scripts/dispatch/next_resolver.py, FRE-785; the busy guard, priority ordering, and blocked-by skip are NOT logic held in this skill — ADR-0113 §1). FIRST git fetch origin (you still need latest main for Step 0). Then run python -m scripts.dispatch.next_resolver --stream build<N> --json. A nonzero exit, invalid JSON, or a printed error (e.g. missing AGENT_LINEAR_API_KEY) → STOP and surface stderr — never fall back to reconstructing the busy-guard/priority/blocked-by logic inline. A null result (the stream is occupied — building, or a PR at master's gate that could bounce back; it frees at Awaiting Deploy — OR there is no eligible Approved candidate; the resolver conflates both) → STOP, same as the empty/ambiguous-queue case below. A non-null result names the ticket to build — read its context:keep status straight off the JSON's labels field (Step 1's get_issue still fetches the full ticket for scope/body). Honor its context flag (context:keep label → KEEP; absent → CLEAR):
- CLEAR (the default): this ticket wants a fresh slate. First check: are you a blank/new session — freshly started or just
/cleared, with essentially nothing in context but this invocation and session-start priming? If yes, proceed. If no (you still carry a previous ticket's work in context), STOP and tell the owner: "FRE-… is flagged CLEAR — run /clear, then /build <N> again." A stale prior-ticket context pollutes the plan.
- KEEP: the NEXT ticket is a direct follow-on (same files/substrate) — proceed on the current warm context regardless of the blank-session check; do not ask for a
/clear.
An explicit FRE-… id skips the queue and builds that ticket (treat Context as CLEAR unless the owner says otherwise). If the queue is empty or ambiguous, STOP and ask master.
Step 0 — Fresh-start (worktree reset + retire the merged branch)
git fetch --prune origin
- Safety gate — BOTH must hold, else STOP and surface:
git status --short is empty
- the current per-ticket branch is merged (or nothing unpushed:
git rev-list --count @{u}..HEAD is 0)
- Cut a fresh branch off latest main for the new ticket:
git switch -c fre-<id>-<slug> origin/main.
- Retire the now-merged previous branch — local THEN remote (so branches don't pile up on origin).
The lowercase
-d is the verification: it refuses on an unmerged branch, so only a merged branch is
ever deleted; run the remote delete only after -d succeeds. Never delete the
worktree-build / worktree-build2 / worktree-adrs anchors.
git branch -d <merged-branch>
git push origin --delete <merged-branch>
- Confirm branch + worktree (
git worktree list, git branch --show-current); paste.
1 — Ticket
get_issue(<id>) on FrenchForest; must be Approved. If Needs Approval, STOP and tell the owner.
Then set the ticket → In Progress (save_issue state="In Progress"). The GitHub integration
automates only the PR transitions (PR opened → In Review, PR merged → Awaiting Deploy — retargeted
2026-07-04); the session doing the work owns the In Progress transition; master owns the Done
transition at the gate.
1.5 — Done = master-ready (responding to a poke)
Never arm a /loop monitor — polling re-reads the session context past the prompt-cache TTL every
tick (an uncached-cost blowup, removed 2026-07-06). You do the work and open the PR, then go idle — but
you are not done at the PR; you are done when the PR is master-ready: CI green AND any bounce resolved.
You don't wait for CI (that's the loop) — you go idle, and something re-engages this warm seat:
- CI goes red → the watcher pokes this seat with a plain message.
- master bounces → master tells this seat directly.
Either poke: read it, fix on this branch, re-run the Step-8 quality gates, git push, go idle again. Your
context is warm — you built this — so the fix is cheap. (This is the old /prime-worker, folded in; that
skill is gone.)
2 — Scope
Read ticket body + linked ADRs + specs. Summarize scope in 3–5 bullets. Pull out the acceptance
criteria this ticket carries from the backing ADR (adr SKILL Step 5) — the testable, outcome-level
invariants you must prove. They are the definition of done. If a feature ticket names none and it is
not a standalone bug, get them from the ADR or flag the gap before coding — master will bounce a PR
with no provable criteria.
3 — Plan + (risk-tiered) codex review
Write a plan: atomic steps, exact file paths, exact test commands.
Self-classify the work from the Step-2 scope (you have the most context here — master does not pre-route this):
- Trivial — mechanical only: docs / config / test-only / a one-liner; no
src/ logic change, no
schema / security / cost / memory / new-ADR-implementation. → skip codex plan-review; the Approved
ticket is sufficient authorization, proceed straight to TDD.
- Standard / Complex — touches
src/ logic, schema, security, cost, memory, a new ADR's
implementation, or multi-file behavior. → codex plan-review REQUIRED: invoke codex:rescue on the
plan (approach second-opinion), revise per findings, and get explicit owner approval before coding.
When in doubt, treat as Standard and run codex — bias toward review. Codex is a reviewer here, not a
co-author: you own the work and codex gives the independent, adversarial second opinion (adversarial beats
redundant); reach for codex as a collaborator only in Step 7 rescue, when you're genuinely stuck. Lean
reviewer — that's your judgment to make per plan. The owner/master may override per ticket in the dispatch
with [codex: required] (force it) or [codex: skip] (force-skip) when they know something the scope
doesn't show. Master backstops this at the gate — a mis-tiered Standard change that
skipped codex gets bounced. (One phase = one PR — see halt conditions.)
4 — TDD implement
Failing test first → confirm it fails → implement. Each acceptance criterion from Step 2 gets a
test or probe that asserts the outcome — the invariant actually holds — not that the component is
wired; this is the proof master's gate reads. Standards (.claude/CLAUDE.md) + ADR-0074 identity
threading on every new log.* / bus.publish / Cypher MERGE|CREATE.
5 — Meet the objective — fold in, don't over-ticket
A ticket is an objective — a user story, usually spawned from an ADR but not uniquely — not a
boxed single change with no deviation allowed. Your job is to meet the objective; the supporting
changes and reasonable deviations you discover while building or in review are part of meeting it,
not separate work. This is a single-developer project — tickets are for structured sequencing of
real / planned / ADR work, not a log of every change; over-ticketing only delays development.
- Non-ADR supporting changes needed to make THIS build function (a helper, a small fix, a config
tweak the feature depends on) → fold them into this PR. Do NOT file a ticket. Note them in the
handoff (Step 9) so master validates them as supporting rather than reading them as scope creep.
- Findings from a code review — your self-review (Step 8) or master's gate — that are reasonable
changes to THIS build task → fix them in this PR. No multi-ticket paper trail for review fixes.
- File a new Needs-Approval ticket ONLY for genuinely separate, sequenceable work OR anything
ADR-requiring (a design decision / a new architectural surface). When unsure, prefer folding
in over ticketing — a ticket explosion buys nothing for one developer.
6 — Documentation
Update docs the change touches (skill docs, READMEs, doc-strings).
7 — Codex rescue (escalation only)
3 failed attempts OR same error twice OR self-revert → invoke codex:rescue with full error context.
8 — Quality gates (all pass before PR)
make test (module then full) · make mypy · make ruff-check + make ruff-format ·
pre-commit run --all-files.
Self-review before the PR (shift-left — you fix your own findings so master never has to bounce
them). Run it once, at this pre-PR gate — NOT on every implementation turn (a strategic
checkpoint, not a per-turn tax). Invoke the code-review skill on your branch diff, effort sized to the diff: low
for a small/localized change, high for src / schema / security / cost / memory. Sizing means
dialing the level, NOT skipping — any real-logic change (a script, a helper, behavioural config)
gets at least a low pass; only pure docs / config-values / test-only diffs skip it. Invoke
security-review too when the diff touches inputs / subprocess / files / auth / secrets / network.
Fix every confirmed finding on your branch before opening the PR, and note in the PR body that
the review ran and what you addressed. (FRE-847: a high review caught 3 confirmed correctness bugs
in a 146-line script — "it's small" is not grounds to skip.)
9 — PR + final ticket comment for master — then STOP
Sync to latest main FIRST (prevents a stale-base collision / a DIRTY PR at master's gate when a
sibling PR merged during your session): git fetch origin && git rebase origin/main — resolve any
conflicts in-session (you have the context; master won't), re-run the Step 8 quality gates, then
git push --force-with-lease. Then open the PR with .github/PULL_REQUEST_TEMPLATE.md. Pre-merge
checklist ONLY (see lifecycle-rules PR hygiene).
Then post a final comment on the Linear ticket addressed to master (save_comment on the
issue) — this is required, not optional. It carries everything master needs that does NOT belong
in the PR's pre-merge checklist:
- acceptance-criteria proof (the master gate's input — master SKILL Step 4): the backing ADR + the
specific criteria this ticket implements, and for each, the evidence it is delivered end to end
(test name + result, probe/query output, or observed behaviour at the criterion's altitude). Without
it master bounces the PR. (Standalone bug: the reproducing test / verification stands in for ADR
provenance.)
- self-review summary (the executive input for master's gate — master SKILL Step 2): the
code-review effort level run and the security-review verdict; what they flagged (confirmed
findings, most-severe first) and what you fixed on-branch; call out anything you deliberately did
NOT fix and why. "No findings" is a valid summary. A real-logic diff with no summary gets bounced.
- the post-deploy runbook (exact ES/Kibana/migration/verification steps, in order);
- any safety constraints / gotchas (e.g. "do NOT back-attach existing indices", "register the
template before first write", "verify the code is generating the logs");
- what to verify live to prove the AC (commands + expected output);
- discovered follow-up tickets filed;
- the Linear auto-Done caveat if the deploy will be batched;
- your context disposition for the next ticket — whether you want your context kept (the next
queued ticket is a direct follow-on — same files/feature, multi-phase, regression test for what you
just built, depends on a fresh discovery) or cleared (
/clear — different area; you know your own
context best). State it plainly, e.g. "FRE-X next: keep — shares this refactor" / "clear before next".
Master reads this comment by default at the gate, so it is the handoff channel.
STOP. Do not merge, deploy, close the ticket, or edit MASTER_PLAN — that is master's role.