A7 — Breakdown skill: generate issues from specs/*.md #142

Closed
opened 2026-04-20 13:02:26 +00:00 by claude-desktop · 0 comments
Collaborator

User story

As the operator, I want a breakdown skill the orchestrator can dispatch against a specs/*.md file so that large spec documents get automatically decomposed into a set of correctly-labeled user-story issues — the way the global CLAUDE.md breakdown conventions prescribe — without me writing every ticket by hand.

Context

Closes the A7 story of milestone #16 Agent pool + customization (the last open story — tracking issue #47).

Today, I (claude-desktop) manually write each user-story issue when we decompose a feature. The user wants to move this workload to the boss/dev agents: feed a specs/<name>.md to a breakdown skill, get a batch of tickets back with:

  • Full user-story bodies (As a <role>, I want <capability>, so that <outcome>)
  • Acceptance criteria grouped by sub-section
  • Out-of-scope list
  • References + dependencies block
  • Correct area:* + type:user-story labels
  • Optional milestone assignment
  • Suggested implementation order at the tail

The resulting labels drive label-aware dispatch (A3) — a reviewer-security instance picks up issues tagged area:security, etc.

Acceptance criteria

Skill file

  • New skills/breakdown.md, following the same vocabulary + structure as the existing implement.md.
  • Input variables (interpolated by dispatch): {{repo}}, {{spec_path}}, {{milestone}} (optional).
  • Skill instructs the agent to:
    1. Read {{spec_path}} from the repo's specs/ directory (fail loudly if missing).
    2. Parse the spec into discrete user-stories, following the conventions in the operator's global CLAUDE.md (As a <role>… / Acceptance / Out of scope / References / Dependencies).
    3. Reconcile labels with list_repo_labels; file new area:* labels only if the operator has pre-approved them in a config (see below).
    4. Create issues via mcp__forgejo__create_issue in parallel where safe (the operator is fine with non-sequential issue numbers — see CLAUDE.md).
    5. Apply labels via add_issue_labels (by numeric ID — the forgejo-mcp gotcha in memory).
    6. If a milestone is specified, attach it to each issue via update_issue.
    7. Post a summary comment on a tracking issue if one exists ({{tracking_issue}} optional var): lists the created numbers + their titles, with the suggested implementation order.

Dispatch path

  • New HTTP surface: POST /breakdown — payload { repo, spec_path, milestone?, tracking_issue? }. Looks up the boss pool, dispatches the breakdown skill, returns { task_id }.
  • Alternatively (operator's choice — document both in the PR body): webhook-triggered on an issue labeled type:spec-breakdown pointing at a specs/*.md path in the body. Simpler to wire; the first story in the resulting breakdown can be the operator's review of the batch.

Guardrails

  • Never create duplicate issues — before creating, search the repo for existing issues whose title matches the proposed story's title (case-insensitive); if one exists, skip with a log entry.
  • Cap the number of stories per dispatch at a sane number (e.g. 15) — if the spec would decompose into more, emit the first 15 + a "next batch" summary comment.
  • No cross-repo — repo must match the orchestrator's own configured repo (out-of-scope per #47).
  • Dry-run flag ({{dry_run}} var): if true, the skill lists the proposed issues as a comment instead of creating them.

Tests

  • src/breakdown.test.ts — unit coverage of the webhook / HTTP route that dispatches the skill. Seed a fixture worker, call the route, assert the task text includes {{spec_path}} and the boss type was dispatched.
  • src/webhook-handlers.test.ts (if webhook-triggered option is chosen): assert the type:spec-breakdown label on an issue fires a breakdown dispatch.
  • Skill-level behaviour (parse / create-issues) is not unit-testable server-side — lives in the skill file itself; the operator verifies on a real spec.

Docs

  • CLAUDE.md "Roles" table: add breakdown flow or note that boss owns the skill.
  • CLAUDE.md "API" table: new POST /breakdown endpoint, or note the label-triggered path.
  • README — optional "Running a breakdown" section with one example (curl -X POST /breakdown -d '{"repo": "charles/foo", "spec_path": "specs/multi-tenant.md"}').

Out of scope

  • Cross-repo breakdown (explicitly excluded per #47).
  • Editing the breakdown skill through the UI — stays a markdown file in the repo.
  • Re-parsing spec updates — a breakdown is a one-shot operation; if the spec changes, the operator re-runs and the dedupe guard handles overlap.
  • Auto-classification beyond label matching — the labels the skill applies are what A3 routes on. No diff classifier.
  • LLM-driven label invention — the skill can only use labels that already exist (or that the operator has pre-approved in a config); it must not call create_label autonomously. This keeps the area:* taxonomy operator-controlled.

Resolves open question from #47

The tracking issue says A7 is a "stretch story for milestone close." Shipping this ticket closes #47's dependency graph and completes milestone 16.

References

  • Tracking: #47 (milestone 16: Agent pool + customization).
  • Existing skills to follow: skills/implement.md, skills/breakdown.md (if it exists — this story creates it fresh if not), skills/design-breakdown.md.
  • Global operator conventions: ~/.claude/CLAUDE.md "Issue authoring conventions" + "Label & milestone scheme".
  • Label API gotcha: operator memory forgejo_mcp_label_ids.mdadd_issue_labels needs numeric IDs, not names.

Dependencies

  • Blocked by: nothing (A1-A6 all merged).
  • Blocks: closing milestone 16.
  • Branch off: main.
## User story As the **operator**, I want a `breakdown` skill the orchestrator can dispatch against a `specs/*.md` file so that large spec documents get automatically decomposed into a set of correctly-labeled user-story issues — the way the global CLAUDE.md breakdown conventions prescribe — without me writing every ticket by hand. ## Context Closes the A7 story of milestone **#16 Agent pool + customization** (the last open story — tracking issue **#47**). Today, I (claude-desktop) manually write each user-story issue when we decompose a feature. The user wants to move this workload to the boss/dev agents: feed a `specs/<name>.md` to a `breakdown` skill, get a batch of tickets back with: - Full user-story bodies (`As a <role>, I want <capability>, so that <outcome>`) - Acceptance criteria grouped by sub-section - Out-of-scope list - References + dependencies block - Correct `area:*` + `type:user-story` labels - Optional milestone assignment - Suggested implementation order at the tail The resulting labels drive label-aware dispatch (A3) — a `reviewer-security` instance picks up issues tagged `area:security`, etc. ## Acceptance criteria ### Skill file - [ ] New `skills/breakdown.md`, following the same vocabulary + structure as the existing `implement.md`. - [ ] Input variables (interpolated by dispatch): `{{repo}}`, `{{spec_path}}`, `{{milestone}}` (optional). - [ ] Skill instructs the agent to: 1. Read `{{spec_path}}` from the repo's `specs/` directory (fail loudly if missing). 2. Parse the spec into discrete user-stories, following the conventions in the operator's global CLAUDE.md (`As a <role>… / Acceptance / Out of scope / References / Dependencies`). 3. Reconcile labels with `list_repo_labels`; file new `area:*` labels only if the operator has pre-approved them in a config (see below). 4. Create issues via `mcp__forgejo__create_issue` in parallel where safe (the operator is fine with non-sequential issue numbers — see CLAUDE.md). 5. Apply labels via `add_issue_labels` (by numeric ID — the forgejo-mcp gotcha in memory). 6. If a milestone is specified, attach it to each issue via `update_issue`. 7. Post a summary comment on a tracking issue if one exists (`{{tracking_issue}}` optional var): lists the created numbers + their titles, with the suggested implementation order. ### Dispatch path - [ ] New HTTP surface: `POST /breakdown` — payload `{ repo, spec_path, milestone?, tracking_issue? }`. Looks up the boss pool, dispatches the breakdown skill, returns `{ task_id }`. - [ ] Alternatively (operator's choice — document both in the PR body): webhook-triggered on an issue labeled `type:spec-breakdown` pointing at a `specs/*.md` path in the body. Simpler to wire; the first story in the resulting breakdown can be the operator's review of the batch. ### Guardrails - [ ] Never create duplicate issues — before creating, search the repo for existing issues whose title matches the proposed story's title (case-insensitive); if one exists, skip with a log entry. - [ ] Cap the number of stories per dispatch at a sane number (e.g. 15) — if the spec would decompose into more, emit the first 15 + a "next batch" summary comment. - [ ] No cross-repo — `repo` must match the orchestrator's own configured repo (out-of-scope per #47). - [ ] Dry-run flag (`{{dry_run}}` var): if true, the skill lists the proposed issues as a comment instead of creating them. ### Tests - [ ] `src/breakdown.test.ts` — unit coverage of the webhook / HTTP route that dispatches the skill. Seed a fixture worker, call the route, assert the task text includes `{{spec_path}}` and the boss type was dispatched. - [ ] `src/webhook-handlers.test.ts` (if webhook-triggered option is chosen): assert the `type:spec-breakdown` label on an issue fires a breakdown dispatch. - [ ] Skill-level behaviour (parse / create-issues) is not unit-testable server-side — lives in the skill file itself; the operator verifies on a real spec. ### Docs - [ ] CLAUDE.md "Roles" table: add `breakdown` flow or note that boss owns the skill. - [ ] CLAUDE.md "API" table: new `POST /breakdown` endpoint, or note the label-triggered path. - [ ] README — optional "Running a breakdown" section with one example (`curl -X POST /breakdown -d '{"repo": "charles/foo", "spec_path": "specs/multi-tenant.md"}'`). ## Out of scope - **Cross-repo breakdown** (explicitly excluded per #47). - **Editing the breakdown skill through the UI** — stays a markdown file in the repo. - **Re-parsing spec updates** — a breakdown is a one-shot operation; if the spec changes, the operator re-runs and the dedupe guard handles overlap. - **Auto-classification beyond label matching** — the labels the skill applies are what A3 routes on. No diff classifier. - **LLM-driven label invention** — the skill can only use labels that already exist (or that the operator has pre-approved in a config); it must not call `create_label` autonomously. This keeps the `area:*` taxonomy operator-controlled. ## Resolves open question from #47 The tracking issue says A7 is a "stretch story for milestone close." Shipping this ticket closes #47's dependency graph and completes milestone 16. ## References - Tracking: **#47** (milestone 16: Agent pool + customization). - Existing skills to follow: `skills/implement.md`, `skills/breakdown.md` (if it exists — this story creates it fresh if not), `skills/design-breakdown.md`. - Global operator conventions: `~/.claude/CLAUDE.md` "Issue authoring conventions" + "Label & milestone scheme". - Label API gotcha: operator memory `forgejo_mcp_label_ids.md` — `add_issue_labels` needs numeric IDs, not names. ## Dependencies - **Blocked by:** nothing (A1-A6 all merged). - **Blocks:** closing milestone 16. - **Branch off:** `main`.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#142
No description provided.