| name | create-ticket |
| description | Author one loop-harness planning ticket in the format the implement-ticket loop consumes. Use when asked to plan a feature, scope a change, draft a ticket, or turn a described problem into a ticket the loop can run. Writes one ticket file to the configured plans directory. |
create-ticket
A loop-harness ticket is the CONTRACT the implement-ticket loop
executes against and the loop-reviewer judges against. This skill
defines that contract and produces one ticket file in it. Everything
downstream depends on a ticket shaped exactly this way: the lifecycle
gates, the tree-bound verdict, and the "every changed line traces to
the ticket" scope rule all read it as the interface. The format is
load-bearing.
Two authoring paths
- Scaffold inline (this skill). For a small, well-understood
change you already hold in context, write the ticket directly using
the contract below.
- Delegate the exploration (the
ticket-planner agent). For
anything needing repo-aware investigation (finding the code
surface, discovering the gates, resolving cited anchors), dispatch
the ticket-planner subagent. Repo exploration is a read-heavy
fan-out that belongs off the driver's context. The subagent returns
just the ticket path. Prefer this for real features.
Both paths produce the same contract, and this file is its source of
truth.
Where the ticket goes
Write one file to the plans directory the consumer configured
(.loop/config.json plans_dir, default ~/.claude/plans/), named
<slug>.md. The slug is the ticket's stable identity. The loop's
commit-subject convention is <slug>: summary and the reconciler
matches commits by it, so choose a slug that is unique, kebab-case,
and descriptive (add-rate-limit-headers, not fix or ticket-3).
The contract
Every ticket carries these sections. Omit a section only when it is
genuinely empty, and say so rather than dropping it silently.
- Title. One line naming what changes and why it is worth doing.
- Size / Effort. A rough magnitude (S/M/L) and one clause on what
drives it. Calibrates the reviewer's expectations.
- Triggered by. The request, bug, or decision that motivates
this, in one sentence.
- Context. What exists today, cited to the code (
path:line),
and what is wrong or missing. The reader should not need to
re-derive the current state.
- Non-goals / out of scope. What this ticket deliberately does
NOT do. This prevents scope creep and tells the reviewer that a
diff touching those areas is a violation.
- Requirements & restrictions. What the change must achieve and
the principles it must respect, EACH cited to where the repo
states it (a rule file, an existing pattern, a config). Discover
the repo's own conventions and cite them rather than assuming
generic ones.
- Code surface. The specific files and
path:line anchors the
change will touch, each with a one-line note on the change. The
"every changed line traces to the ticket" scope rule is checked
against this list, so keep it precise and complete. Needing a file
not listed here is the out-of-scope-fix-needed blocker.
- Tests & validation gates. The exact gates this change must pass,
discovered from the repo (its test command, its lint/type config,
its review rule), and the specific tests to add. A bug fix names a
reproducing test first.
- Risk assessment. Blast radius, reversibility, and the likeliest
failure modes. What breaks if this is wrong.
- Subtickets. The change decomposed into an ordered,
dependency-aware sequence a single loop iteration can each
execute.
- Open questions. Every decision this ticket cannot answer from
the request, the repo, or the consumer's decision record. Each
carries a recommendation. An unresolved design fork is a
blocked
state for the implementer (code unresolved-design-fork), never a
silent judgment call, so surfacing forks here with your
recommended resolution is what lets the operator settle them
before the loop runs.
Discipline
- Cite, do not assume. Every claim about the current code carries
a
path:line anchor you actually resolved. Re-open each anchor,
because stale line numbers mislead the implementer.
- Discover the gates from the repo, not from habit. The test
command, the lint/type config, the review rule, and the CI (or its
absence) are facts about this repo, and the ticket's "Tests &
validation gates" section must match them.
- Forks are the operator's, not yours. When the request, the repo,
and the decision record leave a choice open, it goes in Open
Questions with a recommendation. Picking silently is the failure the
loop's
unresolved-design-fork block exists to prevent.
- One ticket, one slug, one file. Split unrelated changes into
separate tickets the loop runs independently.