SKILL.md
Vertical Slice Builder
A slice is one user-visible capability with its own routes, server functions, schema, RLS, and acceptance criteria. Ship it whole, verified, and pinned. Never half.
The loop
Run in order. Never skip a step.
1. Normalize the slice spec
Restate the user's input as:
- User story: "As <role>, I can <action> so that <outcome>."
- Routes touched: public vs authenticated.
- Server functions: name, method, auth model, input schema.
- Schema delta: tables, columns, policies, paired per supabase-schema-discipline.
- Acceptance criteria: 3 to 6 bullets, each independently testable.
- Out of scope: explicit non-goals.
Any field unclear: ask before planning. A vague spec builds the wrong slice fast.
2. Emit the plan prompt
Produce one prompt the user can approve:
SLICE: <title>
STORY: <user story>
ROUTES: <list>
SERVER FNS: <list with auth model>
SCHEMA: <migration summary; policies in the same migration>
ACCEPTANCE:
- [ ] <criterion>
NON-GOALS: <list>
GATES: RLS on every table, money-path HALT-GO if applicable, idempotency on side effectsDo not start building until the plan is approved.
3. Build
- One tracked work item per acceptance criterion.
- Migration ships structure, GRANTs, RLS, and policies in one file (supabase-schema-discipline).
- User-scoped server functions require auth middleware; admin clients only inside handler bodies.
- Public routes never call protected server functions from loaders.
4. Verify
Run every check in references/verification-checklist.md. All must pass. Any failure: fix and re-verify. Do not pin.
5. Pin the version
Only after all acceptance criteria pass: mark work items done with implementation notes, publish or tag the version, and summarize shipped routes, server functions, schema delta, and verification results.
Hard stops
- Diff touches checkout, payout, trade, escrow, ledger, balance, wallet, order, or invoice surfaces: run money-path-halt-go before step 3.
- Any schema change: apply supabase-schema-discipline.
- Any new table or server function: run rls-security-gate at step 4.
Good vs bad
Good slice: "As a member, I can bookmark a listing so I can find it later." One route change, one server function, one bookmarks table with policies, four testable criteria.
Bad slice: "Bookmarks plus the notifications system, they're related." Two capabilities lumped into one item means neither gets verified independently and the pin waits on both. Split it. One capability, one slice.
Verification
Do this: execute references/verification-checklist.md top to bottom and test each acceptance criterion by exercising the running app. Expect every checklist item and every criterion to pass with observed behavior, not inference from code. If anything fails, fix it and re-run the full checklist before pinning. "It compiled" is not verification.
Completion checklist
- [ ] Spec normalized with all six fields filled
- [ ] Plan approved before any build step
- [ ] Migration ships structure, GRANTs, RLS, and policies together
- [ ] Applicable hard stops invoked (money, schema, RLS gates)
- [ ] references/verification-checklist.md fully green
- [ ] Version pinned and slice summary written
Any box unchecked: not done. Fix or say so.
Footguns
- Building during "plan drafting": half the slice exists before approval and the plan gets reverse-engineered to match. Plan first, build second.
- Acceptance criteria written as implementation tasks ("add bookmarks table") instead of user-observable behavior ("bookmarked listing appears on /saved after reload"). You can complete every task and still ship a broken slice.
- Pinning with one criterion "basically done": the pin is the contract that the slice is whole. One open criterion means no pin.
- Quick schema tweak mid-build without the paired policy: the leak window ships with the slice.