slice · diff

git:20260730.9807306 to git:20261106.ce8ab68

97 added, 101 removed. Audit A to A.

---
name: slice
- description: Turn a feature into well-defined, independently shippable slices — whether it's an epic that needs breaking apart or a single story that needs sharpening into a job story
- argument-hint: "[feature description]"
- disable-model-invocation: true
+ description: Cut a feature or idea down to one full-stack slice.
+ argument-hint: "[feature or idea to slice]"
---
- ## Phase 1: Understand the Work
+ # Full-stack slice SPEC
- If no feature is specified, open with:
+ A full-stack slice cuts vertically through every layer a feature needs: storage, logic, interface, integration. It ships on its own, and a user gets something they couldn't get before. The opposite is a horizontal slice ("add the schema", "build the API", "design the UI"), which ships nothing anyone can use and hides the integration pain until the end.
- **"What are you building? Describe the feature or capability — big or small."**
+ Full stack means whatever this project's fullest stack is. For a web app, storage through to screen. For a CLI, argument parsing through to printed output. Let the repo tell you its layers instead of assuming.
- Wait for their answer before proceeding.
+ The job is finding the version that costs a fraction of the work and is still worth shipping. The SPEC goes to a session that has none of this conversation, so it has to stand alone.
- Once the feature is known, ask three things — conversationally, not as a form:
+ ## Workflow
- **"Before we slice this, I need to understand it. Three things:**
+ Arguments start with `--auto`? Nobody will answer. Read [Autonomous mode](#autonomous-mode) first; it replaces the interview and both gates below.
- **Who is this for — specifically? Not 'users', but which person, in which moment, with which need.**
+ 1. Capture the raw idea in the user's words.
+ 2. Recon the codebase with subagents. Wait for them; the interview depends on what they find.
+ 3. Run the interview to cut scope.
+ 4. Fill in the SPEC template and paste the whole thing in a message for review. This is the skill's only approval gate.
+ 5. Write the approved draft to `docs/specs/<slug>.md` and tell the user the path.
- **What does done look like? When this ships, what can that person do that they can't do today?**
+ **The gate is the SPEC text, and it is the only gate.** Never end a turn with a prose recap of the slice and "confirm and I'll write the SPEC" — that asks the user to approve something they haven't read, which is the whole problem. If you're about to send that message, send the draft instead. And before writing the file, check one thing: the exact text you're about to write appeared in an earlier message and the user said yes to it. If it didn't, you're in step 4, not step 5.
- **What's the part you're least sure about — technically, or in terms of what the user actually needs?"**
+ ### 1. Capture the raw idea
- Wait for their answers. Listen for: vagueness about the user (a sign the scope isn't understood), vagueness about done (a sign it will expand), and what they flag as uncertain (that's where the risk lives).
+ The feature, if the user passed one: `$ARGUMENTS`
- If their answers are vague, ask one follow-up before moving on. Do not proceed to slicing on work you don't understand.
+ If that's empty, ask what they're building. Don't tidy up the answer. The messy version carries the motivation you need for the job story.
- ### Ground it in the codebase — when there is one
+ ### 2. Recon the codebase, before any questions
- Slices invented in the abstract ignore reality. In an existing app, the right cut depends on what's already there: half of it may exist already, the layers it touches may already have the abstractions it needs, and the edge cases worth putting in acceptance criteria are the ones this domain actually has, not the ones you can imagine.
+ Finish this before you ask anything. An interview run blind produces cuts that sound reasonable and turn out wrong: you propose building something the app already has, or you cut something load-bearing because you didn't know what depended on it. In a mature codebase the best cut is usually "that already exists, reuse it", and questioning the user won't surface it. They usually don't know either.
- Skip this step entirely when it doesn't apply:
+ Check how much codebase there is first (`git log --oneline | wc -l`, a source file count). A near-empty repo has nothing to find, so say that and go straight to the interview.
- - **The conversation already carries a codebase map.** If you arrived here from `/feature-dev`, its Phase 2 has already done this work — use what it found and move on. Never explore the same ground twice.
- - **There's nothing to explore.** Greenfield work, a brand-new app, or a feature that touches no existing behavior. Same for a product-shaped conversation where no repo is in play.
+ Otherwise tell the user you're reading the codebase first. Then launch subagents in parallel (`Explore`, or `general-purpose`), one per angle:
- Otherwise, match the effort to the feature. For a small change in familiar territory, a few targeted reads inline are enough. For anything spanning layers or touching code you don't know, launch 2–3 general-purpose subagents in parallel (via the `Agent` tool) — give each the brief in `references/slice-explorer.md` plus a different angle to cover:
+ - **Closest prior art.** The existing feature most like this one, traced end to end. These are the files worth copying.
+ - **Territory.** Every layer this would touch, in whatever form the project has them. What's already there, what's missing.
+ - **Conventions.** How the codebase handles its inputs, its trust boundaries if it has any, and its tests.
- - Find out whether this already exists, in whole or in part — the feature itself, an earlier attempt, or adjacent behavior that covers some of it.
- - Map the layers and models this would touch, and what abstractions are already available to reuse.
- - Find the closest comparable feature and report how it's tested — including the specific edge cases and error states those tests cover.
+ Ask for exact file paths rather than prose, because you need that specificity to argue for cuts the user can verify. Have each name up to 10 files worth reading, fewer if fewer are worth it, then read those files yourself.
- Ask each subagent to return the files most worth reading. When they return, read those files yourself before opening Phase 2.
+ Keep the paths as you go. The SPEC carries a short list of them under `## Where to look`, because a path is cheap to check and expensive to find again. Only files you actually read qualify: a path a subagent mentioned and you never opened is a guess with a citation on it.
- **What you do with this matters more than finding it.** These facts are here to sharpen your questions, not to answer them. You now know things the developer may not, and the temptation is to hand it over as a plan — don't. Keep asking; let the grounding make the questions specific. "There's already a `Subscription#cancel` that soft-deletes — does your slice extend that or replace it?" is the same Socratic move as before, just aimed somewhere real. Do not present findings as a report, do not propose the slices yourself, and do not slide into designing the implementation. The developer still does the seeing.
+ Then give the user 3 to 5 lines on what you found: what already exists, the closest pattern, what's missing. If recon misread the codebase, this is where they catch it, and that's far cheaper than finding out once the SPEC is written.
- ---
+ No repo, or no subagents available? Do a timeboxed grep and skim yourself, or say plainly that you're cutting scope without knowing what already exists, which is the weaker version of this.
- ## Phase 2: Shape the Slices — Socratically
+ ### 3. The interview
- Based on the size and complexity of the feature, take one of two paths. Do not announce which path you're taking — just follow the one that fits.
+ If the idea already arrives slice-sized, say so and go straight to step 4. The rounds below are for ideas that need cutting.
- ### Path A: The feature is already small
+ Rounds of 2 to 4 questions. One at a time is a slog; twelve at once is a survey.
- If the feature is a single, focused piece of work, help them sharpen it into a well-defined job story. Read `examples/job-stories.md` for the job story format. Guide them with:
+ **Lead with a cut.** "Should we include search?" makes the user do the work, and they'll say yes. Instead: _"I'm cutting search. With a dozen records the user can scan the list. Push back if that's wrong."_ A proposed cut is easy to accept and easy to reject, so it moves fast, and whatever they defend tells you what actually matters. Use `AskUserQuestion` when the choices are genuinely enumerable, plain questions otherwise.
- - "What's the specific situation the user is in when they need this? Not just 'using the app' — what moment triggers the need?"
- - "What do they want to do in that moment — and why does it matter to them?"
- - "How would you know this is done? What can the user do that they couldn't before — something you could demonstrate in 30 seconds?"
+ **Defend the cuts you propose.** If they ask why, answer it rather than restating the cut. A cut you can't answer for wasn't grounded in the recon, so withdraw it.
- Push on scope:
+ **Spend the recon.** You did the reading so the cuts could be specific, so use it. _"I'm not building an exporter. The reports page already renders CSV at `<the file you found>`, and this can go through the same path"_ is a cut the user can verify. Name the file. Vague cuts get argued about; grounded ones get accepted in one line.
- - "Is this actually one thing, or are you sneaking two things in? Could any part of this ship on its own?"
- - "Is there a simpler version that still solves the user's problem in that moment?"
+ **One test for everything.** For each behavior still standing: cut it, and does the slice still deliver the job story's outcome? If yes, cut it. Nothing earns an acceptance criterion until it has survived that question out loud. Guardrails are exempt.
- Push on acceptance criteria:
+ **Know when you're at the floor.** Two rounds with no new cuts means you're there: removing one more thing would break the demo or leave the user with nothing new. Past that you're negotiating trivia, and the remaining scope is the user's to defend rather than yours to keep whittling. Say which cut you considered and rejected, and why. They can overrule you.
- - "How would you verify this actually works? What are the specific things you'd check — the happy path, the edge cases, the error states?"
- - "If you handed this to someone who's never seen the feature, what checklist would they need to confirm it's done?"
+ There is no checkpoint at the end of the interview. The moment you're at the floor, go on to step 4 in the same turn and draft the SPEC.
- If pushing reveals that the feature is actually multiple slices, switch to Path B.
+ **Guardrails.** Four things survive however thin the slice gets: anything that risks data loss or corruption, authorization boundaries that would expose other people's data, whatever makes the slice demo-able, and tests for the acceptance criteria. Each becomes an acceptance criterion even though it would pass the cut test, which is why they're listed separately. Deferring one is a decision rather than a cut, so say it plainly and record it under `## Owed`. It isn't gone, it's owed.
- ### Path B: The feature is large
+ **If it won't cut, change the axis.** A feature that resists slicing is usually being cut in the wrong direction. Cut by workflow step, by user, or by input, not by layer and not by a "phase one" that ships nothing. The tell is a slice nobody can exercise end to end without you narrating it for them. Change the axis instead of thinning it further. And if the user says the axis is wrong, that outranks every cut on the table: start the rounds over on their axis rather than defending the cuts you've already made. The recon still holds unless the new axis points somewhere it didn't reach. Second axis change, draft on the axis you have.
- Guide them to find the slices themselves, one question at a time.
+ ### 4. Show the SPEC before saving it
- Start here:
+ Read `assets/spec-template.md` now, before you write anything else. Reading it at save time instead is how this step turns into a freehand summary.
- **"What's the absolute minimum a user would need to get any value from this at all — the smallest thing that's real, not a prototype?"**
+ Fill it in, then paste the filled-in file into the message. Not a description of it, not the job story and a sentence about the slice: the file, every section, acceptance criteria included, worded the way it will be worded on disk. The wording of a criterion _is_ the scope boundary, so the text under review has to be the real text. If your message has no acceptance criteria in it, you skipped this step.
- This is the walking skeleton (thoughtbot / XP). It's almost always smaller than they think. Read `examples/full-stack-slices.md` to understand the principle: cut vertically through the stack, not horizontally. Push on it:
+ The message looks like this, and nothing is on disk when you send it:
- - "Could a user actually do something with that, or is it just plumbing?"
- - "Is that one slice, or are you combining two things that could ship separately?"
- - "If you shipped only that, what feedback could you get from a real user?"
+ ````
+ Here's the SPEC I'd save to `docs/specs/{slug}.md`. Nothing written yet.
- Once the first slice is clear, work outward:
+ ```markdown
+ {the filled-in template, in full}
+ ```
- - "What's the next most important thing — not the next most obvious thing to build, but the next most valuable to the user?"
- - "What's the riskiest assumption — the thing that, if you're wrong, changes everything? Should that be a slice?"
- - "Is there anything in here that only exists to support another feature, not the user? That's probably not a slice."
- - "Which slices depend on each other, and which are actually independent?"
+ **What I cut:**
+ - {cut} — {they pushed back / passed without comment}
+ - ...
- As each slice takes shape, push on acceptance criteria:
+ Say the word and I'll save it.
+ ````
- - "How would you verify this slice works? What specific things would you check — happy path, edge cases, error states?"
- - "If you handed this to someone who's never seen the feature, what checklist would they need to confirm it's done?"
+ The template is thin on purpose: title, one-sentence summary, job story, acceptance criteria, plus `## Where to look` and `## Owed`, each only if it has something to carry. This is a contract rather than a design doc. Don't write a design, a file plan, or an ordering — that's the implementing session's to decide, and it'll have read the code more recently than you.
- Keep pushing until they've named the full set. Validate each slice against two tests — ask them:
+ Two things do carry over. Decisions, because they go missing rather than stale: "go through the existing export path rather than building a new one" belongs in the summary sentence if the user approved it. And the paths from step 2, because a path is cheap to check and expensive to find again.
- 1. "Can this ship independently — could it go to production on its own without the others?"
- 2. "Can a user or stakeholder see the value — is this end-to-end, or is it a layer?"
+ **`## Where to look` is a reading list, not a plan.** At most six paths, fewer if fewer earn it: the ones you'd open first if you were implementing this yourself. Each gets one line on why it matters to _this_ slice — "the CSV rendering this can go through", not "the reports controller". A path with no reason is noise the next session has to open before it can judge it, which costs more than leaving it out. A path already named in the summary sentence or a criterion doesn't repeat here.
- If a slice fails either test, it's either too big or it's not a slice.
+ Spend one of the six on the test nearest this slice, and name the command that runs it. Reading the local test idiom is the one piece of exploration the implementing session is _required_ to do before its first test, so it's the line that saves real work. Stamp the section with `git rev-parse --short HEAD`: the paths survive a moving repo better than the reasons beside them do, and the stamp is what lets the next session tell how much to trust each one.
- ---
+ **The acceptance criteria are the scope boundary.** There's no in/out list because there doesn't need to be one: if a behavior isn't in a criterion, it isn't in the slice. That only holds if the criteria are tight, so write them as behavior someone can observe by using the thing. Given a starting state, when the user does something, then something is observably true. "A blank title is rejected by the validation layer" names an implementation the next session should get to choose; "when I submit with the title empty, then I see the form again with an error on the title field" says the same thing and decides nothing. Outside a UI the same rule holds: "when I run `report --format=csv` with no matching records, then it prints the header row and exits 0". Where recon found something specific enough to change the work, put it in the criterion itself.
- ## Phase 3: Deliverable
+ One criterion per observable behavior, usually three to six. One means you spec'd a fragment; ten means you didn't cut.
- ### For a single slice
+ Replace every `{placeholder}`. Nothing in braces survives into the finished file, and a section with nothing to carry gets deleted rather than padded.
- Produce a job story. Read `examples/job-stories.md` for the format:
+ Mark which cuts they pushed back on and which passed without comment, because a silent round isn't agreement. The SPEC won't carry the cut list, so this message is the only place the user sees what's out while they can still object. Make it a real list rather than a summary.
- ---
+ Then stop. Don't write the file in the same turn as the playback, whatever their last message implied. Scope pushback sends you back to step 3. Wording pushback is cheaper: fix the draft and show it again in full, because a diff of a file they haven't seen on disk is harder to read than the file.
- **[Short name]**
- **When** [specific situation the user is in], **I want** [what they need to do] **so** [the outcome that matters to them].
- **Ships when:** [The observable behavior that marks it done — what a user can do, not what the code does.]
- **Acceptance criteria:**
+ ### 5. Write the file
- - [ ] [Specific, verifiable condition — the happy path]
- - [ ] [Edge case or boundary condition]
- - [ ] [Error state or failure handling, if applicable]
- **Risk / learning:** [What this slice tests or de-risks, or "Low risk" if straightforward.]
+ Write to `docs/specs/<slug>.md` at the repo root (`git rev-parse --show-toplevel`), with a short kebab-case slug (`invoice-csv-export`, not `export-invoices-as-csv-file-v1`). Create the directory if it doesn't exist. If the file already exists, read it: same feature, ask whether to replace it or revise it in place; different feature, pick a different slug. Never auto-suffix, because `/multi-lens-review` finds SPECs by slug and can't tell two near-identical ones apart. Then tell the user the path.
- ---
+ Write the draft they approved, unchanged. Anything you improve between approval and write is unreviewed, and the point of step 4 was that the file matches what they signed off on. If you spot a problem, show the corrected draft and get the nod again.
- Close with:
+ If you can't point to the message where you showed them this text, don't write the file. Go do step 4.
- **"Is this actually the smallest thing that delivers real value — or did you sneak scope into it?"**
+ ## Autonomous mode
- ### For multiple slices
+ Only when the arguments start with `--auto`. The rest of the arguments are the idea, often a GitHub issue body. Nobody is there to answer: your final reply gets posted as a comment, a human may edit it there, and the next step picks it up from the comment. Without `--auto`, ignore this section.
- Guide the sequencing:
+ What changes:
- **"Now order them. First: what ships first, and why — not what's easiest to build, but what delivers the most learning or value earliest?"**
+ - **Recon as in step 2.** Skip the 3 to 5 line summary; nobody is there to catch a misread.
+ - **No interview.** Make the cuts yourself, by the same rules: the cut test, the guardrails, changing the axis. Everything you'd have proposed is now decided.
+ - **Draft, then have it reviewed.** Fill in the template, then launch one fresh subagent with the draft, this skill's path, and the paths you read. It never saw your reasoning, so it can't be talked into it. Ask it to check: the template's shape kept word for word (`When` / `I want to` / `So I can`, `Given` / `when` / `then`), since the next step parses it; one job story, criteria a user could observe, cuts grounded in files that exist, guardrails kept, no horizontal slice. Tell it to report only problems that change the scope or make a criterion uncheckable, and to skip wording and style. A reviewer asked for problems always finds some.
+ - **Revise once.** Fix what holds up, drop what doesn't. No second review.
+ - **Guess, and say so.** Anything only a human could answer, like who receives an email or which plan a limit applies to, gets your best guess, recorded under `## Assumptions`. A guess the reader can see costs one edit; a guess buried in a criterion ships.
+ - **No file.** Don't write `docs/specs/`. On a CI runner it's thrown away unless pushed, and the comment is the handoff.
- Ask:
+ The final reply is the comment, so it carries nothing else:
- - "Which slice would tell you the most about whether this is heading in the right direction?"
- - "Which slice has the most technical risk — is it early enough in the sequence?"
- - "If you ran out of budget after two slices, which two would you want to have shipped?"
+ ```
+ <!-- spec -->
+ {the filled-in template, in full}
+ <!-- /spec -->
- When sequencing is agreed, produce the deliverable. Read `example.md` for a complete example of the expected format and quality. Format each slice as a job story:
+ **What I cut:**
+ - {cut} — {why, with the file that grounds it}
- ---
+ **What the review changed:**
+ - {finding} — {fixed / rejected, and why}
- **Slice [N]: [Short name]**
- **When** [specific situation the user is in], **I want** [what they need to do] **so** [the outcome that matters to them].
- **Ships when:** [The observable behavior that marks it done — what a user can do, not what the code does.]
- **Acceptance criteria:**
+ _Written by {model name} ({model ID}) with /slice --auto. No human has edited this yet._
+ ```
- - [ ] [Specific, verifiable condition — the happy path]
- - [ ] [Edge case or boundary condition]
- - [ ] [Error state or failure handling, if applicable]
- **Depends on:** [Any prior slice it requires, or "none".]
- **Risk / learning:** [What this slice tests or de-risks.]
+ No code block around the SPEC: GitHub would show it as raw text. Write the two marker lines exactly as shown, each on its own line. GitHub hides them, so the SPEC renders, and the next step finds the SPEC by them.
- ---
+ The last line says which model wrote the comment, so a reader can tell AI text from a human's. Take the name and exact ID from your system prompt, like `Claude Opus 5.5 (claude-opus-5-5)`. Don't know it? Write `Claude` alone; never guess a model. Keep it below `<!-- /spec -->`, so it never lands in the SPEC.
- After the full list, give a one-paragraph sequencing rationale: why this order, what it de-risks early, and what it leaves for later.
+ ## Job story craft
- Close with:
+ The shape is in the template. There's no persona in a job story. "As a hiring manager" tells you nothing about when the need arises; the situation does that work.
- **"Look at your first slice. Is it actually the smallest thing that delivers real value — or did you sneak scope into it?"**
+ - **Situation** is a concrete moment with a trigger. "When I'm closing out the month and my accountant asks for our invoice history", not "When I am a finance user."
+ - **Motivation** is the problem rather than your solution. "I want our invoices out of the app in one file", not "I want to click an Export button." If the UI shows up here, you've written the implementation into the story.
+ - **Outcome** is why it's worth anything. It should imply what gets worse if you don't build it.
- Wait for their answer. Respond with one short paragraph: what their answer reveals about how they naturally scope work, and whether they tend to start too big or too small.
+ One job story per slice. If yours needs an "and", you have two slices. Spec the first and tell the user what the second one is.
- ## Tone
+ ## Notes
- Collaborative but rigorous. Slicing is a thinking tool, not a planning ceremony. Push back on slices that are too big, too vague, or not actually end-to-end. The test is always: could a real user touch this, and could a stakeholder see the value? If not, it's not a slice yet.
+ - Resist appending sections. A design note or a roadmap is defensible on its own, and together they turn the contract back into the design doc this avoids. If something must survive, it belongs in an acceptance criterion, in `## Owed`, or in conversation. Never in `## Where to look`, which is paths and one line each, not a place to park a decision.
+ - If the feature is genuinely large, you're still speccing exactly one slice. Tell the user what the remaining slices look like, in order, but keep them out of the file.