Files
agent-skills/skills/plan-milestone/SKILL.md
T
Miguel Palhas a229d0ce79
ci / nix (push) Successful in 9s
ci / lint (push) Failing after 13s
fix(plan-milestone): send owner and repo in dependency payload
2026-08-26 07:01:58 +01:00

5.7 KiB

name, description, user-invocable, args
name description user-invocable args
plan-milestone Turn a design doc or feature idea into a tracker milestone with a filed, labeled, interdependent issue set — by auditing what already exists, grilling the operator through the open decisions, and drafting the full set for approval before filing. The milestone is the handoff unit: /blitz <milestone> sweeps it, and parallel planning efforts stay distinguishable. Use when the user wants to plan a feature area into issues, e.g. "plan TV tracking" or "/plan-milestone §6 of DESIGN.md". true
name description required
input What to plan: a design-doc section, a feature description, or a doc path. Omit to ask. false

Plan Milestone — Design to Issue Set

Produces a tracker milestone holding a set of issues another session can land one at a time — /blitz <milestone> is the intended consumer, /yolo works per issue. The milestone is what keeps two concurrent planning efforts apart: every issue this skill files belongs to the milestone it creates. The output is the milestone; this skill never implements anything.

First: read tracker-common/COMMON.md (sibling skill, same skills root) for project config and tracker API conventions.

1. Ground yourself

  1. Read the design document end to end if the repo has one (DESIGN.md or whatever CLAUDE.md names as the contract). The design doc is authoritative: if planning surfaces a contradiction, the fix is a design-doc amendment issue, never an issue that quietly contradicts it.
  2. Audit what already exists — code, migrations, API surface, closed issues — so the set covers the gap, not what is built. Plan from evidence, not from the doc's table of contents.
  3. Learn the label taxonomy: the repo's CLAUDE.md, or the tracker's existing labels. A good taxonomy has one label per axis per issue (e.g. phase/, area/, difficulty/, type/). If the repo has none, propose one to the operator before drafting.

2. Grill the operator

The operator holds decisions the design doc doesn't. Interview them in batches, one batch at a time — a wall of twenty questions gets skimmed; four pointed ones get answered.

  • Ask about behavior, not implementation: semantics, defaults, edge cases, what "done" looks like for the user.
  • Challenge vague answers and surface tradeoffs ("per-episode grabbing doubles indexer load — accept that or prefer season packs?").
  • Where the design doc is thin or self-contradictory, say so explicitly and get a ruling.
  • Record each settled decision in one line; these lines become issue-body context.

Stop interviewing when new questions stop changing the issue set.

3. Draft, then file

Draft the complete set and show it to the operator for approval before filing anything. For each issue:

  • Title: imperative, specific, no scope words like "improve" or "handle".
  • Body: the settled decisions it depends on, pointers into the design doc (cite sections, don't restate them), and explicit non-goals when adjacent scope is likely to creep. Still write Depends on: #N lines for a human skimming the body, but they are cosmetic — the tracker's real dependency graph, not prose, drives execution order (see step 2 below).
  • Labels: exactly one per axis. Difficulty drives model selection downstream, so calibrate it against the work's real shape, not its size — a large mechanical issue is easy; a ten-line scoring change can be hard.
  • Scope: one session must be able to land it without widening it. If a draft needs two sessions, split it; if two drafts always land together, merge them.

After approval:

  1. Create the milestone (POST $BASE/api/v1/repos/$REPO/milestones) named for the feature area, with a one-paragraph description linking the design doc section and stating the goal. Reuse an existing open milestone only if the operator says this plan extends it.

  2. File each issue with the milestone set (milestone: <id> in the create payload), then its labels. An issue outside the milestone is invisible to /blitz <milestone> — the milestone link is not decoration, it is the execution boundary. Keep the Depends on: #N body lines from the draft — don't strip them once real dependencies exist, they're what a human reading the issue sees.

  3. Wire real dependencies. File issues in dependency order (blockers before dependents) so every #N referenced already has a number. For each Depends on: #N line on a just-filed issue #M:

    curl -sS -X POST -H "Authorization: token $GITEA_TOKEN" -H "Content-Type: application/json" \
      "$BASE/api/v1/repos/$REPO/issues/$M/dependencies" \
      -d "$(jq -nc --arg owner "$OWNER" --arg repo "$REPO_NAME" --argjson index $N \
            '{owner: $owner, repo: $repo, index: $index}')"
    

    owner and repo are required even for a same-repo dependency. Gitea resolves the blocker by owner/repo/index, and omitting them returns a bare 404 with no explanation. $REPO_NAME is the repo name alone, not owner/repo.

    This is Gitea's actual dependency graph (GET .../issues/$M/dependencies lists it) — /blitz reads this, not the prose. The body text stays for human readers; the API call is what makes it load-bearing.

  4. Report the milestone name plus the issue numbers with their dependency edges so the operator can eyeball the DAG, and note the follow-up command: /blitz <milestone>.

What this skill must not do

  • Implement, branch, or push code.
  • File before the operator has seen the full set.
  • Restate design-doc content in issue bodies — reference it.
  • Leave a dependency implied in prose (Depends on: #N) but missing from the real Gitea dependency graph.
  • File an issue without the milestone link.