@stacksjs/defaults 0.72.102 → 0.73.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 (164) hide show
  1. package/ai/AGENTS.md +25 -4
  2. package/ai/README.md +26 -4
  3. package/ai/skills/stacks-actions/SKILL.md +1 -1
  4. package/ai/skills/stacks-ai/SKILL.md +1 -1
  5. package/ai/skills/stacks-alias/SKILL.md +1 -1
  6. package/ai/skills/stacks-analytics/SKILL.md +1 -1
  7. package/ai/skills/stacks-api/SKILL.md +1 -1
  8. package/ai/skills/stacks-arrays/SKILL.md +1 -1
  9. package/ai/skills/stacks-auto-imports/SKILL.md +1 -1
  10. package/ai/skills/stacks-browse/SKILL.md +1 -1
  11. package/ai/skills/stacks-browser/SKILL.md +1 -1
  12. package/ai/skills/stacks-buddy/SKILL.md +1 -1
  13. package/ai/skills/stacks-build/SKILL.md +79 -5
  14. package/ai/skills/stacks-cache/SKILL.md +1 -1
  15. package/ai/skills/stacks-calendar/SKILL.md +1 -1
  16. package/ai/skills/stacks-chat/SKILL.md +1 -1
  17. package/ai/skills/stacks-cli/SKILL.md +1 -1
  18. package/ai/skills/stacks-cloud/SKILL.md +1 -1
  19. package/ai/skills/stacks-cms/SKILL.md +1 -1
  20. package/ai/skills/stacks-codebase-design/DEEPENING.md +79 -0
  21. package/ai/skills/stacks-codebase-design/DESIGN-IT-TWICE.md +72 -0
  22. package/ai/skills/stacks-codebase-design/SKILL.md +180 -0
  23. package/ai/skills/stacks-collections/SKILL.md +1 -1
  24. package/ai/skills/stacks-commerce/SKILL.md +141 -35
  25. package/ai/skills/stacks-composables/SKILL.md +1 -1
  26. package/ai/skills/stacks-config/SKILL.md +1 -1
  27. package/ai/skills/stacks-configuration/SKILL.md +1 -1
  28. package/ai/skills/stacks-cron/SKILL.md +1 -1
  29. package/ai/skills/stacks-crosswind/SKILL.md +1 -1
  30. package/ai/skills/stacks-database/SKILL.md +1 -1
  31. package/ai/skills/stacks-datetime/SKILL.md +1 -1
  32. package/ai/skills/stacks-dependencies/SKILL.md +1 -1
  33. package/ai/skills/stacks-deploy/SKILL.md +1 -1
  34. package/ai/skills/stacks-desktop/SKILL.md +1 -1
  35. package/ai/skills/stacks-development/SKILL.md +1 -1
  36. package/ai/skills/stacks-dns/SKILL.md +1 -1
  37. package/ai/skills/stacks-docs/SKILL.md +1 -1
  38. package/ai/skills/stacks-domain-modeling/FORMATS.md +123 -0
  39. package/ai/skills/stacks-domain-modeling/SKILL.md +109 -0
  40. package/ai/skills/stacks-enums/SKILL.md +1 -1
  41. package/ai/skills/stacks-error-handling/SKILL.md +1 -1
  42. package/ai/skills/stacks-events/SKILL.md +1 -1
  43. package/ai/skills/stacks-faker/SKILL.md +1 -1
  44. package/ai/skills/stacks-flow/PHASE-BOUNDARIES.md +91 -0
  45. package/ai/skills/stacks-flow/SKILL.md +117 -0
  46. package/ai/skills/stacks-git/SKILL.md +37 -9
  47. package/ai/skills/stacks-grilling/SKILL.md +85 -0
  48. package/ai/skills/stacks-guard/SKILL.md +86 -11
  49. package/ai/skills/stacks-guard/scripts/block-destructive.sh +67 -0
  50. package/ai/skills/stacks-handoff/SKILL.md +70 -0
  51. package/ai/skills/stacks-health/SKILL.md +1 -1
  52. package/ai/skills/stacks-http/SKILL.md +1 -1
  53. package/ai/skills/stacks-i18n/SKILL.md +1 -1
  54. package/ai/skills/stacks-investigate/SKILL.md +234 -106
  55. package/ai/skills/stacks-investigate/scripts/hitl-loop.template.sh +47 -0
  56. package/ai/skills/stacks-jobs/SKILL.md +1 -1
  57. package/ai/skills/stacks-listeners/SKILL.md +1 -1
  58. package/ai/skills/stacks-logging/SKILL.md +1 -1
  59. package/ai/skills/stacks-mail/SKILL.md +1 -1
  60. package/ai/skills/stacks-middleware/SKILL.md +1 -1
  61. package/ai/skills/stacks-migrations/SKILL.md +1 -1
  62. package/ai/skills/stacks-models/SKILL.md +1 -1
  63. package/ai/skills/stacks-new-feature/SKILL.md +65 -5
  64. package/ai/skills/stacks-notifications/SKILL.md +1 -1
  65. package/ai/skills/stacks-objects/SKILL.md +1 -1
  66. package/ai/skills/stacks-office-hours/SKILL.md +16 -2
  67. package/ai/skills/stacks-orm/SKILL.md +1 -1
  68. package/ai/skills/stacks-path/SKILL.md +1 -1
  69. package/ai/skills/stacks-payments/SKILL.md +35 -1
  70. package/ai/skills/stacks-plan-review/SKILL.md +27 -6
  71. package/ai/skills/stacks-plugins/SKILL.md +1 -1
  72. package/ai/skills/stacks-prototype/LOGIC.md +103 -0
  73. package/ai/skills/stacks-prototype/SKILL.md +66 -0
  74. package/ai/skills/stacks-prototype/UI.md +112 -0
  75. package/ai/skills/stacks-push/SKILL.md +1 -1
  76. package/ai/skills/stacks-query-builder/SKILL.md +1 -1
  77. package/ai/skills/stacks-queue/SKILL.md +1 -1
  78. package/ai/skills/stacks-realtime/SKILL.md +1 -1
  79. package/ai/skills/stacks-registry/SKILL.md +1 -1
  80. package/ai/skills/stacks-repl/SKILL.md +1 -1
  81. package/ai/skills/stacks-retro/SKILL.md +121 -75
  82. package/ai/skills/stacks-review/SKILL.md +182 -74
  83. package/ai/skills/stacks-router/SKILL.md +1 -1
  84. package/ai/skills/stacks-routes/SKILL.md +1 -1
  85. package/ai/skills/stacks-scaffolding/SKILL.md +1 -1
  86. package/ai/skills/stacks-scheduler/SKILL.md +1 -1
  87. package/ai/skills/stacks-search-engine/SKILL.md +1 -1
  88. package/ai/skills/stacks-security/SKILL.md +1 -1
  89. package/ai/skills/stacks-security-audit/SKILL.md +1 -1
  90. package/ai/skills/stacks-server/SKILL.md +1 -1
  91. package/ai/skills/stacks-shell/SKILL.md +1 -1
  92. package/ai/skills/stacks-slug/SKILL.md +1 -1
  93. package/ai/skills/stacks-sms/SKILL.md +1 -1
  94. package/ai/skills/stacks-socials/SKILL.md +1 -1
  95. package/ai/skills/stacks-storage/SKILL.md +1 -1
  96. package/ai/skills/stacks-strings/SKILL.md +1 -1
  97. package/ai/skills/stacks-stx/SKILL.md +1 -1
  98. package/ai/skills/stacks-tdd/EXAMPLES.md +136 -0
  99. package/ai/skills/stacks-tdd/SKILL.md +125 -0
  100. package/ai/skills/stacks-testing/SKILL.md +13 -3
  101. package/ai/skills/stacks-tunnel/SKILL.md +1 -1
  102. package/ai/skills/stacks-types/SKILL.md +1 -1
  103. package/ai/skills/stacks-ui/SKILL.md +1 -1
  104. package/ai/skills/stacks-utils/SKILL.md +1 -1
  105. package/ai/skills/stacks-validation/SKILL.md +1 -1
  106. package/ai/skills/stacks-whois/SKILL.md +1 -1
  107. package/ai/skills/stacks-wizard/SKILL.md +127 -0
  108. package/ai/skills/stacks-wizard/scripts/template.sh +208 -0
  109. package/ai/skills/stacks-writing-for-agents/MECHANICS.md +125 -0
  110. package/ai/skills/stacks-writing-for-agents/SKILL.md +218 -0
  111. package/app/Actions/Auth/GenerateTwoFactorSecretAction.ts +12 -2
  112. package/app/Actions/Commerce/Shipping/{DriverDestroyAction.ts → CourierDestroyAction.ts} +6 -6
  113. package/app/Actions/Commerce/Shipping/{DriverIndexAction.ts → CourierIndexAction.ts} +3 -3
  114. package/app/Actions/Commerce/Shipping/CourierPingStoreAction.ts +61 -0
  115. package/app/Actions/Commerce/Shipping/{DriverShowAction.ts → CourierShowAction.ts} +5 -5
  116. package/app/Actions/Commerce/Shipping/{DriverStoreAction.ts → CourierStoreAction.ts} +4 -4
  117. package/app/Actions/Commerce/Shipping/{DriverUpdateAction.ts → CourierUpdateAction.ts} +6 -6
  118. package/app/Actions/Commerce/Shipping/DeliveryRouteStartAction.ts +38 -0
  119. package/app/Actions/Commerce/Shipping/DeliveryStopCompleteAction.ts +40 -0
  120. package/app/Actions/Commerce/Shipping/DeliveryStopFailAction.ts +44 -0
  121. package/app/Actions/Commerce/Shipping/DeliveryStopStartAction.ts +39 -0
  122. package/app/Actions/Commerce/Shipping/courier-session.ts +75 -0
  123. package/app/Actions/Commerce/commerce-action.test.ts +5 -5
  124. package/app/Actions/Dashboard/Commerce/CommerceDeliveryAction.ts +5 -5
  125. package/app/Actions/Dashboard/Commerce/CourierIndexAction.ts +24 -0
  126. package/app/Actions/Dashboard/Commerce/DeliveryRouteIndexAction.ts +7 -7
  127. package/app/Actions/Dashboard/Commerce/commerce-delivery.test.ts +11 -11
  128. package/app/Actions/Dashboard/Commerce/commerce-delivery.ts +29 -29
  129. package/app/Actions/Dashboard/Commerce/{driver-records.test.ts → courier-records.test.ts} +9 -9
  130. package/app/Actions/Dashboard/Commerce/{driver-records.ts → courier-records.ts} +14 -14
  131. package/app/Actions/Dashboard/Commerce/delivery-route-records.test.ts +13 -13
  132. package/app/Actions/Dashboard/Commerce/delivery-route-records.ts +25 -25
  133. package/app/Models/User.ts +1 -1
  134. package/app/Models/commerce/{Driver.ts → Courier.ts} +7 -7
  135. package/app/Models/commerce/{DriverPing.ts → CourierPing.ts} +7 -7
  136. package/app/Models/commerce/DeliveryRoute.ts +6 -6
  137. package/app/Models/commerce/DeliveryStop.ts +31 -8
  138. package/bootstrap.ts +7 -0
  139. package/functions/commerce/shippings/couriers.ts +19 -0
  140. package/ide/vscode/package.json +1 -1
  141. package/package.json +4 -3
  142. package/resources/components/Dashboard/Commerce/Delivery/{DriverDeleteDialog.stx → CourierDeleteDialog.stx} +5 -5
  143. package/resources/components/Dashboard/Commerce/Delivery/{DriverDialog.stx → CourierDialog.stx} +10 -10
  144. package/resources/components/Dashboard/Commerce/Delivery/{DriversDashboard.stx → CouriersDashboard.stx} +43 -43
  145. package/resources/components/Dashboard/Commerce/Delivery/{DriversTable.stx → CouriersTable.stx} +21 -21
  146. package/resources/components/Dashboard/Commerce/Delivery/DeliveryOverviewDashboard.stx +18 -18
  147. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDeleteDialog.stx +2 -2
  148. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRouteDialog.stx +22 -22
  149. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesDashboard.stx +24 -24
  150. package/resources/components/Dashboard/Commerce/Delivery/DeliveryRoutesTable.stx +8 -8
  151. package/resources/components/Dashboard/Commerce/Delivery/TabNavigation.stx +1 -1
  152. package/resources/functions/dashboard/data.ts +1 -1
  153. package/resources/functions/dashboard/sidebar.ts +2 -2
  154. package/routes/dashboard-api.ts +6 -6
  155. package/routes/dashboard.ts +7 -7
  156. package/routes/delivery.ts +24 -0
  157. package/types/defaults.ts +3 -3
  158. package/views/dashboard/.discovered-models.json +18 -18
  159. package/views/dashboard/AUDIT.md +1 -1
  160. package/views/dashboard/commerce/delivery/{drivers.stx → couriers.stx} +2 -2
  161. package/views/dashboard/composables/useChart.ts +16 -2
  162. package/views/dashboard/layouts/default.stx +1 -1
  163. package/app/Actions/Dashboard/Commerce/DriverIndexAction.ts +0 -24
  164. package/functions/commerce/shippings/drivers.ts +0 -19
@@ -1,119 +1,247 @@
1
1
  ---
2
2
  name: stacks-investigate
3
- description: Use when debugging issues in the Stacks project — four-phase root-cause debugging with hypothesis testing and escalation. Enforces "no fixes without root cause." Invoke with /stacks-investigate.
3
+ description: Use when debugging a Stacks issue - something broken, throwing, failing, flaky or slow. Builds a tight feedback loop that goes red on the bug before any hypothesis is allowed, then minimises, tests hypotheses, fixes and locks it down with a regression test. Enforces no fixes without root cause. Invoke with /stacks-investigate.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
7
7
  ---
8
8
 
9
- # /stacks-investigate — Root Cause Debugging
10
-
11
- You are a systematic debugger for the Stacks framework. Find the **root cause**, not just make symptoms go away. No fixes until the root cause is confirmed.
12
-
13
- ## Phase 1: Investigate
14
-
15
- Gather information. Do not form hypotheses yet.
16
-
17
- 1. **Understand the symptom**: What's happening vs. what should happen?
18
- 2. **Reproduce mentally**: Read code paths end-to-end. Trace data flow from input to failure point.
19
- 3. **Collect evidence**:
20
- - Read error messages, stack traces, and logs (`storage/logs/stacks.log`)
21
- - Check recent git history: `git log --oneline -20 -- [relevant files]`
22
- - Check for related test failures: `bun test [relevant test file]`
23
- - Check config files that affect the failing path (`config/*.ts`)
24
- 4. **Map blast radius**: What else touches this code? Use `grep` to find all callers.
25
-
26
- For Stacks-specific issues, also check:
27
- - ORM model definitions in `storage/framework/defaults/app/Models/`
28
- - Route definitions in `routes/`
29
- - Action handlers in `storage/framework/core/actions/src/`
30
- - Middleware in `storage/framework/defaults/app/Middleware/`
31
-
32
- ```
33
- ## Investigation Summary
34
- **Symptom**: [what's happening]
35
- **Expected**: [what should happen]
36
- **Affected code**: [file:line references]
37
- **Recent changes**: [relevant commits]
38
- **Blast radius**: [other code/features affected]
39
- ```
40
-
41
- ## Phase 2: Pattern Analysis
42
-
43
- 1. **When does it fail?** Always, or only under certain conditions? Environment-specific?
44
- 2. **Failure mode?** Crash / wrong result / hang / intermittent
45
- 3. **Where in the stack?**
46
- - Framework issue (check `storage/framework/core/`)
47
- - Application code issue (`app/`, `routes/`, `resources/`)
48
- - Dependency issue (check `bun.lock` for version changes)
49
- - Configuration issue (`config/*.ts`)
50
-
51
- ```
52
- ## Pattern Analysis
53
- **Failure type**: [crash / wrong result / hang / intermittent]
54
- **Consistency**: [always / conditional / intermittent]
55
- **Layer**: [framework / application / dependency / config]
56
- **Key observation**: [most important pattern]
57
- ```
58
-
59
- ## Phase 3: Hypothesis Testing
60
-
61
- Form up to 3 hypotheses, ranked by likelihood.
62
-
63
- ```
64
- ### Hypothesis 1 (most likely): [title]
65
- **Claim**: [specific root cause]
66
- **Prediction**: [observable if true]
67
- **Test**: [how to verify]
68
- **Result**: ✅ Confirmed / ❌ Refuted / ⚠️ Inconclusive
69
- ```
70
-
71
- ### Escalation Rule
72
-
73
- If all 3 hypotheses refuted:
74
- 1. **Stop and reassess.** Don't generate more hypotheses in a loop.
75
- 2. Present what you've ruled out.
76
- 3. Ask for additional context.
77
- 4. If still stuck after second round, recommend:
78
- - Add targeted logging with `log.debug()` from `@stacksjs/logging`
79
- - Write a minimal reproduction case
80
- - Run `buddy doctor` for system diagnostics
81
-
82
- **Never apply a fix just to "see if it helps."**
83
-
84
- ## Phase 4: Implementation
85
-
86
- Only enter when a hypothesis is confirmed.
87
-
88
- 1. **Explain the root cause** in plain language
89
- 2. **Show the minimal fix** — change as little as possible
90
- 3. **Verify**:
91
- - Run existing tests: `bun test`
92
- - Check blast radius from Phase 1
93
- - Run `bunx --bun pickier . --fix` for formatting
94
- 4. **Suggest a regression test**
95
-
96
- ```
97
- ## Root Cause
98
- [Clear explanation]
99
-
100
- ## Fix
101
- [Minimal code change with file:line references]
102
-
103
- ## Verification
104
- - [x] Existing tests pass (`bun test`)
105
- - [x] Blast radius checked
106
- - [ ] Regression test: [suggested test]
107
- ```
9
+ # /stacks-investigate - root cause debugging
10
+
11
+ A discipline for hard bugs. Find the **root cause**, not a way to make the
12
+ symptom go away. Skip a phase only when you can say why.
13
+
14
+ Credit: the feedback-loop-first structure is adapted from Matt Pocock's
15
+ `diagnosing-bugs` skill (MIT), <https://github.com/mattpocock/skills>.
16
+
17
+ ## Redact
18
+
19
+ This skill has you show commands, outputs and captured artifacts. **Redact every
20
+ secret first**, writing `<REDACTED>` in its place. Build loops against env vars
21
+ so the credential stays in the environment rather than in what you show. In a
22
+ Stacks project the usual offenders are `.env`, `.env.production`,
23
+ `config/services.ts`, `APP_KEY`, AWS keys and `HCLOUD_TOKEN`, plus captured HTTP
24
+ traffic carrying an `Authorization` header. Quote only the lines that carry the
25
+ signal.
26
+
27
+ If the redacted output is not enough to diagnose the bug, say so and ask the
28
+ user.
29
+
30
+ ## Phase 1: build a feedback loop
31
+
32
+ **This is the skill.** Everything else is mechanical. With a **tight** pass/fail
33
+ signal, one that goes **red** on *this* bug, you will find the cause: bisection,
34
+ hypothesis testing and instrumentation all just consume it. Without one, no
35
+ amount of staring at code will save you.
36
+
37
+ Spend disproportionate effort here. Be aggressive, be creative, refuse to give
38
+ up.
39
+
40
+ ### Ways to construct one, in roughly this order
41
+
42
+ 1. **Failing test** at whatever seam reaches the bug. `bun test <path>` is the
43
+ loop. See `stacks-tdd` for which seam.
44
+ 2. **HTTP script** against `buddy dev`, using `curl` or `Bun.fetch` with a
45
+ fixture payload.
46
+ 3. **CLI invocation**, for instance `buddy <command>` with a fixture input,
47
+ diffing stdout against a known-good snapshot.
48
+ 4. **REPL probe**. `buddy repl` reaches models, config and the query builder
49
+ directly, which is the fastest loop for an ORM or relationship bug.
50
+ 5. **Headless browser script**. `/stacks-browse` drives a real browser over CDP
51
+ and asserts on DOM, console and network with nothing to install.
52
+ 6. **Replay a captured trace.** Save a real request, payload or event log to
53
+ disk, then replay it through the code path in isolation.
54
+ 7. **Throwaway harness.** A single file that boots the minimum (one action, a
55
+ seeded database) and exercises the bug path with one call.
56
+ 8. **Deterministic database state.** `buddy migrate:fresh --seed` plus the
57
+ model factories gives byte-identical rows every run, which turns "sometimes
58
+ wrong" into "always wrong" more often than you would expect.
59
+ 9. **Property or fuzz loop.** For "sometimes the output is wrong", run a
60
+ thousand inputs and look for the failure mode.
61
+ 10. **Bisection harness.** If the bug appeared between two known states, automate
62
+ "boot at state X, check, repeat" so `git bisect run` can consume it.
63
+ 11. **Differential loop.** Same input through two versions or two configs, diff
64
+ the outputs. This is the one for a dependency bump or a driver swap.
65
+ 12. **HITL bash script.** Last resort. If a human must click, drive *them* with
66
+ [scripts/hitl-loop.template.sh](scripts/hitl-loop.template.sh) so the loop is
67
+ still structured, and the captured output feeds back to you.
68
+
69
+ Build the right feedback loop and the bug is 90% fixed.
70
+
71
+ ### Tighten the loop
72
+
73
+ Treat the loop as a product. Once you have *a* loop, **tighten** it:
74
+
75
+ - Faster. Narrow the test path, skip unrelated init, reuse the seeded database
76
+ instead of re-migrating.
77
+ - Sharper signal. Assert on the specific symptom, not "it did not crash".
78
+ - More deterministic. Pin the clock, seed the RNG, isolate the filesystem, freeze
79
+ the network, and pick one driver rather than whatever `config/` happens to
80
+ select.
81
+
82
+ A 30-second flaky loop is barely better than no loop. A 2-second deterministic
83
+ one is a superpower.
84
+
85
+ ### Non-deterministic bugs
86
+
87
+ The goal is not a clean repro but a **higher reproduction rate**. Loop the
88
+ trigger 100 times, parallelise, add stress, narrow the timing window, inject
89
+ sleeps. A 50% flake is debuggable, 1% is not, so keep raising the rate.
90
+
91
+ ### When you genuinely cannot build a loop
92
+
93
+ Stop and say so explicitly. List what you tried. Ask the user for one of: access
94
+ to an environment that reproduces it, a redacted captured artifact (a HAR file, a
95
+ log dump from `storage/logs/stacks.log`, a screen recording with timestamps), or
96
+ permission to add temporary instrumentation in production. Do **not** proceed to
97
+ hypothesise without a loop.
98
+
99
+ ### Completion criterion: a tight loop that goes red
100
+
101
+ Phase 1 is done when you can name **one command** that you have **already run at
102
+ least once**, showing the invocation and its output, redacted, and that is:
103
+
104
+ - [ ] **Red-capable.** It drives the actual bug code path and asserts the
105
+ **user's exact symptom**, so it can go red now and green once fixed. Not
106
+ "runs without erroring".
107
+ - [ ] **Deterministic.** Same verdict every run, or for a flaky bug, a pinned
108
+ high reproduction rate.
109
+ - [ ] **Fast.** Seconds, not minutes.
110
+ - [ ] **Agent-runnable.** You can run it unattended, with a human in the loop
111
+ only through the HITL template.
112
+
113
+ If you catch yourself reading code to build a theory before this command exists,
114
+ **stop. Jumping straight to a hypothesis is the exact failure this skill
115
+ prevents.** No red-capable command, no Phase 2.
116
+
117
+ ## Phase 2: reproduce and minimise
118
+
119
+ Run the loop. Watch it go red.
120
+
121
+ Confirm:
122
+
123
+ - [ ] The loop produces the failure the **user** described, not a different one
124
+ that happens to be nearby. Wrong bug means wrong fix.
125
+ - [ ] It reproduces across multiple runs, or at a high enough rate to debug
126
+ against.
127
+ - [ ] You have captured the exact symptom (error message, wrong output, slow
128
+ timing) so later phases can verify the fix addresses it.
129
+
130
+ Then shrink the repro to the **smallest scenario that still goes red**. Cut
131
+ inputs, callers, config, middleware, seeded rows and steps **one at a time**,
132
+ re-running the loop after each cut, and keep only what is load-bearing.
133
+
134
+ A minimal repro shrinks the hypothesis space in Phase 3 and becomes the clean
135
+ regression test in Phase 5.
136
+
137
+ Done when **every remaining element is load-bearing**: removing any one of them
138
+ makes the loop go green.
139
+
140
+ ## Phase 3: hypothesise
141
+
142
+ Generate **3 to 5 ranked hypotheses** before testing any of them.
143
+ Single-hypothesis generation anchors on the first plausible idea.
144
+
145
+ Each must be **falsifiable**, stating the prediction it makes:
146
+
147
+ > If X is the cause, then changing Y will make the bug disappear, or changing Z
148
+ > will make it worse.
149
+
150
+ If you cannot state the prediction, the hypothesis is a vibe. Discard or sharpen
151
+ it.
152
+
153
+ Gather the evidence that ranks them from where Stacks actually keeps it:
154
+
155
+ - `storage/logs/stacks.log` for the runtime trail.
156
+ - `git log --oneline -20 -- <paths>` for what changed recently.
157
+ - `config/*.ts` for which driver, connection or host is selected in this
158
+ environment.
159
+ - `app/Models/` and `storage/framework/defaults/app/Models/` for the model, and
160
+ `database/migrations/` for whether the schema matches it.
161
+ - `storage/framework/types/*.d.ts` and the auto-import manifests, which are
162
+ generated and go stale. A symbol that types as `any` in an app is usually this.
163
+ - `routes/`, `app/Middleware.ts` and `app/Events.ts` for the registries, where a
164
+ missing entry fails silently rather than loudly.
165
+ - `bun.lock` and `pantry.lock`. There are two install trees, and Bun resolves
166
+ `node_modules`, so verify the version that actually loads.
167
+
168
+ Show the ranked list to the user before testing. They often re-rank it instantly
169
+ ("we just deployed a change to number three") or name one already ruled out. Do
170
+ not block on it. Proceed with your ranking if the user is away.
171
+
172
+ ## Phase 4: instrument
173
+
174
+ Each probe maps to a specific prediction from Phase 3. **Change one variable at a
175
+ time.**
176
+
177
+ Tool preference:
178
+
179
+ 1. **REPL or debugger inspection** where the environment supports it. One
180
+ breakpoint beats ten logs, and `buddy repl` is usually reachable.
181
+ 2. **Targeted logs** at the boundaries that distinguish the hypotheses, via
182
+ `log.debug()` from `@stacksjs/logging`.
183
+ 3. Never "log everything and grep".
184
+
185
+ **Tag every debug log** with a unique prefix such as `[DEBUG-a4f2]`, so cleanup
186
+ is a single grep. Untagged logs survive. Tagged ones die.
187
+
188
+ **Performance branch.** For a regression, logs are usually the wrong instrument.
189
+ Establish a baseline measurement first (a timing harness, `performance.now()`, a
190
+ profiler, the query plan), then bisect. Measure first, fix second. In a Stacks
191
+ app the first thing to measure is query count, because an N+1 through a
192
+ relationship looks exactly like "the framework got slower".
193
+
194
+ ## Phase 5: fix and regression test
195
+
196
+ Write the regression test **before the fix**, but only if there is a **correct
197
+ seam** for it.
198
+
199
+ A correct seam is one where the test exercises the **real bug pattern** as it
200
+ occurs at the call site. If the only available seam is too shallow (a single
201
+ caller test when the bug needs several, a unit test that cannot replicate the
202
+ chain that triggered it), a test there gives false confidence.
203
+
204
+ **If no correct seam exists, that itself is the finding.** Note it. The
205
+ architecture is preventing the bug from being locked down, which is a
206
+ `stacks-codebase-design` problem, not a testing one.
207
+
208
+ If a correct seam exists:
209
+
210
+ 1. Turn the minimised repro into a failing test at that seam.
211
+ 2. Watch it fail.
212
+ 3. Apply the fix. Change as little as possible.
213
+ 4. Watch it pass.
214
+ 5. Re-run the Phase 1 loop against the original, un-minimised scenario.
215
+
216
+ ## Phase 6: cleanup
217
+
218
+ Required before declaring done:
219
+
220
+ - [ ] The original repro no longer reproduces. Re-run the Phase 1 loop.
221
+ - [ ] The regression test passes, or the absence of a seam is documented.
222
+ - [ ] All `[DEBUG-...]` instrumentation removed. Grep the prefix.
223
+ - [ ] Throwaway harnesses deleted, or moved to a clearly marked debug location.
224
+ - [ ] `./buddy lint:fix` and `./buddy typecheck` are clean.
225
+ - [ ] The hypothesis that turned out correct is stated in the commit message, so
226
+ the next debugger learns.
108
227
 
109
228
  ## Rules
110
229
 
111
- - **No fixes without root cause.** If you can't explain WHY, you haven't found the bug.
112
- - **Read before you grep.** Understand architecture first.
113
- - **Don't blame the framework first.** Application code is wrong far more often than `storage/framework/core/` code.
114
- - **Intermittent bugs are timing bugs** until proven otherwise. Look for race conditions, missing `await`, shared mutable state.
115
- - **If the fix is more than ~20 lines, question the root cause.** Large fixes often mean you're working around the problem.
230
+ - **No fixes without root cause.** If you cannot explain why, you have not found
231
+ the bug.
232
+ - **Never apply a fix to see if it helps.** That is a hypothesis test with no
233
+ prediction and no cleanup.
234
+ - **Do not blame the framework first.** Application code and configuration are
235
+ wrong far more often than `storage/framework/core/` is.
236
+ - **Intermittent bugs are timing bugs** until proven otherwise. Look for a
237
+ missing `await`, a race, or shared mutable state.
238
+ - **If the fix runs past about 20 lines, question the root cause.** Large fixes
239
+ usually mean you are working around the problem.
240
+ - **Check the blast radius before you fix.** A change in `storage/framework/core/`
241
+ can reach 15+ downstream packages, and in a published package a change to a
242
+ `.d.ts` path can silently degrade consumers to `any`.
116
243
 
117
244
  ## Downstream
118
245
 
119
- > **Fix applied.** Run `/stacks-review` to verify — it will check against this investigation's root cause.
246
+ > **Fix applied.** Run `/stacks-review` to review it, and `/stacks-retro` when
247
+ > the real lesson is that the environment let the bug hide.
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bash
2
+ # Human-in-the-loop reproduction loop.
3
+ #
4
+ # Adapted from Matt Pocock's `diagnosing-bugs` skill (MIT),
5
+ # https://github.com/mattpocock/skills
6
+ # Copy this file, edit the steps below, and run it.
7
+ # The agent runs the script; the user follows prompts in their terminal.
8
+ #
9
+ # Usage:
10
+ # bash hitl-loop.template.sh
11
+ #
12
+ # Two helpers:
13
+ # step "<instruction>" → show instruction, wait for Enter
14
+ # capture VAR "<question>" → show question, read response into VAR
15
+ #
16
+ # At the end, captured values are printed as KEY=VALUE for the agent to parse.
17
+ #
18
+ # `capture` prints its value back to the terminal, where the agent reads it,
19
+ # so capture observations, and leave signing in to the user as a `step`.
20
+
21
+ set -euo pipefail
22
+
23
+ step() {
24
+ printf '\n>>> %s\n' "$1"
25
+ read -r -p " [Enter when done] " _
26
+ }
27
+
28
+ capture() {
29
+ local var="$1" question="$2" answer
30
+ printf '\n>>> %s\n' "$question"
31
+ read -r -p " > " answer
32
+ printf -v "$var" '%s' "$answer"
33
+ }
34
+
35
+ # --- edit below ---------------------------------------------------------
36
+
37
+ step "Run ./buddy dev, open the app, and sign in."
38
+
39
+ capture ERRORED "Click the 'Export' button. Did it throw an error? (y/n)"
40
+
41
+ capture ERROR_MSG "Paste the error message (or 'none'):"
42
+
43
+ # --- edit above ---------------------------------------------------------
44
+
45
+ printf '\n--- Captured ---\n'
46
+ printf 'ERRORED=%s\n' "$ERRORED"
47
+ printf 'ERROR_MSG=%s\n' "$ERROR_MSG"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-jobs
3
- description: Use when creating background job classes in app/Jobs/ — job structure, the handle method, job configuration (queue, tries, backoff, timeout, rate), dispatching patterns (dispatch, dispatchIf, dispatchAfter, dispatchNow), or the Every schedule constants. For the queue system internals (workers, batching, events, drivers, testing), see stacks-queue.
3
+ description: Use when creating background job classes in app/Jobs/ - job structure, the handle method, job configuration (queue, tries, backoff, timeout, rate), dispatching patterns (dispatch, dispatchIf, dispatchAfter, dispatchNow), or the Every schedule constants. For the queue system internals (workers, batching, events, drivers, testing), see stacks-queue.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-listeners
3
- description: Use when creating event listeners in app/Listeners/ — the listener file structure, registering listeners in app/Events.ts, the listener-to-action mapping pattern, CLI event listeners in Console.ts, or debugging listener execution. For the event system API (dispatch, listen, emitter, model events), see stacks-events.
3
+ description: Use when creating event listeners in app/Listeners/ - the listener file structure, registering listeners in app/Events.ts, the listener-to-action mapping pattern, CLI event listeners in Console.ts, or debugging listener execution. For the event system API (dispatch, listen, emitter, model events), see stacks-events.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-logging
3
- description: Use when implementing logging in Stacks — the log facade (info, error, warn, debug, success), dump/dd debugging, timing functions, file-based logging, or log configuration. Covers @stacksjs/logging and config/logging.ts.
3
+ description: Use when implementing logging in Stacks - the log facade (info, error, warn, debug, success), dump/dd debugging, timing functions, file-based logging, or log configuration. Covers @stacksjs/logging and config/logging.ts.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-mail
3
- description: Use when creating mail classes in app/Mail/ — defining email content and templates, using the template() function with STX or HTML templates, variable interpolation, email layouts, or the app-level mail sending pattern. For the email framework itself (drivers, Mail singleton, EmailSDK, inbox management), see stacks-email.
3
+ description: Use when creating mail classes in app/Mail/ - defining email content and templates, using the template() function with STX or HTML templates, variable interpolation, email layouts, or the app-level mail sending pattern. For the email framework itself (drivers, Mail singleton, EmailSDK, inbox management), see stacks-email.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-middleware
3
- description: Use when working with middleware in a Stacks application — defining middleware, applying to routes, middleware aliases, parameterized middleware, groups, or the middleware execution pipeline. Covers the Middleware class, app/Middleware.ts alias registry, and all 22 default middleware files.
3
+ description: Use when working with middleware in a Stacks application - defining middleware, applying to routes, middleware aliases, parameterized middleware, groups, or the middleware execution pipeline. Covers the Middleware class, app/Middleware.ts alias registry, and all 22 default middleware files.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-migrations
3
- description: Use when working with database migrations in a Stacks application — creating migration files, running migrations, fresh migration (drop + recreate), seeding after migration, migration file naming conventions, or the 96+ built-in migration files. For the database API itself (queries, connections, SQL helpers), see stacks-database.
3
+ description: Use when working with database migrations in a Stacks application - creating migration files, running migrations, fresh migration (drop + recreate), seeding after migration, migration file naming conventions, or the 96+ built-in migration files. For the database API itself (queries, connections, SQL helpers), see stacks-database.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript, SQLite >= 3.47.2
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-models
3
- description: Use when working with data models in Stacks — the defineModel() API, model attributes with validation and factories, relationships (hasOne/hasMany/belongsTo/belongsToMany), traits (useAuth, useUuid, useTimestamps, useSearch, useApi, billable, taggable, categorizable, commentable, likeable, observe), computed properties (get/set), model generation, and the 50+ built-in framework models. Covers model definitions and storage/framework/defaults/app/Models/.
3
+ description: Use when working with data models in Stacks - the defineModel() API, model attributes with validation and factories, relationships (hasOne/hasMany/belongsTo/belongsToMany), traits (useAuth, useUuid, useTimestamps, useSearch, useApi, billable, taggable, categorizable, commentable, likeable, observe), computed properties (get/set), model generation, and the 50+ built-in framework models. Covers model definitions and storage/framework/defaults/app/Models/.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript, SQLite >= 3.47.2
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-new-feature
3
- description: Use when adding a new feature end-to-end in a Stacks application — the complete workflow from model definition through migration, action, route, test, and deployment. Covers the recommended order of operations for building features.
3
+ description: Use when adding a new feature end-to-end in a Stacks application - slicing the work into tracer bullets, then building each slice from model through migration, action, route, test and deploy. Covers the recommended order of operations, the blocking edges between slices, and the expand-contract sequence for a wide refactor.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -10,12 +10,66 @@ allowed-tools: Read Edit Write Bash Grep Glob
10
10
 
11
11
  Step-by-step guide for building features end-to-end.
12
12
 
13
+ ## Slice it first
14
+
15
+ Before any code, break the work into **tracer bullets**: vertical slices, each
16
+ cutting a narrow but complete path through every layer.
17
+
18
+ - Each slice cuts through model, migration, action, route and test. Vertical, not
19
+ a horizontal slice of one layer.
20
+ - A finished slice is demoable or verifiable on its own.
21
+ - Each slice fits in one fresh context window.
22
+ - Any prefactoring goes first. Make the change easy, then make the easy change.
23
+
24
+ Give each slice its **blocking edges**: the slices that must land before it can
25
+ start. A slice with no blockers can start immediately, and the set of slices
26
+ whose blockers are all done is the **frontier** you work from.
27
+
28
+ Present the breakdown as a numbered list before building anything. For each
29
+ slice: the title, what it delivers end to end, and what blocks it. Then ask
30
+ whether the granularity is right, whether the edges are real, and whether
31
+ anything should be merged or split. Iterate until the user approves.
32
+
33
+ Where the project tracks work on a real tracker, publish the slices in
34
+ dependency order so the edges can reference real identifiers. Where it does not,
35
+ one file per slice under `.scratch/<feature>/issues/<NN>-<slug>.md`, numbered
36
+ blockers-first, is enough. Avoid file paths and code snippets in either form,
37
+ because they go stale faster than the ticket does.
38
+
39
+ ### The exception: a wide refactor
40
+
41
+ A **wide refactor** is one mechanical change whose blast radius fans across the
42
+ codebase, so a single edit breaks hundreds of call sites at once and no vertical
43
+ slice can land green. Renaming a model column, retyping a shared symbol, and
44
+ changing an exported signature in `storage/framework/core/` are all this shape.
45
+
46
+ Do not force it into a tracer bullet. Sequence it as **expand and contract**:
47
+
48
+ 1. **Expand.** Add the new form beside the old so nothing breaks. A new column
49
+ alongside the old one, a new export alongside the old one.
50
+ 2. **Migrate** the call sites in batches sized by blast radius, one per package or
51
+ directory, each batch its own slice blocked by the expand. CI stays green
52
+ batch to batch because the old form still exists.
53
+ 3. **Contract.** Delete the old form once no caller remains, in a slice blocked by
54
+ every migrate batch.
55
+
56
+ When even the batches cannot stay green alone, keep the sequence but let them
57
+ share an integration branch that all block a final integrate-and-verify slice.
58
+ Green is promised only there.
59
+
60
+ Credit: the tracer-bullet and expand-contract framing is adapted from Matt
61
+ Pocock's `to-tickets` skill (MIT), <https://github.com/mattpocock/skills>.
62
+
13
63
  ## Workflow Overview
14
64
 
15
65
  ```
16
66
  1. Model → 2. Migration → 3. Action → 4. Route → 5. Test → 6. Lint → 7. Deploy
17
67
  ```
18
68
 
69
+ Run this once per slice, not once per feature. Within a slice, `stacks-tdd`
70
+ owns the red-green loop: the migration lands, then the failing test, then the
71
+ code that passes it.
72
+
19
73
  ## Step 1: Define the Model
20
74
 
21
75
  ```typescript
@@ -119,7 +173,7 @@ route.group({ prefix: '/articles', middleware: ['auth'] }, () => {
119
173
  })
120
174
  ```
121
175
 
122
- Or rely on auto-generated routes from `useApi` trait — they're created automatically.
176
+ Or rely on auto-generated routes from `useApi` trait - they're created automatically.
123
177
 
124
178
  ### When a TypeScript client will call these
125
179
 
@@ -144,14 +198,14 @@ const client = createTypedClient<AppRoutes>({ baseUrl })
144
198
  const created = await client.post('/articles', { title: 'x', content: 'y' })
145
199
  ```
146
200
 
147
- Same runtime path, same middleware, same OpenAPI document — the difference is
201
+ Same runtime path, same middleware, same OpenAPI document - the difference is
148
202
  entirely at compile time. Keep the string form for routes no TypeScript consumer
149
203
  calls; it stays lazily imported. See the `stacks-api` and `stacks-router` skills.
150
204
 
151
205
  ## Step 5: Add Event Listeners (Optional)
152
206
 
153
207
  ```typescript
154
- // app/Events.ts — add to existing
208
+ // app/Events.ts - add to existing
155
209
  {
156
210
  'article:created': ['NotifySubscribers'],
157
211
  'article:published': ['SendNewsletter', 'IndexInSearchEngine']
@@ -225,9 +279,15 @@ export default new Job({
225
279
  ```
226
280
 
227
281
  ## Gotchas
228
- - Models work directly via the dynamic ORM — no generation step needed before migrations
282
+ - Models work directly via the dynamic ORM - no generation step needed before migrations
229
283
  - The `useApi` trait auto-generates both routes AND dashboard views
230
284
  - Model events (observe: true) emit `article:created`, `article:updated`, `article:deleted`
231
285
  - Factories in model attributes are used by `buddy seed`
232
286
  - Always lint after code generation: `bunx --bun pickier . --fix`
233
287
  - Use conventional commits: `feat: add article management`
288
+
289
+ ## Downstream
290
+
291
+ > **Slice green?** Run `/stacks-review` before merging it, then take the next
292
+ > slice off the frontier. `/stacks-tdd` is the loop inside each one, and
293
+ > `/stacks-plan-review` is where to go back to if the slices stop making sense.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-notifications
3
- description: Use when implementing notifications in Stacks — multi-channel notifications (email, SMS, push, chat, database), the database notification driver with read/unread tracking, notification factories (useEmail, useSMS, useChat, useDatabase), or notification configuration. Covers @stacksjs/notifications and config/notification.ts.
3
+ description: Use when implementing notifications in Stacks - multi-channel notifications (email, SMS, push, chat, database), the database notification driver with read/unread tracking, notification factories (useEmail, useSMS, useChat, useDatabase), or notification configuration. Covers @stacksjs/notifications and config/notification.ts.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: stacks-objects
3
- description: Use when working with object manipulation in Stacks — deep merging with type safety, object mapping/transformation, strict key checking, typed entries/keys, property picking, clearing undefined values, or the DeepMerge utility type. Covers @stacksjs/objects.
3
+ description: Use when working with object manipulation in Stacks - deep merging with type safety, object mapping/transformation, strict key checking, typed entries/keys, property picking, clearing undefined values, or the DeepMerge utility type. Covers @stacksjs/objects.
4
4
  license: MIT
5
5
  compatibility: Bun >= 1.3.0, TypeScript
6
6
  allowed-tools: Read Edit Write Bash Grep Glob