Agent Skills: scoped-planning

Per-stage scope-check overlay across the planning lifecycle. Wraps brainstorming, grill-plan, and writing-plans as black boxes and applies post-hoc scope guardrails at each stage's natural checkpoint against a scope map built from a GitHub issue-label universe. Use when the user says "/scoped-planning" or asks to scope a planning stage to specific tickets. Classifies every overscoped artifact point as IN SCOPE, OWNED BY ANOTHER TICKET, or GENUINE GAP, and proposes gap tickets. Requires a non-empty ticket universe; use create-scoped-tickets to seed one first.

UncategorizedID: kyzooghost/audit-code-health-skill/scoped-planning

Install this agent skill to your local

pnpm dlx add-skill https://github.com/kyzooghost/skills/tree/HEAD/skills/scoped-planning

Skill Files

Browse the full folder contents for scoped-planning.

Download Skill

Loading file tree…

skills/scoped-planning/SKILL.md

Skill Metadata

Name
scoped-planning
Description
Per-stage scope-check overlay across the planning lifecycle. Wraps brainstorming, grill-plan, and writing-plans as black boxes and applies post-hoc scope guardrails at each stage's natural checkpoint against a scope map built from a GitHub issue-label universe. Use when the user says "/scoped-planning" or asks to scope a planning stage to specific tickets. Classifies every overscoped artifact point as IN SCOPE, OWNED BY ANOTHER TICKET, or GENUINE GAP, and proposes gap tickets. Requires a non-empty ticket universe; use create-scoped-tickets to seed one first.

scoped-planning

A per-stage scope-check overlay across the planning lifecycle (/brainstorming -> /grill-plan -> /writing-plans). Each stage is invoked separately as scoped-planning /<wrapped-skill>, wrapping that stage's base skill as a black box. The wrapped skill runs to its natural checkpoint (brainstorming's user-review gate, grill-plan's handoff, writing-plans' execution-handoff); scope-check guardrails are then applied post-hoc, before the artifact is handed off. The deliverable is the wrapped skill's normal output (spec / grilled plan / task plan), kept scope-clean - not a separate verdict report.

All scope-routing logic - scope inventory, IN/OWNED/GAP classification, gap rule, gap-ticket template - is defined here. The only external reference is to create-scoped-tickets, which is used to seed the ticket universe when it is empty; scope-routing itself is self-contained.

Inputs

  • --tickets <N,M,...> - one or more target ticket numbers in the label universe that this planning effort implements (e.g. 4343,4380). Comma-separated. Required; omitting --tickets is always an error.
  • --label <label> - the issue label defining the ticket universe. Default: agent-work-ticket.
  • <wrapped-skill> - the base skill to wrap: one of /brainstorming, /grill-plan, /writing-plans. This token selects the overlay mode; no separate --mode flag.
  • The wrapped skill's own inputs (idea/spec, plan draft, etc.) are passed through unchanged.

--repo is required when --tickets are bare numbers; inferred from full ticket URLs when --tickets are given as full URLs.

If the label universe is empty (no tickets exist yet), use the create-scoped-tickets skill first to seed it from a spec, then invoke /scoped-planning with the seeded ticket numbers.

Built-in defaults (never restated by the user)

  • No-duplication check against every open ticket carrying --label in the repo.
  • Gap routing: every overscoped artifact point must map to a target ticket's owned scope, another open ticket's owned scope, or a proposed new ticket - never silently introduced as new scope.
  • No-new-scope guard: an artifact point that fits neither a target ticket nor an existing open ticket is a gap, not a license to expand the plan.
  • Post-hoc guardrails: the wrapped skill runs uninterrupted to its natural checkpoint; scope-checks apply after, before handoff.

Scope inventory

Run:

gh issue list -R <REPO> --label <LABEL> --state open --limit 200 --json number,title,body

For every ticket, extract what it OWNS ("The owner may" / "Scope of Work" or equivalent) and EXCLUDES ("The owner must not" / "Not In Scope" or equivalent). Produce a scope map: ticket number -> one-line ownership statement. Treat every ticket's ownership as exclusive. If work appears under another ticket's "owner may", it is out of scope here, full stop.

The authoritative set of recognized scope-section headings is: "The owner may", "The owner must not", "Not In Scope", "Scope of Work", "Definition of Done". If a ticket uses none of these, see Error handling.

IN/OWNED/GAP classification

Applied to every point of the wrapped skill's artifact (a spec section, an unresolved decision, a task line) at the stage's natural checkpoint:

  • IN SCOPE - the point touches the union of the target tickets' owned scope. Silent pass; emit the artifact as the base skill would.
  • OWNED BY ANOTHER TICKET - the point touches an area owned by a different open ticket in the scope map. Flag inline at the point of collision; name the owning ticket. Ask the user to narrow the artifact, reassign, or explicitly accept the cross-ticket work before handoff.
  • GENUINE GAP - the point touches an area no open ticket owns. Flag inline at the unowned work. Stop and ask: (i) create a gap ticket now (embedded template) or (ii) narrow the artifact to drop the gap.
  • Uncertain mapping - if you cannot map a point to a scope-map entry with confidence, default to GENUINE GAP and flag the uncertainty inline. The approval gate for gap tickets lets the user filter noise; do not interrupt the stage to ask per-point about the uncertainty.

Stubs, interfaces, TODOs, and hardcoded placeholders standing in for other tickets' unimplemented work are CORRECT by design - only verify the stub matches the agreed interface; do not flag them as overscope.

Gap rule

Draft each GENUINE GAP as a new ticket using the self-contained Agent Work Ticket template below. Present drafts under "Proposed new tickets". Request approval before filing each gap ticket via gh issue create -R <REPO> --label <LABEL> -t "<title>" -b "<body>". Do not file any gap ticket unless approved. Capture the real number/URL of each filed ticket and surface it back to the user.

Self-contained gap-ticket template

Title: <Area> - <Concrete outcome>. Do NOT include Status, Status Flow, Required Receipt, or Due Date in the body.

## Agent Work Ticket

### Request / Outcome

What needs to happen?

* <Concrete outcomes, not a vague theme. Concrete verbs + named components.>

### Background / Context

* <Why this exists: prior PRs, reviews, design constraints.>
* <Dependencies on other tickets: "Depends on #N (consumed via <interface/stub>); blocked by #M landing first.">

### Source Materials

* <Specs, PRs, commits, adjacent tickets. Prefer repo-relative paths.>

### Scope of Work

The owner may:

* <Allowed work. Every bullet traces to the Request / Outcome.>

The owner must not:

* <Out-of-scope work item> (ticket #N)
* <Out-of-scope work item> (ticket #M)
* <Change shared interfaces/contracts owned elsewhere>
* <Invent semantics not in the spec/source materials>
* Take any action requiring human approval without asking first

### Definition of Done

This ticket is complete when:

* <Verifiable checks only: tests, invariants, docs.>

### Stop Conditions

Stop and ask for input if:

* Ambiguity or missing information in the spec or interfaces
* A decision requires product/protocol judgment
* An action would affect another team or repo
* There is risk of overstepping the ticket scope

### Blocking Questions

* <Pre-seed only if already known; otherwise leave empty.>

The "owner must not" list cites adjacent ticket numbers from the scope map so every boundary is unambiguous.

Architecture

scoped-planning is a per-stage scope-check overlay with three entry points, each wrapping one lifecycle skill as a black box and bolting a scope guard onto its output:

| Mode | Wraps | Scope-checks | |------|-------|--------------| | scoped-planning /brainstorming | brainstorming | The emerging spec/design - flag scope creep vs the ticket universe. | | scoped-planning /grill-plan | grill-plan | The grilled plan - flag unresolved decisions that drift outside ticket scope. | | scoped-planning /writing-plans | writing-plans | The task plan - flag any task that touches work owned by another ticket or outside the universe. |

Each stage keeps its own human review gate intact. scoped-planning is invoked once per stage, not as a single end-to-end run.

Universe seeding is out of scope for this skill. If the label universe is empty, use create-scoped-tickets to seed it from a spec before invoking /scoped-planning.

Workflow

Each mode follows the same shape: build scope map -> run wrapped skill (black box) to its natural checkpoint -> apply scope-check guardrails post-hoc -> emit the artifact scope-cleaned.

Phase 0 - Scope inventory

Run once at the start of every invocation.

  1. List all open GitHub issues carrying --label via gh issue list --label <label> --state open --json number,title,body.
  2. For each issue, parse the recognized scope-section headings to extract owned scope ("The owner may" / "Scope of Work") and excluded scope ("The owner must not" / "Not In Scope").
  3. Build the scope map: {ticketNumber -> {owned, excluded}}.
  4. Fetch each target ticket in --tickets via gh issue view <N> -R <REPO> and confirm it is OPEN and carries --label. If any target ticket is closed, missing, or not in the label universe: Error - unknown target ticket. Stop.
  5. Mark the union of the target tickets' owned scope as the in-scope region.
  6. If the scope map is empty, stop and tell the user to seed the universe via create-scoped-tickets first.

Mode: /scoped-planning /brainstorming <idea>

  • Run brainstorming to its user-review gate. Then apply scope-check guardrails post-hoc, before the gate is passed:
    • IN SCOPE: design stays within the union of target tickets' owned scope. Silent pass; emit the spec as brainstorming would.
    • OWNED BY ANOTHER TICKET: flag inline at the design point that collides. Name the owning ticket. Ask the user to narrow the design, reassign, or explicitly accept the cross-ticket work before the artifact is handed off.
    • GENUINE GAP: flag inline at the unowned design point. Stop and ask: (i) create a gap ticket now (embedded template) or (ii) narrow the design to drop the gap.

Mode: /scoped-planning /grill-plan <plan>

  • Run grill-plan to its handoff. Then apply scope-check guardrails post-hoc to the unresolved-decision list and the plan's scope:
    • IN SCOPE: unresolved decisions stay within the union of target tickets' owned scope. Silent pass; emit the grilled plan as grill-plan would.
    • OWNED BY ANOTHER TICKET: flag inline which unresolved decisions would commit to another ticket's owned work. Ask the user to narrow or reassign.
    • GENUINE GAP: flag inline decisions that require unowned work. Stop and ask: create a gap ticket or narrow.

Mode: /scoped-planning /writing-plans <spec>

  • Run writing-plans to its execution-handoff. Then apply scope-check guardrails post-hoc to every task:
    • IN SCOPE: every task touches only the union of target tickets' owned scope. Silent pass; emit the plan as writing-plans would, through to its execution-handoff.
    • OWNED BY ANOTHER TICKET: flag inline at the offending tasks and which ticket owns the work they touch. Ask the user to drop/split/reassign the tasks.
    • GENUINE GAP: flag inline tasks needing unowned work. Stop and ask: create a gap ticket or drop the tasks.

Guardrail behavior (all modes)

The scope-check runs as a post-hoc guardrail at the wrapped skill's natural checkpoint, not alongside its dialogue and not as a separate report. The deliverable is the wrapped skill's normal artifact, scope-cleaned before handoff:

  • IN SCOPE - silent pass. No annotation; the artifact is emitted as the base skill would emit it.
  • OWNED BY ANOTHER TICKET - flag inline at the point of collision (a spec section, an unresolved decision, a task line). Name the owning ticket. Ask the user how to resolve before the artifact is handed off.
  • GENUINE GAP - flag inline at the unowned work. Stop and ask: create a gap ticket (embedded template) or narrow the artifact to drop the gap.

The final output is indistinguishable from the base skill's own output, except overscoped content has been flagged and resolved before the artifact is handed off.

Error handling and edge cases

Input errors

  • A target ticket is not in the --label universe -> stop, report which ticket(s), ask the user to confirm the label or ticket numbers.
  • REPO cannot be inferred and was not supplied -> stop, ask for REPO.
  • gh issue list returns zero open tickets carrying --label -> stop, tell the user the universe is empty and to seed it via create-scoped-tickets first. Scope routing has no boundary to enforce against an empty universe.
  • A target ticket has no recognizable scope section -> stop, ask the user for the scope statement. Never infer scope from a ticket title alone.
  • --tickets omitted -> stop, ask for --tickets. Target tickets are explicit; the skill does not infer them.
  • The wrapped skill token is not one of /brainstorming, /grill-plan, /writing-plans -> stop, report the unrecognized token, list the three valid modes.

Scope-map ambiguity

  • An artifact point touches an area that two tickets both appear to own -> flag the overlap inline with both ticket numbers; ask the user to resolve the boundary. Do not silently pick one.
  • The scope map cannot be built because tickets use non-standard headings -> stop, report which tickets are unparseable, ask the user to confirm the heading convention or supply scope statements.

Gap-ticket creation

  • User declines to create a gap ticket -> leave the gap flagged inline; do not file. Ask whether to narrow the artifact to drop the gap instead.
  • gh issue create fails -> report the error, stop, do not file. Tickets already filed in this run remain filed; report their numbers.
  • A drafted gap ticket duplicates an existing open ticket the scope map missed -> do not file; note the possible duplicate URL and ask the user to confirm.

No mutations beyond gap tickets

  • The skill never edits existing issues, changes labels, closes issues, or mutates the wrapped skill's artifact beyond inline scope flags. The only GitHub mutation is gh issue create for approved gap tickets.

Invocation

/scoped-planning /brainstorming <idea> --tickets 4343,4380 --label synchronous-composability-demo
/scoped-planning /grill-plan <plan> --tickets 4343,4380
/scoped-planning /writing-plans <spec> --tickets 4343,4380

If the label universe is empty, seed it via create-scoped-tickets first.

--repo is optional when tickets are given as full URLs (inferred); required when --tickets are bare numbers. --label defaults to agent-work-ticket. All scope-routing guarantees become built-in defaults, never restated by the user.

Verification

Since this is a Markdown skill wrapping vendor skills, verification is static checks plus scenario exercises against this SKILL.md.

Static checks

# All three wrapped skills are referenced
rg -n 'brainstorming|grill-plan|writing-plans' skills/scoped-planning/SKILL.md
# Expected: matches in mode descriptions and workflow

# Self-contained scope-routing concepts are all defined
rg -n 'Scope inventory|IN SCOPE|OWNED BY ANOTHER TICKET|GENUINE GAP|Gap rule|gap-ticket template|Guardrail behavior' skills/scoped-planning/SKILL.md
# Expected: matches in workflow and classification sections

# No lingering bootstrap references
rg -n -i 'bootstrap' skills/scoped-planning/SKILL.md
# Expected: no output

# No em-dash (per workspace rule)
rg -n $'\u2014' skills/scoped-planning/SKILL.md
# Expected: no output

Scenario exercises

  1. Empty universe - gh issue list returns zero. Output: stop, tell the user to seed the universe via create-scoped-tickets first.
  2. Brainstorm, all in scope - Design stays within #4343 and #4380's owned scope. Output: brainstorming's normal spec, no inline flags.
  3. Brainstorm, owned by another ticket - A spec section touches #4350's owned scope. Output: inline flag at the section, name #4350, ask user to narrow/reassign/accept.
  4. Brainstorm, genuine gap - A design point needs unowned work. Output: inline flag, stop and ask - create gap ticket or narrow.
  5. Grill, unresolved decision drifts out of scope - A grilled unresolved decision would commit to #4350's work. Output: inline flag at the decision, ask user to narrow/reassign.
  6. Writing-plans, task touches another ticket's scope - A task line implements #4350's scope. Output: inline flag at the task, ask user to drop/split/reassign.
  7. Writing-plans, genuine gap task - A task needs unowned work. Output: inline flag, stop and ask - create gap ticket or drop the task.
  8. Gap ticket created - User approves gap creation. Output: gh issue create, capture real number, surface it back.
  9. Gap ticket declined - User declines. Output: gap stays flagged inline, no filing; ask whether to narrow.
  10. Two target tickets both appear to own the same area - Overlap flagged inline with both numbers; ask user to resolve boundary.
  11. Unrecognized wrapped skill - User invokes /scoped-planning /foo. Output: stop, report unrecognized token, list three valid modes.
  12. Target ticket not in label universe - --tickets 4343 but #4343 lacks --label. Output: stop, report, ask to confirm.