fdeops 3.16.0 → 3.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +82 -84
  2. package/adapters/AGENTS.md +1 -1
  3. package/adapters/GEMINI.md +1 -1
  4. package/adapters/LOCAL-LLM.md +5 -5
  5. package/adapters/README.md +2 -2
  6. package/adapters/copilot-instructions.md +1 -1
  7. package/adapters/cursor.fde.mdc +1 -1
  8. package/bin/check.js +42 -11
  9. package/bin/fde.js +157 -20
  10. package/bin/lib/render.js +2 -2
  11. package/bin/lib/trust.js +42 -5
  12. package/mcp/fdeops-ingest/package.json +1 -1
  13. package/package.json +1 -1
  14. package/plugin.json +1 -1
  15. package/skills/fde/SKILL.md +43 -42
  16. package/skills/fde/references/ai.md +2 -2
  17. package/skills/fde/references/audit.md +2 -2
  18. package/skills/fde/references/board-memo.md +1 -1
  19. package/skills/fde/references/business-case.md +1 -1
  20. package/skills/fde/references/close.md +1 -1
  21. package/skills/fde/references/connect.md +1 -1
  22. package/skills/fde/references/dashboard.md +2 -2
  23. package/skills/fde/references/debrief.md +1 -1
  24. package/skills/fde/references/demo-prep.md +1 -1
  25. package/skills/fde/references/discover.md +34 -15
  26. package/skills/fde/references/earn-trust.md +1 -1
  27. package/skills/fde/references/encode-pattern.md +3 -3
  28. package/skills/fde/references/eval-pack.md +2 -2
  29. package/skills/fde/references/hold-scope.md +1 -1
  30. package/skills/fde/references/ingest.md +1 -1
  31. package/skills/fde/references/land.md +1 -1
  32. package/skills/fde/references/pick-three.md +1 -1
  33. package/skills/fde/references/plan.md +10 -7
  34. package/skills/fde/references/poc.md +4 -2
  35. package/skills/fde/references/readout.md +1 -1
  36. package/skills/fde/references/red-team.md +1 -1
  37. package/skills/fde/references/rescue.md +3 -2
  38. package/skills/fde/references/review.md +1 -1
  39. package/skills/fde/references/rollback.md +1 -1
  40. package/skills/fde/references/runbook.md +1 -1
  41. package/skills/fde/references/score-use-cases.md +1 -1
  42. package/skills/fde/references/ship.md +124 -17
  43. package/skills/fde/references/switch-clients.md +1 -1
  44. package/skills/fde/references/test-assumptions.md +2 -2
  45. package/skills/fde/references/three-options.md +1 -1
  46. package/skills/fde/references/what-breaks.md +1 -1
  47. package/skills/fde/references/who-decides.md +1 -1
  48. package/templates/.fde/assumptions.md +1 -1
  49. package/templates/.fde/reality.md +6 -1
  50. package/templates/.fde/terrain.md +1 -1
  51. package/skills/fde/references/thin-slices.md +0 -100
@@ -1,10 +1,106 @@
1
- # ship - production without surprises
1
+ # ship - Deliver the increment
2
2
 
3
- **Enter when:** a slice is built, reviewed, and ready to deploy.
3
+ **Enter when:** you are writing or updating on their codebase, they need to see something real, or you are going live.
4
4
 
5
- **Read first:** `context.md`, `delivery.md`, `success.md`. Load `trust-profile.md` if the deploy touches regulated data or needs an approval chain. Load `evals.md` when the deploy touches AI/ML/LLM/RAG/agents.
5
+ **Read first:** `context.md`, `decisions.md`, `delivery.md`, `success.md`. Load `terrain.md` before you touch their code. Load `trust-profile.md` if the deploy touches regulated data or needs an approval chain. Load `evals.md` when the work touches AI/ML/LLM/RAG/agents.
6
6
 
7
- Opening question, calm tech lead voice: **has anyone actually *run* the rollback, or is it still a slide?** If only planned, that's today's work - say so plainly.
7
+ Do not ask them to pick a mode. Name where you are, then start at the matching section:
8
+
9
+ - Nothing on their staging yet → **one change they can see**
10
+ - On staging, the signer in `success.md` can reject it → **go-live**
11
+ - Prod is the question → **go-live**. Do not start a second change.
12
+
13
+ If going live, opening question: **has anyone actually *run* the rollback, or is it still a slide?** If only planned, that's today's work - say so plainly.
14
+
15
+ A same-day throwaway that kills an assumption is `poc`. This skill is the real change on a repo they will own, then production.
16
+
17
+ ## Field (name it once, then the same loop)
18
+
19
+ | | Brownfield | Greenfield |
20
+ |--|------------|------------|
21
+ | What you touch | Code they already run | A new path or empty tree they will own |
22
+ | First move | Characterise their tests, their runner, the workaround in `terrain.md` | First path a user can click. Not the whole product. |
23
+ | Proof | Their staging, a screen they already use | Their staging, or the environment they will operate. Local demo is not delivery. |
24
+ | Undo | Revert this change on its own | Same. If you cannot undo it, the design is coupled. |
25
+
26
+ Skip POC only when the killer assumption already lives in the repo (typical brownfield). If the bet is unproven, `poc` first.
27
+
28
+ **Done means:** the signer in `success.md` can reject this on staging they operate. A green check on your laptop is not delivery. Do not start the next change until this one is rejectable.
29
+
30
+ If `terrain.md` **Data estate** lists a **Blocker** this change depends on: stop. That is discover, not ship. Do not build a path they cannot feed.
31
+
32
+ ## Method - one change they can see
33
+
34
+ One change = one thing a user can do, with a test, that you can revert on its own. Not "all the APIs, then all the UI." Not a 2,000-line dump. A PR is how this often lands. It is not the job. The job is the change they can see.
35
+
36
+ ```
37
+ BAD (layers):
38
+ 1: all database models
39
+ 2: all API endpoints
40
+ 3: all UI components
41
+ 4: wire everything together (and pray)
42
+
43
+ GOOD (one user action each):
44
+ 1: User can create a payment (schema + endpoint + minimal UI) - testable
45
+ 2: User can view payment status (query + endpoint + UI) - testable
46
+ 3: Payment retry on failure (logic + endpoint + UI feedback) - testable
47
+ 4: Admin can void a payment (auth + logic + UI) - testable
48
+ ```
49
+
50
+ Each change is independently revertible.
51
+
52
+ **Before you start this change:**
53
+
54
+ - [ ] It is in `decisions.md` with acceptance criteria (happy + unhappy path)
55
+ - [ ] Blast radius declared: which files, which systems, which users affected
56
+ - [ ] Rollback named: revert this change, or something more specific
57
+ - [ ] No dependency on an unmerged change (if dependent, state it and land in order)
58
+ - [ ] `Kill if` is written - the observation that stops this change
59
+
60
+ **The loop.** In this order:
61
+
62
+ ```
63
+ Read existing code in the area (search before creating)
64
+ → Characterise what is already there (their tests, their runner; greenfield: the empty tree)
65
+ → Implement the smallest path that works
66
+ → Prove it on their staging (below)
67
+ → Cleanup pass (dedupe, simplify - behaviour unchanged)
68
+ → Self-review against acceptance criteria
69
+ → Commit with a message the client's team can read
70
+ → Update decisions.md + delivery.md
71
+ ```
72
+
73
+ **Prove it on their staging.** A green check on your laptop is not delivery.
74
+
75
+ - Run **their** test command, typecheck, or smallest proving path. Write the command and the result in `delivery.md`.
76
+ - If the signer in `success.md` cannot reject this on a screen they already use, it is not proven.
77
+ - Staging they operate beats a local demo. If you have no staging: `unknown - ask:` who owns an environment, then stop pretending it shipped.
78
+ - Model in the path: `eval-pack` until `evals.md` says SHIP. Do not skip because "it looked right in chat."
79
+
80
+ The proof is whatever this client already believes, plus one new receipt they can replay.
81
+
82
+ **Size.** Each change targets:
83
+
84
+ | Metric | Target | Why |
85
+ |--------|--------|-----|
86
+ | Lines changed | 100-300 | Reviewable in one sitting |
87
+ | Time to implement | 30-90 minutes | Testable before context decays |
88
+ | Files touched | 1-5 | Blast radius stays containable |
89
+ | Tests added | ≥1 per new behaviour | Proves this change; guards against regression |
90
+
91
+ Larger than 300 lines → split first. "It's all connected" means the design needs work, not a bigger dump.
92
+
93
+ **Show it.** Every 2-3 changes, something the customer can see: an endpoint they can hit, a UI they can click, a metric that moved, a risk that was retired. Technical progress invisible to stakeholders is trust decay. `delivery.md` gets updated after every visible change.
94
+
95
+ **The scope trap.** Mid-change discoveries ("this module also needs updating," "I should refactor this while I'm here"):
96
+
97
+ - If it's in `decisions.md`: do it as a separate change.
98
+ - If it's NOT in `decisions.md`: log it as a scope receipt (see `hold-scope.md`), don't touch it.
99
+ - Ugly code outside this change stays ugly. That is discipline, not laziness.
100
+
101
+ After each change: tests pass (state the command and result), acceptance criteria met, blast radius as declared, `Kill if` still false. After every 2-3: what did they see, and what's their signal? Then, when the signer can reject it on their staging, go-live below.
102
+
103
+ ---
8
104
 
9
105
  ## Deployment readiness gate (confirm the target before building the runway)
10
106
 
@@ -24,7 +120,7 @@ Before scoring readiness, confirm WHERE this is going. State it in 2-3 lines - b
24
120
  | **Compliance** | Region constraints? Data residency? Encryption requirements? CAB/change window? | |
25
121
  | **Infra-as-code** | Terraform/Pulumi/CDK/manual? State file location? | |
26
122
 
27
- **If anything is blank:** ask now. Discovering deployment constraints AFTER build is where timelines slip. If the client hasn't defined these yet, that's a conversation before you write the runbook - not after.
123
+ **If anything is blank:** ask now. Discovering deployment constraints after the change is where timelines slip. If the client hasn't defined these yet, that's a conversation before you write the runbook - not after.
28
124
 
29
125
  Write confirmed deployment context to `delivery.md` under a `## Deployment target` section.
30
126
 
@@ -46,9 +142,9 @@ Score each dimension green/amber/red. This is the gate, not a suggestion:
46
142
 
47
143
  | Dimension | Green | Amber | Red |
48
144
  |-----------|-------|-------|-----|
49
- | **Value bucket** | `success.md` names primary bucket (`cost-save` \| `risk-mitigation` \| `revenue-uplift`) and a baseline→target metric; this slice’s value-ledger row has **Bucket** + **Promised** | Bucket named; **Measured** still `pending` with a pulse date | No bucket, or Promised empty / ticket-theater only |
50
- | **Audit receipt** | Dated line in `delivery.md` (`## Ship receipts` or ledger Evidence) proving exceptions/operating path were walked - cite `terrain.md` / `reality.md` / `audit.md` | Path described, not verified this ship | No audit receipt for this slice |
51
- | **Eval receipt** | **n/a** (no AI on this slice) **or** `evals.md` Verdict SHIP with dated golden run + HITL gate named | Eval pack exists; known fails open with owner + date | AI in scope and no eval receipt |
145
+ | **Value bucket** | `success.md` names primary bucket (`cost-save` \| `risk-mitigation` \| `revenue-uplift`) and a baseline→target metric; this change's value-ledger row has **Bucket** + **Promised** | Bucket named; **Measured** still `pending` with a pulse date | No bucket, or Promised empty / ticket-theater only |
146
+ | **Audit receipt** | Dated line in `delivery.md` (`## Ship receipts` or ledger Evidence) proving exceptions/operating path were walked - cite `terrain.md` / `reality.md` / `audit.md` | Path described, not verified this ship | No audit receipt for this change |
147
+ | **Eval receipt** | **n/a** (no AI on this change) **or** `evals.md` Verdict SHIP with dated golden run + HITL gate named | Eval pack exists; known fails open with owner + date | AI in scope and no eval receipt |
52
148
  | **AI eval pack** | `.fde/evals.md` Verdict SHIP; goldens run this change; critical fails 0; HITL filled if policy requires | Pack exists; run stale vs change log | AI-touching deploy and pack missing / NO-SHIP / HITL required but empty |
53
149
 
54
150
  **Any RED = stop. Do not deploy. Fix the red dimension first.**
@@ -65,7 +161,7 @@ Write the readiness score (including value + receipts) to `delivery.md` before d
65
161
 
66
162
  ## Intent vs diff (before pre-blast)
67
163
 
68
- Ship the change you intended - not the drift that snuck in. Run this on the deploy branch against the **one-line intent** from `decisions.md` / `success.md` (the slice you said you were building).
164
+ Ship the change you intended - not the drift that snuck in. Run this on the deploy branch against the **one-line intent** from `decisions.md` / `success.md` (the change you said you were building).
69
165
 
70
166
  ```bash
71
167
  git diff <base>...HEAD --stat
@@ -78,7 +174,7 @@ Score every touched path (or logical hunk):
78
174
  |---------------|---------|------|
79
175
  | | **KEEP** | Directly required for the stated intent |
80
176
  | | **JUSTIFY** | Adjacent but load-bearing - one sentence why it must ship *now*, or split |
81
- | | **SPLIT** | Real work, wrong PR - park in `decisions.md` kill/Next; do not deploy with this slice |
177
+ | | **SPLIT** | Real work, wrong change - park in `decisions.md` kill/Next; do not deploy with this one |
82
178
  | | **DROP** | Noise (format-only, drive-by rename, unrelated tidy) - revert before ship |
83
179
 
84
180
  **Any SPLIT or DROP still in the tree = fix-first.** JUSTIFY without a written sentence = treat as SPLIT. Log a one-line receipt in `delivery.md`: `intent vs diff: KEEP n · JUSTIFY n · SPLIT n · DROP n - <intent>`.
@@ -164,12 +260,12 @@ Never skip a step. The sponsor always wants to skip from pilot to standard - tha
164
260
 
165
261
  ## Method - progressive adoption (built it, now people need to use it)
166
262
 
167
- Adoption isn't a handoff-stage problem - it starts during build. Software that launches to silence is software that gets decommissioned.
263
+ Adoption isn't a handoff-stage problem - it starts while you are still writing the change. Software that launches to silence is software that gets decommissioned.
168
264
 
169
- **During build:**
265
+ **During the change:**
170
266
  - **Feature flags from day one.** Every new capability behind a flag. Ship to 5% of users first. Watch behavior before opening to 100%.
171
267
  - **Feedback loops built in.** A thumbs-up/down, a "was this helpful?", a usage counter. Instrument adoption, don't assume it.
172
- - **Resistance signals.** Watch for: workaround creation (they built a spreadsheet instead of using the tool), drop-off after day 3 (onboarding fails), vocal detractors (one influential skeptic can kill adoption). Address these DURING build, not after launch.
268
+ - **Resistance signals.** Watch for: workaround creation (they built a spreadsheet instead of using the tool), drop-off after day 3 (onboarding fails), vocal detractors (one influential skeptic can kill adoption). Address these before launch, not after.
173
269
 
174
270
  **At launch:**
175
271
  - **Champion network.** Identify 2-3 power users per team who adopt early. Support them intensely - they become your multiplier.
@@ -180,24 +276,35 @@ Adoption isn't a handoff-stage problem - it starts during build. Software that l
180
276
 
181
277
  ## Artifact
182
278
 
183
- **`delivery.md`** - deployment record: what shipped, when, what it delivers in business terms, rollback procedure, pulse definition, **scale-readiness assessment, and adoption metrics**. Written for whoever inherits the system.
279
+ **`decisions.md`** - each change: what was implemented, what was tested, what was deferred, `Kill if`.
280
+
281
+ **`delivery.md`** - each visible change in business language; then the deployment record: what shipped, when, rollback procedure, pulse definition, **scale-readiness assessment, and adoption metrics**. Written for whoever inherits the system.
184
282
 
185
283
  ## Checkpoint
186
284
 
187
- Before 100%: canary clean, business metric verified, pulse written into `delivery.md`. Also green: value bucket named, audit receipt dated, eval receipt **n/a or pass**, **intent vs diff clean** (no unresolved SPLIT/DROP). Missing any of those → not green. For enterprise-scale: scale-readiness gate passed before broad rollout.
285
+ After each change: tests pass, acceptance criteria met, blast radius as declared, `Kill if` still false, proven on staging they operate.
286
+
287
+ Before 100% live: canary clean, business metric verified, pulse written into `delivery.md`. Also green: value bucket named, audit receipt dated, eval receipt **n/a or pass**, **intent vs diff clean** (no unresolved SPLIT/DROP). Missing any of those → not green. For enterprise-scale: scale-readiness gate passed before broad rollout.
188
288
 
189
289
  ## Worked example
190
290
 
191
- Acme, shipping the failure-routing slice into a payments environment on a Thursday.
291
+ Acme, brownfield. Plan Now has three changes, not "the payments rewrite."
192
292
 
193
- Readiness scoring catches two things the diff does not. The audit receipt is missing: the operating map says Marco's manual re-run is the fallback, and nobody has checked whether the new page fires *before* his morning run or after - if after, the alert changes nothing. That gets walked and cited before deploy. Second, the intent-vs-diff read shows the PR also touches the settlement retry that was deferred in build; it comes out.
293
+ Change 1 is *user sees retry status on a failed payment* - schema + endpoint + the existing ops screen, 180 lines, their `pytest -k payments` green, revert is this change. `Kill if:` the signer cannot reject it on the screen they already use. Ugly retry-queue code two files over stays ugly. `decisions.md` logs the change; `delivery.md` says ops can see a retry without opening the spreadsheet. Marco sees it on staging they operate. That is the proof. Local green was not.
294
+
295
+ Then Thursday go-live of the failure-routing change. Readiness scoring catches two things the diff does not. The audit receipt is missing: the operating map says Marco's manual re-run is the fallback, and nobody has checked whether the new page fires *before* his morning run or after - if after, the alert changes nothing. That gets walked and cited before deploy. Second, the intent-vs-diff read shows the PR also touches the settlement retry that was deferred; it comes out.
194
296
 
195
297
  Pre-blast challenge: "what does this break if it fires at 3am and nobody acks?" Answer: nothing breaks, but the rota is not yet agreed - so the deploy waits on a name, not on code. That is a one-day slip that prevents a fake green.
196
298
 
197
299
  After deploy: `delivery.md` ship receipt with the audit cite, the kill test evidence, and the rollback line. Eval receipt: n/a, no AI in this path.
198
300
 
301
+ Greenfield is the same loop with an empty tree: first path a user can click, on an environment they will operate, then this go-live. Not the whole product in one dump.
302
+
199
303
  ## Principles
200
304
 
305
+ - One user action per change. Layers are untestable until assembled.
306
+ - On their staging, and you can undo it. Local green is not delivery.
307
+ - The ugly code outside this change stays ugly. That's discipline, not laziness.
201
308
  - A deployment without a tested rollback is reckless.
202
309
  - Roll back on any canary anomaly; investigate safely.
203
310
  - Verify the business metric, not just the technical one.
@@ -1,4 +1,4 @@
1
- # switch-clients - juggling engagements without dropping any
1
+ # switch-clients - Switch engagements
2
2
 
3
3
  **Enter when:** the FDE is running 2+ engagements simultaneously, context-switching is causing mistakes or delays, a new customer is being onboarded while existing engagements are active, or the FDE says "I'm losing track."
4
4
 
@@ -1,4 +1,4 @@
1
- # test-assumptions - pressure-test the brief before building on it
1
+ # test-assumptions - Test assumptions
2
2
 
3
3
  **Enter when:** the brief feels too neat, the customer is very confident about the solution (not the problem), someone says "we just need…" about a complex system, or discover surfaced contradictions between what was said and what the codebase shows.
4
4
 
@@ -40,7 +40,7 @@ CONVENIENCE - if wrong, a task changes but the approach holds
40
40
  | "The team will adopt the new tool" | Ask three team members individually: "Show me how you'd use this" | 1h | 2 of 3 can describe a use case without prompting |
41
41
  | "The data is clean enough for ML" | Sample 200 records, count nulls/duplicates/format errors | 1h | <5% error rate on the fields the model needs |
42
42
 
43
- **4. Run the killer test first.** The assumption with the highest blast radius AND the cheapest validation gets tested immediately. This single principle saves more engagement time than any other: if the killer assumption is wrong, you've saved weeks; if it holds, you've bought confidence.
43
+ **4. Run the killer test first.** The assumption with the highest blast radius AND the cheapest validation gets tested immediately. This single principle saves more engagement time than any other: if the killer assumption is wrong, you've saved weeks; if it holds, you've bought confidence. Write the kill observation in `How we test` as the result that would **stop** the plan - plan copies that line onto each Now PR as `Kill if`.
44
44
 
45
45
  **5. Present findings as a fact base, not a challenge.**
46
46
 
@@ -1,4 +1,4 @@
1
- # three-options - three paths, not one recommendation
1
+ # three-options - Generate options
2
2
 
3
3
  **Enter when:** a significant technical or strategic decision needs to be made, the FDE is asked "what should we do?", the team is stuck between approaches, or a fork in the engagement requires the sponsor's input.
4
4
 
@@ -1,4 +1,4 @@
1
- # what-breaks - know what breaks before you touch it
1
+ # what-breaks - Assess impact
2
2
 
3
3
  **Enter when:** about to make a change on a system you don't fully understand, touching a high-churn module from `terrain.md`, modifying shared infrastructure (auth, database, messaging), or the FDE asks "what could go wrong?"
4
4
 
@@ -1,4 +1,4 @@
1
- # who-decides - reading the room before it reads you
1
+ # who-decides - Map decision rights
2
2
 
3
3
  **Enter when:** new stakeholders appear, signals shift mid-engagement, a meeting felt off but you can't say why, or it's been two weeks and the map hasn't been updated.
4
4
 
@@ -8,4 +8,4 @@
8
8
  **Blast radius:** `CRITICAL` · `LOAD-BEARING` · `CONVENIENCE`
9
9
  **Status:** `OPEN` · `TESTING` · `CONFIRMED` · `DISPROVED` · `PARKED`
10
10
 
11
- **Rule:** a CRITICAL assumption still OPEN blocks plan. DISPROVED → update `reality.md` / `success.md` and log the reset in `decisions.md` the same day.
11
+ **Rule:** a CRITICAL assumption still OPEN blocks plan. `How we test` is the kill observation (the result that stops the work) - plan copies it as `Kill if`. DISPROVED → update `reality.md` / `success.md` and log the reset in `decisions.md` the same day.
@@ -1,7 +1,12 @@
1
1
  # Reality (actual problem)
2
2
 
3
- <!-- Hypothesis until the discover phase confirms with evidence. -->
3
+ <!-- Hypothesis until the discover phase confirms with evidence. Dashboard reads Working theory / Evidence / Differs from brief how. -->
4
4
 
5
5
  **Working theory:**
6
6
  **Evidence:**
7
7
  **Differs from brief how:**
8
+
9
+ **Situation:**
10
+ **Complication:**
11
+ **Question:**
12
+ **Answer-space:**
@@ -9,7 +9,7 @@
9
9
  ## Operating map (exception-led)
10
10
 
11
11
  <!-- How work actually runs when the happy path fails. Fill in discover; leave blank until heard/seen.
12
- fde doctor requires ≥1 real exception row before plan/build/ship/close. -->
12
+ fde doctor requires ≥1 real exception row before plan/ship/outcome/close. -->
13
13
 
14
14
  | Exception / break | Who notices first | What they do today (workaround) | System of record then | Blast if wrong | Evidence |
15
15
  |-------------------|-------------------|---------------------------------|-----------------------|----------------|----------|
@@ -1,100 +0,0 @@
1
- # thin-slices - thin slices on someone else's codebase
2
-
3
- **Enter when:** the build task is larger than a single PR, multiple files or systems are involved, or the FDE needs to show visible progress to a stakeholder every 2-3 days.
4
-
5
- **Read first:** `decisions.md` (the plan), `terrain.md` (the danger zones), `context.md`. This skill works *inside* the build phase - it's the execution discipline that makes large features safe on codebases you don't own.
6
-
7
- The FDE who builds a 2,000-line feature in one PR gets it rejected. The FDE who ships five 200-line PRs - each reviewable, testable, and revertible - earns the team's trust. On someone else's codebase, small and visible beats clever and large.
8
-
9
- ## Method (you do this work)
10
-
11
- **1. Slice vertically, never horizontally.**
12
-
13
- ```
14
- BAD (horizontal):
15
- PR 1: Build all database models
16
- PR 2: Build all API endpoints
17
- PR 3: Build all UI components
18
- PR 4: Wire everything together (and pray)
19
-
20
- GOOD (vertical):
21
- PR 1: User can create a payment (schema + endpoint + minimal UI) - testable
22
- PR 2: User can view payment status (query + endpoint + UI) - testable
23
- PR 3: Payment retry on failure (logic + endpoint + UI feedback) - testable
24
- PR 4: Admin can void a payment (auth + logic + UI) - testable
25
- ```
26
-
27
- Each vertical slice delivers working functionality the customer can see. Each slice is independently revertible.
28
-
29
- **2. The slice checklist.** Before starting any slice:
30
-
31
- - [ ] Slice is in `decisions.md` with acceptance criteria (happy + unhappy path)
32
- - [ ] Blast radius declared: which files, which systems, which users affected
33
- - [ ] Rollback path identified: "revert this PR" or something more specific
34
- - [ ] No dependency on an unmerged slice (if dependent, state it and merge in order)
35
-
36
- **3. The implementation loop.** For each slice, in this order:
37
-
38
- ```
39
- Read existing code in the area (search before creating)
40
- → Characterise what is already there (their tests, their runner)
41
- → Implement the minimal working path
42
- → On-site proof (below)
43
- → Cleanup pass (dedupe, simplify - behaviour unchanged)
44
- → Self-review against acceptance criteria
45
- → Commit with a message the client's team can read
46
- → Update decisions.md + delivery.md
47
- ```
48
-
49
- **On-site proof.** A green check on your laptop is not delivery. Before the slice is done:
50
-
51
- - Run **their** test command, typecheck, or smallest proving path. Write the command and the result in `delivery.md`.
52
- - If the signer in `success.md` cannot reject this slice on a screen they already use, it is not proven.
53
- - Staging they operate beats a local demo. If you have no staging: `unknown - ask:` who owns an environment, then stop pretending it shipped.
54
- - Model in the path: `eval-pack` until `evals.md` says SHIP. Do not skip because "it looked right in chat."
55
-
56
- Do not prove it with a textbook ritual. The proof is whatever this client already believes, plus one new receipt they can replay.
57
-
58
- **4. Size discipline.** Each slice targets:
59
-
60
- | Metric | Target | Why |
61
- |--------|--------|-----|
62
- | Lines changed | 100-300 | Reviewable in one sitting |
63
- | Time to implement | 30-90 minutes | Testable before context decays |
64
- | Files touched | 1-5 | Blast radius stays containable |
65
- | Tests added | ≥1 per new behaviour | Proves the slice works; guards against regression |
66
-
67
- A slice larger than 300 lines → split before implementing. "It's all connected" means the design needs work, not the slice limit.
68
-
69
- **5. Stakeholder visibility rhythm.** Every 2-3 slices, something the customer can see:
70
-
71
- - A working endpoint they can hit
72
- - A UI change they can click
73
- - A metric that moved
74
- - A risk that was retired
75
-
76
- Technical progress invisible to stakeholders is trust decay. `delivery.md` gets updated after every visible slice.
77
-
78
- **6. The scope trap.** Mid-slice discoveries - "this module also needs updating," "I should refactor this while I'm here":
79
-
80
- - If it's in `decisions.md`: do it as a separate slice.
81
- - If it's NOT in `decisions.md`: log it as a scope receipt (see `hold-scope.md`), don't touch it.
82
- - The hardest discipline: leaving ugly code alone when it's not in your slice.
83
-
84
- ## Artifact
85
-
86
- **`decisions.md`** - each slice logged with: what was implemented, what was tested, what was deferred.
87
-
88
- **`delivery.md`** - each visible slice with business-language description of what it delivers.
89
-
90
- ## Checkpoint
91
-
92
- After each slice: tests pass (state the command and result), acceptance criteria met, blast radius as declared. After every 2-3 slices: stakeholder visibility confirmed - what did they see, and what's their signal?
93
-
94
- ## Principles
95
-
96
- - Vertical slices, always. Horizontal layers are untestable until assembled.
97
- - 100-300 lines per slice. Larger means split first.
98
- - Every slice is independently revertible. If it isn't, the design is coupled.
99
- - Visible progress every 2-3 slices. Technical progress alone is trust decay.
100
- - The ugly code outside your slice stays ugly. That's discipline, not laziness.