ticket
Skill4 starsChanged 19 days agoMITView on GitHub
The front door. Open or resume a ticket, load its context and prior art, write the plan (and the spec when the plan calls for one), and wait for your approval before anything is built. Start every ticket here.
23 other projects use a version of this.
Adopted by
Most recently taken up by
- infenia/yuktatheir own version, first seen Nov 8, 2026
- peterpme/skillstheir own version, first seen Nov 8, 2026
- Mrbaeksang/skillstheir own version, first seen Nov 8, 2026
- 0xfurai/peekapingtheir own version, first seen Nov 1, 2026
- codingpains/skillstheir own version, first seen Nov 1, 2026
- philippmossier/cofabriqtheir own version, first seen Nov 1, 2026
Used with
Projects with it also use orchestrate, retro and 5 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
varun29ankuSSkillorchestrate
This skill should be used when the user asks to 'orchestrate a task', 'break down work into parallel agents', 'coordinate subtasks', 'run agents in parallel', or mentions 'multi-agent'. Decomposes complex tasks into tracked subtasks, dispatches parallel subagents, and coordinates until completion.
Also in 4 projects that use this
AWSSkillretro
Conduct a retrospective on a coding session.
Also in 3 projects that use this
SentrySkillspec
Produce a verified spec — problem, desired outcome, and acceptance criteria — before building. Use when given a GitHub/Linear issue link, when starting from a fuzzy in-conversation idea, or asked to "figure out what to do" / "scope this" / "what should I build" — whenever the *what* isn't yet pinned down. Grills the ambiguities, checks the premise against the code, and produces acceptance criteria you sign off on — then hands to design-first.
Also in 3 projects that use this
MicrosoftSkillhandoff
Compact the current conversation into a handoff document for another agent to pick up.
Also in 5 projects that use this
GoogleSkillprototype
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.
Also in 3 projects that use this
Microsoft AzureSkillverify
End-to-end app testing pipeline for browser-based web apps on cloud browsers via Azure Playwright Workspaces: verify the live app, author tests for working flows, heal failing tests, then re-run with video and produce one consolidated report. Three phases (app verification, test authoring, test healing) plus a scoped final sanity run; each phase emits a sub-report. Use when asked to "verify my app", "make sure my app works and has good test coverage", "do a full QA pass", "add tests where I'm missing coverage", "fix failing tests and add new ones", "smoke test before deploy", "QA my deployment", or any combined verify-and-test ask. Requires Azure CLI (`az login`) and a Playwright Workspace resource ID — bootstraps configs on first invocation. Browser-based web apps with Playwright only — not for unit/API tests, native mobile/desktop, load/perf, or full accessibility audits.
Also in 3 projects that use this
Other versions23 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 23
- 0xfurai/peekaping★ 1.2ksame name
- kjnez/claude-code-django★ 177same name
- peterpme/skills★ 28same name
- ConnorGriffin/skills★ 21same name
- a-saven/agent-skills★ 2same name
- AaravChadha/acstack★ 2same name
- gingerminds/claude-skills★ 2same name
- codingpains/skills★ 1same name
- HoussemDjeghri/self-review★ 1same name
- ilamanov/skills★ 1same name
13 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
9 rules. 0 are common, 4 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 20 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 20
Read capabilities from this skill's kit_paths.py --json probe the first time a question comes up, and keep the result.
- Very specific: line 78
Read owner, never project.assignee_dir directly.
- Very specific: line 165
Write the assignee(s) fetch_ticket returned to a scratch file as {"assignees": [{"id": …, "login": …, "email": …, "name": …}]}, with every …
- Distinctive: line 187
Follow priming.md, in order:
- Distinctive: line 194
Keep the whole brief tight (≤ ~300 words) — slices, not the whole knowledge base.
- Distinctive: line 212
Every ticket gets a plan, every time — there is no "small change, build directly" branch.
- Very specific: line 253
Every block has real content: no … placeholder lines, no template hints, nothing empty.
- Very specific: line 288
Only after the human says go: do the artifacts touch the ticket.
- Distinctive: line 329
No SQL beyond the describe/sample reads priming and spec research already make, no analysis, no deliverables, no external posts — while …
“Common” is measured: kept by at least 6 in 10 of the 20 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
/ticket
One command owns the ticket lifecycle: it opens (or creates) the ticket, sets up the workspace,
loads exactly the context this ticket needs, surfaces the closest prior work, and then carries the
work forward in the same window — plan → build → check → ship. Every read-only planning step
happens HERE, in Phase 4: the plan, and the spec when the plan calls for one, behind a single
approval — so /build never starts on a ticket nobody scoped, and on that approval it starts here. Reads the merged config; everything tool-specific resolves
through the adapters, so it works with any configured tracker/warehouse/vcs.
How this skill asks the person something
<!-- ticketwright:ask-rule:begin -->The kit's one question rule, the same in every skill that asks:
- Read
capabilitiesfrom this skill'skit_paths.py --jsonprobe the first time a question comes up, and keep the result. capabilities.structured_questionsisyesandcapabilities.question_toolis notnone→ ask with that tool, withincapabilities.question_limits(when that saysunknown: one question per call, at most four options). Group up to the limit only questions that do not depend on each other's answers; ask a dependent question after the one it depends on.- Otherwise (
no/unknown, or the probe failed) → ask in chat as a short numbered list, one question at a time unless this skill says a set goes in one round, and wait for an explicit answer. - The question content is the same either way; only how it is shown changes. No skill names a
runtime's tool: the runtime's own adapter (
adapters/runtime/<name>.md) does. A question tool is not available inside a subagent, so the main session asks. - Never invent an option. Options come from what this run found or the fixed choices a step names. A recommended option goes first, marked recommended, with where it came from; the person still picks. Each option says what choosing it changes, and free text is always possible (the tool's own "Other", or "or tell me something else" in prose).
- Whatever the person needs to answer is already in chat before the question, so a picker never hides it.
- A reply the kit asks for word for word (
ship unreviewed, theyesbefore destructive SQL) stays typed: an unreviewed ship or an irreversible write is never one click. The external-send gate (go ahead) is asked like any other question once the full delivery plan is in chat: its first option is "Go ahead", which delivers exactly the printed plan, and with no question tool the person typesgo ahead.
<!-- ticketwright:ask-rule:end -->In this skill the questions are step 1's ambiguous person, step 2's local-only offer, step 3's
owner choice, step 6c's offer to assign the ticket to you, step 11's open questions (one round: they
go together), and step 12's approval. The first of them can come before step 8, so run step 8's
probe then and keep the result.
- The options come from the resolver's
candidates, the owner folders that hold the id, and the plan's own assumption with the alternatives it weighed. - More real options than the limit allows: show the first ones plus a "Show more" option that asks again with the rest.
- "Never pick one" still holds. A question lets the person choose; never answer it for them.
Mode: --recall (standalone prior-art lookup, no workspace setup)
/ticket --recall "<topic>" or --recall --object <NAME> — rank prior tickets and write a reuse
brief, nothing else. Follow priming.md § Recall. Useful mid-session ("have we built
this before?", "which tickets touched VW_X?").
Phase 0 — Resolve & preflight (halt-on-fail)
- Read the merged config first — it is what decides WHO —
bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" effective_config.py --json, never rawstack.yaml. It carriesproject.*,seams.tracker,seams.vcs— and it settles the owner mechanically, in one field, so no skill re-derives the rule. If the team config is missing, say so and offer/setup— don't scaffold blind. Branch onowner_source, never on apeople/listing of your own: a roster can live entirely in$XDG_CONFIG_HOME/ticketwright/people/and never appear in this repo, and only the resolver looks in both homes — "nopeople/*.yamlhere" is not the same question.resolved— proceed;owneris this person and owns everything below.unbound— HARD STOP here, before any ticket path is rendered. Say: "I can't tell who you are:people/<id>.yamlis a placeholder (or nopeople/entry matches this machine's identity). Run/setup --teammatefirst — it asks who you are, binds it, and sets up your machine." Do not fall back toproject.assignee_dir: with a roster present that key names a COLLEAGUE, and theirtickets/<owner>/folder is exactly where an unbound teammate's work silently lands. Never infer an owner from a name.assignee_dir_fallback— proceed withowner: there is no roster in either home, soproject.assignee_diris the documented last resort for repos that predate owner routing.none— stop: no roster and noassignee_dir. Offer/setup. Readowner, neverproject.assignee_dirdirectly.
- Then show who that is —
bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" whoami.py, and show its one-line "Working as …" display. This is the display-and-binding step; the routing decision was already made in step 0, and whoami never overrides it. Two statuses still change what you do next:ambiguous— ask which person it is, with whoami'scandidatesas the options (see "How this skill asks the person something"); never rank or pick, and step 0's hard stop stands until they answer.conflict— proceed as the machine-pinned person and surface the warning line verbatim. - Verify the tracker + vcs seams (run their
verifycommands). If one is unreachable, print that adapter'sauthnotes and ask whether to continue local-only (workspace + context still work; tracker fetch is skipped) or stop and fix the connection first — degrade, don't die. - Determine the ticket locator:
$ARGUMENTSgives eitherowner/id(exact) or a bareid— resolve a bare id against the resolved person'stickets/<owner>/first, then across the other owners' folders. If a bare id exists under two or more owners and none of them is the resolved person, hard-stop and ask which one, with theowner/idchoices as the options — never pick one. For--create, create the ticket first via the tracker adapter'screate_ticketverb (project.default_epicas parent if set), then use the new id; created work is owned by the step-0 person. Take the path the adapter's gotchas pick for this machine: where the tracker's CLI is optional and not installed here, the connector creates it, and the person is never asked to install a CLI to continue. Say which path ran in the one line that reports the new id.
Phase 1 — Resume, don't restart
- Render
project.ticket_path→ the ticket dir, filling{assignee}with the locator's owner (the step-0 resolved person for new or bare-id work — never the staticproject.assignee_dir, except through step 0'sassignee_dir_fallbacklast resort). If the dir exists: read itsREADME.md, listfinal_deliverables/, checkgit log --oneline -10+git status, and summarize what's done and what remains, re-fetch the ticket for new comments (and record the status it returns the way step 6b does, so the index follows the tracker, and make step 6c's offer from what it returned), then skip to Phase 3. A ticket shipped for review comes back here for revisions. When its README's Status line or its index row says it is in review (the Ticketwright-onlyIn review, or the tracker review status an earlier/shipmoved it to), say so in one line: "<id>was shipped for stakeholder feedback, so this picks it up for revisions. The next/shipcan move it to Done." Leave the status as it is; the next/shipsets it, in the README and the index together. The new feedback goes in the ticket'ssource_materials/like any other intake. Resuming another person's ticket (locator owner ≠ resolved person) is fine — say so out loud. Check for the plan: ifplan.mdexists in the ticket dir, read it and report where the work stands against its Approach and Deliverables. If it is missing and work remains, Phase 4 still runs before anything else — a resumed ticket is not exempt from scoping. If the deliverables already exist and a/reviewverdict is on file (the ticket is at review/ship stage), say the plan is absent and route onward.
Phase 2 — Workspace (new ticket)
- Branch via the vcs adapter, named
<id>, offseams.vcs.default_branch— or a worktree when--worktreeis passed (isolates this ticket from other in-flight work; recommended when you run several tickets in parallel). Branch names stay bare<id>— neverowner/id, because/is git's ref-namespace separator andalice/xwould permanently forbid a branch namedalice. If<id>is already taken (typically another owner's ticket), create<owner>-<id>instead and say so out loud. When the session already runs in a linked worktree (many agent apps start every session in one;bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" kit_paths.py --jsonreportsworktree.linked: true), that worktree already isolates the ticket: run thebranchverb in place, treat--worktreeas already satisfied rather than nesting a second worktree, and say so in one line. The session's own branch (the name the app gave it) is left as it is; the ticket gets its own<id>branch from the default branch. If the session branch carries commits the default branch lacks, say they stay on that branch and are not part of this ticket. - Scaffold
project.ticket_pathwithproject.ticket_subdirs(create the subdirs empty — no.gitkeepplaceholders; they fill with real files during build and git picks them up then); tracker adapterdownload_attachments→source_materials/(silent if none); whenproject.intakelistsemail/chat/meetings, that folder also carries what a human dropped in — meeting notes arrive asYYYY-MM-DD-<slug>-meeting.md, and priming enumerates them withscan_source_materials.py --intakerather than guessing at names; resolve the kit once withKIT="$(bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" --kit)", then render"$KIT"/templates/ticket-README.md.tmpl→ the ticket dir — only if that README doesn't already exist. Where the tracker is the ticket folder, step 3'screate_ticketalready wrote it, and re-rendering would replace a briefed ticket with empty template tokens. 6b. Record the tracker's status, then refresh the catalog so the new ticket shows up immediately with the status the tracker gave it. Take the statusfetch_ticketreturned (fetch the ticket now if it has not been; priming reuses that fetch) and record it as a tracker read:
That way the index never falls back toecho '{"statuses":[{"id":"<id>","owner":"<owner>","status":"<status exactly as fetch_ticket returned it>"}]}' \ | bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" ingest_index_records.py --tracker-status -Unknown, or to the README's Status line, while the tracker answers. When the tracker was skipped (step 2's local-only choice), record nothing and say in one line that the index shows the README's Status line until/refresh indexreads the tracker. Then render; the PostToolUse index hook only fires onWrite/Editand scaffolding happens via Bash:bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" build_ticket_index.py(writes this project'stickets/INDEX.md+OBJECTS.md, and the graph layer when it's on; the new row shows▱until/shipcurates it).
6c. Offer to take the ticket in the tracker: ask, never assign on your own. The tracker's
assignee is who the team sees working the ticket, so when fetch_ticket shows it unassigned or
on someone other than the step-0 person, offer to assign it to them. Skip this step, saying
nothing, when the tracker was skipped (step 2's local-only choice) or the tracker adapter's
assign_ticket section says unsupported. Otherwise:
- Write the assignee(s)
fetch_ticketreturned to a scratch file as{"assignees": [{"id": …, "login": …, "email": …, "name": …}]}, with every field the tracker gave and[]when nobody is assigned. When the person'stracker_handleis unset, also read the signed-in account the way thatassign_ticketsection says, as a real id. When the section says the handle's form must be looked up first, do that lookup. Then runbash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" assignee_check.py --assignee <that file> --id <id> --mode <the section's mode>(adding--signed-in <account id>or--handle-id <id>when you read one). It compares mechanically, so never decide "already theirs" by eye, and never from a display name. offer: false→ nothing to ask. A ticket already theirs needs no line; otherwise say itsnotein one line, so a person whose tracker account is unknown learns how to set it.offer: true→ say thenotefirst when there is one (it names whose account will be used), then ask itsquestionas one question with the options "Assign it to me" and "Leave it as it is". Neither is recommended: it changes what the whole team sees. The question names whoever the write takes off the ticket, so the answer is never a surprise.- Assign it to me → the adapter's
assign_ticketverb withassign_to, then one line naming who the tracker shows now. A refusal orunavailableis one line with the tracker's reason. Leave it → change nothing, and do not ask again in this run. Either way carry on: the offer never blocks scoping. This is the one tracker write scoping makes, and only on that answer.
Phase 3 — Prime context automatically (the part you never have to ask for)
- Follow priming.md, in order:
- Ticket slice — the ticket body + folder + related prior tickets;
- Recall — rank prior art (
tools/recall.py), read the top 2–4, note what to reuse; it also offers the tracker's older tickets when recall is weak (priming §2b); - Domain slice — glossary/rules for the ticket's topic (from
documentation/); - Warehouse slice — schemas/samples/lineage for the specific objects in play (skip cleanly
if no warehouse is configured).
Keep the whole brief tight (≤ ~300 words) — slices, not the whole knowledge base.
7b. Meeting references — the complete rule, stated here in full because it is load-bearing
even for a reader who skips the reference file. When
seams.meetingsis configured, enumerate the ticket's meeting references:bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" meeting_refs.py --ticket <ticket-dir> --json. Zero refs ⇒ do nothing — never fetch speculatively. An invalid ref (exit 4) is a NAMED error to surface, never silence;"reason": "refused-credential"means a URL or token was committed — ask for the bare<provider>:<id>instead. For each ref whose provider matches the configured tool (check via the config resolver,--seam meetings), call the adapter'sfetch_transcript, andfetch_action_itemshandling its typed result:ok→ use the items;empty→ report "no action items recorded" (the provider's answer is authoritative — no extraction fallback);no_native_export→ extract action items in-context from the transcript text. Curate in-context into the committedYYYY-MM-DD-<slug>-meeting.md(decisions + action items, honoring the word limits). Never write the raw transcript to disk — the only opt-in raw location issource_materials/private/, which stays out of git but flags every/shipscan and copy-guard prompt by design. priming.md §1 carries the expanded detail.
Phase 4 — Scope: every read-only planning step, then one approval
Every ticket gets a plan, every time — there is no "small change, build directly" branch. Report the context brief (including the reuse brief) first, then:
- Probe the runtime the same way
/reviewdoes:bash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" kit_paths.py --json— keep itskit_root(it resolves the templates below; no second launcher call is needed) and readcapabilities.plan_mode, branching on the value only, never on the runtime's name:native, and you can enter that mode from where you are → draft steps 9–11 inside the runtime's planning mode and leave it only at step 12, because leaving it IS the approval. Most such modes let nothing but their own plan file be written; that is an instruction to the model, not a sandbox (the adapter,adapters/runtime/<tool>.md, carries the mechanism note), so the rule below still binds inside it.- anything else (
none,unknown, a failed probe, or a native mode you cannot enter mid-skill) → the same steps in the current context, with the approval as an explicit reply. In plain terms: nothing is written to the ticket until step 12; no runtime mode is required. Read-only here is GUIDANCE the agent follows, not a gate the runtime enforces — say so if asked.
- Draft the plan — compose it, do not write it yet. Compose it as Markdown, one
## <Section>block per heading oftemplates/plan.md.tmplunderkit_rootfrom Goal to Risks, in its order, because step 12 renders the file from exactly these blocks. Next step is not a block: the template writes it from thespec:value. The template holds the shape only; what goes in each block is here:- Goal: the outcome and why it matters to the requester.
- Scope:
- **In:**and- **Explicitly out:**(what this ticket will not answer, so nobody assumes it did). - Builds on: each prior ticket from the reuse brief as
<owner>/<id>, why it matched (a shared object, named by its name, a shared tag, a cross-reference, or keyword overlap only), and what is reused. "None found" is a valid answer. When the repeat check in repeats.md ends in a suggestion, also "This is the Nth instance of<pattern>(after<owner>/<id>)". - Deliverables expected: numbered in review order; each names its grain and carries its record count in the filename.
- Approach: ordered steps, with build-and-check loops kept small (one object or change at a time).
- Validation strategy: how each step is verified, decided before any code; these are the
success criteria
/reviewchecks against (duplicate detection on the grain key and record-count reconciliation, source against output, unless the plan says why not). - Touched:
- **Objects/files:**and- **Tool slots:**(which tracker, warehouse, chat, docstore, meetings or vcs, and for what). - Questions for the requester: asked in step 11; after the answers, each question with its answer (they become README assumptions), or "None open".
- Risks: what could make the result wrong or late, and how the plan watches for it.
Every block has real content: no
…placeholder lines, no template hints, nothing empty. Header facts are not blocks: the ticket id, title, Confidence (1 to 10; below 7, a spec is required), owner,after_shipand thespec:value.after_shipis empty unless the repeat check ends in a suggestion; then it is that one Next step line ("- After /ship:/skillify <pattern>(a suggestion, not part of this plan)", or the existing skill to run), never a step of this plan. Thespec:value is exactly one ofnot required(the plan is the build's blueprint), the spec's path spelled from the repo root as<ticket-dir>/specs/<id>-<slug>.md, orafter-root-cause. Inputs: the priming brief + the reuse brief. A spec is required when the work creates or alters a persisted object others depend on (a warehouse object, a model, a published report), reconciles two or more sources, or confidence is below 7. Chooseafter-root-causefor an investigation-shaped ticket ("where is this error coming from", "why did this number drift"): you cannot blueprint a fix you have not root-caused, and a spec written from the ticket's own hypothesis specifies a fix to the wrong place, so the Approach scopes the investigation and/buildreturns here for the spec once the cause is found (its Phase 1 owns that condition). Scoping is still first; it is scoped to what can honestly be planned.
- When a spec is required, draft it now, in this phase — follow spec.md (it consumes
the Phase 3 brief and researches only the delta). Spec authoring is read-only by design, which is
why it belongs here and not in
/build. Nothing about planning is left for the build stage. - Reduce assumptions (policy
reduce_assumptions): gather the open questions from the plan and the spec and ask them now, in one round — scoping is where an answer is cheapest. Show the scoping package first, then ask each open question as its own question (see "How this skill asks the person something"): what the plan assumed is the first, recommended option, and the alternatives the plan weighed are the others. These questions do not depend on each other, so with a question tool ask up to the limit per call, in as many calls in a row as it takes. When an answer differs from what the plan assumed, revise the plan and say what changed before step 12. - Present the scoping package and WAIT for one explicit approval — by leaving planning mode on
a
nativeruntime, by a reply everywhere else. Everywhere else, ask the approval as one question once step 11's answers are in, never in the same call (an answer can change the plan being approved). Its options are "Approve and build", "Approve, don't build yet" and "Change the plan"; the approval is the person's decision, so none is marked recommended. End the package by saying what approval does, since on anativeruntime leaving the mode is the whole answer:<!-- ticketwright:user-facing:begin -->Approving starts the build right away. To save the plan without building yet, say "approve, don't build yet".
<!-- ticketwright:user-facing:end -->Only after the human says go do the artifacts touch the ticket. Write the approved## <Section>blocks, exactly as approved (with step 11's answers folded in), to a scratch file outside the repo, then render the plan from them withbash "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/bin/tw" render.sh "$kit_root/templates/plan.md.tmpl" ticket_id=… title=… confidence=… spec_required=… owner=… after_ship='…' --sections <scratch file> --strictinto a scratch output file, and move it to<ticket-dir>/plan.mdonly when the render exits 0. The six header tokens go on the command line (after_ship=''when there is no suggestion; single-quote a filled one, since it carries backticks); every section comes from the file, so multi-line Markdown never passes through shell quoting, and section text is inserted as written (a{{ }}inside it stays text).--strictmakes each of these an error that prints nothing: a missing section or token, a heading the template has no place for, an empty section, a leftover…placeholder line. On an error, fix the blocks and render again; never hand-edit the output to get past it. If aplan.mdalready exists (a resumed or re-scoped ticket), update it in place; never re-render over an approved plan — then write the spec (<ticket-dir>/specs/<id>-<slug>.md) when one was drafted, and commit them together through the vcs adapter'scommitverb —docs: <id> plan for <thing>, ordocs: <id> plan + spec for <thing>— whencommit_plan_before_implementis on; leave them uncommitted when it is off. Either way they are now on file, which is what/buildrequires. A rejected package writes nothing: revise and present again. - Continue, always with the qualified
<owner>/<id>locator (so the next step can never re-resolve a bare id to a different owner's ticket). What happens next depends on what was approved. Check for replan mode first, because a replan's approval is usually a plain "go" too:- Replan mode (a build called this phase:
/reviewfound a scope problem, the person chose a replan at the review cap, or anafter-root-causeinvestigation found the cause) → updateplan.mdand the spec in place, get the approval, name the build steps the change affects, and return control to the build that called it. In replan mode, never enter/build: the build that called you is still running, and a second one would re-resolve everything and never return there. - Approve and build (outside replan mode, the default; a plain "go" means this) → say
<!-- ticketwright:user-facing:begin -->Plan approved. Starting the build.
<!-- ticketwright:user-facing:end -->and follow/build <owner>/<id>'s instructions in full, in this same window. "Follow" means what it means when/buildruns/review: there is no mechanical skill-invocation tool, and the emitted runtimes carry this body verbatim./builddecides on its own probe whether the work is done by subagents that see only the plan and spec, or here; it ends by running/review, and asks before/ship <owner>/<id>on APPROVE. - Approve, don't build yet → write the artifacts and stop, naming
/build <owner>/<id>as the command to run later.
- Replan mode (a build called this phase:
Stops here
No SQL beyond the describe/sample reads priming and spec research already make, no analysis, no
deliverables, no external posts — while scoping. The one tracker write is step 6c's assignee, and
only when the person chose "Assign it to me". In Phase 4 the plan and the spec are the only files
written, and only after approval. The build that follows an approval is governed by /build, not by
this rule. If the request is ambiguous, state your interpretation and ask before scaffolding heavy
structure (reduce_assumptions).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

