Appearance
build-dev-plan
build-dev-plan
buildwriteshands-off
Use this when: you want to see what to work on next
Build Dev Plan
One live, mobile-readable issue that tells you — at a glance from a phone — what to pick up next: the open work in the earliest milestone, ordered so the top item is the one to start, plus a flag for how much backlog still has no home. The work-in mirror of build-qa-plan (which does the ship-out / open-PR side).
It is a board, not an editor. organise mutates backlog structure (places, re-homes, orders, sets deps); build-dev-plan only reads that structure into a current, ordered, mobile-readable board and flags what organise still needs to fix — it changes nothing. That read-only-board / interactive-editor split is exactly why it earns its own skill rather than folding into organise (mirrors build-qa-plan being a board over the PRs). It is a status board, not a snapshot — every run re-derives the facts from GitHub.
Contract
- Task class: build — produces/refreshes a tracking artifact.
- Allowed tools:
gh(issue/milestone list+view JSON, native Issue Types, sub-issues; issue create/edit, label create) perdocs/agents/issue-tracker.md; Read/codegraph for context. (In the web/remote env themcp__github__*tools stand in forgh.) Projects v2Statusis NOT on the REST issue /gh issuepayload — read it from the board via the GraphQL API (projectItems → fieldValueByName("Status")); in the web env,curl https://api.github.com/graphqlwith$GH_TOKEN. Area is a label (on the REST payload). Native milestonedue_onand the search countno:milestonecome from REST/search, notgh issue view. - Direct vs fork: direct. Fork a
scanner/general-purposegather only when the issue set is large (≳25) and you want the digest, not the raw JSON, in-thread. - Verifiable artifact: exactly one open issue titled "Dev Plan", labelled
plan, whose body reflects the current earliest-milestone work + orphan count in the format below.
Fresh data, ordered by readiness — this is the skill
The plan's whole value is that the top line is genuinely the thing to start now — so the heart is re-deriving live state and ordering by readiness, not the formatting (which is mechanical).
Re-derive every fact from GitHub on every run. Never copy a claim from the existing plan body — a milestone may have shipped, an issue's Status may have moved from Needs Info to Ready for Agent, a blocking dependency may have closed, an orphan may have been placed. A stale plan is worse than none, because it's trusted. Per in-scope issue pull live: Issue Type (Epic/Sprint/Task/Bug/Feature), milestone, sub-issue parent (Task→Sprint→Epic), Status (Projects v2 board) + Area (label), and native blocked-by dependencies (open or closed?).
Then order by readiness (the same gate organise applies, here read-only): only Ready for Agent / Ready for Human issues are startable; one at Needs Info (incl. vet-flagged) or with an open blocked-by is listed but marked held, never the next pick. Weigh Status and deps together — a held item never goes to the top. Getting this order right is where the effort goes.
Workflow
- Find the earliest open milestone — by the maintainer's fixed order, not by date. The milestone sequence is an explicit, maintained order (currently Foundational → Launch → post-launch buckets). The early ones are dated (Foundational, Launch) and scheduled; the post-launch buckets are deliberately undated ("do this after launch", split into a small number of buckets by urgency). So: dated milestones first in
due_onorder, then the undated buckets in their maintained manual order (the order on the milestones list / board) — never inferred from creation date (creation order ≠ urgency). The earliest open milestone = the first in that sequence that still has open issues. State the basis in the plan header. - Walk DOWN the tree. Milestone issues are usually Epics, not leaf work — the startable items are their child Sprints/Tasks. Descend each Epic's sub-issue tree and place items under
## Epic #NN — <title>/### Sprint <n> · <title> (#NN). A milestone issue that's itself a bare Task/Sprint (no parent) goes under**Loose in milestone**; an Epic with no sub-issues yet is listed as an empty epic that needsorganise/to-issuesto populate it. - Order within a group by readiness then dependency: startable (
Ready for Agent/Ready for Human, no open blocker) first — top item = next pick — then held items with the reason. A Sprint with all-ready Tasks is itself startable viabuild-sprint. If nothing is startable (everything atNeeds Triage/Needs Info— common for a fresh milestone), say so plainly at the top and make the next action "triage these toReady(viatriage/organise)" rather than inventing a pick. - Per issue, fill the block (template below) from live data + a one-line read of what it is and whether Claude can build it now.
- Compute the orphan flag — a deliberate whole-backlog health signal, kept separate from the milestone plan: count open issues with no home — untyped, OR no milestone, OR no epic/sprint parent. Exception: a
Bug-typed issue that is top-level is correctly placed, not an orphan (the bug placement convention —docs/agents/triage-labels.md); never count it. It's a single number + nudge at the top, not part of the ordered plan below (those orphans aren't startable from here). It only counts + nudgesorganise— it never places them. - Find-or-update the plan.
gh issue list --label plan --state open→ there may already be aQA Planon that label; match on titleDev Planspecifically. If a Dev Plan exists,gh issue edit <n>its body; else create it. Title is always exactlyDev Plan. If theplanlabel is missing,gh label create planfirst. - Write the plan automatically — no confirm gate. Create or edit the single
Dev Planissue (andgh label create planif the label is missing) without pausing for approval. The maintainer has given standing approval for this auto-write: the artifact is one known, in-place tracking issue, the edit is idempotent, and it spawns no work — so the write is low-risk (unlikeorganise, which mutates backlog structure, or a skill that opens PRs). Still surface the plan in chat so it's reviewable, and report the issue link once written. (This is the deliberate exception to the surface-then-confirm default — every other outward write in the harness still confirms.)
Format
# Dev Plan — <milestone title> (earliest open milestone)
⚠️ **<N> issues have no home yet** (untyped / no milestone / no epic·sprint parent — top-level `Bug`s excluded by convention) → run `organise` to place them. ← ✅ if zero
## Epic #NN — <title>
### Sprint <n> · <title> (#NN)
<▶ startable | ⏸ held: reason>
- [ ] <🧩> #NN — **<readable title>** · <Status>
_<one concise line: what it is>_
**Claude can:** <build it now / needs info: what's missing / blocked-by #NN>The sprint's status token sits on its own line (not inline after the title) so it doesn't wrap awkwardly on a narrow phone. End with the legend: ▶ startable now · ⏸ held (needs info / blocked) · 🧩 best next pick. Mark exactly one item — the single best next pick across the whole plan — with 🧩. Every #NN is a clickable Markdown link (mobile-first — see CLAUDE.md). Keep titles bold, one block per issue — no nested bullet trees (they waste horizontal space on a phone).
Failure branch
- No milestones / none with issues → say so, fall back to listing the highest-readiness open issues regardless of milestone, and flag that milestones need setting up (point at
organise). - No Projects board configured (Status unavailable) → order by dependencies + Type alone, and note that readiness couldn't be read.
- An issue's parent can't be resolved → place under
**Loose in milestone**and say why; don't guess a parent.
Output / handoff
The single open Dev Plan issue, current. Then offer to hand the top startable sprint to build-sprint (or the milestone's epic to build-epic) to execute, and — if the orphan count is non-zero — organise to place the homeless backlog. Pairs with build-qa-plan for the open-PR side.