specpipe 1.0.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 (60) hide show
  1. package/README.md +1319 -0
  2. package/bin/devkit.js +3 -0
  3. package/package.json +61 -0
  4. package/src/cli.js +76 -0
  5. package/src/commands/check.js +33 -0
  6. package/src/commands/diff.js +84 -0
  7. package/src/commands/init-adopt.js +54 -0
  8. package/src/commands/init-agents.js +118 -0
  9. package/src/commands/init-global.js +102 -0
  10. package/src/commands/init.js +311 -0
  11. package/src/commands/list.js +54 -0
  12. package/src/commands/remove.js +133 -0
  13. package/src/commands/upgrade.js +215 -0
  14. package/src/lib/agent-guards.js +100 -0
  15. package/src/lib/agent-install.js +161 -0
  16. package/src/lib/agents.js +280 -0
  17. package/src/lib/claude-global.js +183 -0
  18. package/src/lib/detector.js +93 -0
  19. package/src/lib/hasher.js +21 -0
  20. package/src/lib/installer.js +213 -0
  21. package/src/lib/logger.js +16 -0
  22. package/src/lib/manifest.js +102 -0
  23. package/src/lib/reconcile.js +56 -0
  24. package/templates/.claude/CLAUDE.md +79 -0
  25. package/templates/.claude/hooks/comment-guard.js +126 -0
  26. package/templates/.claude/hooks/file-guard.js +216 -0
  27. package/templates/.claude/hooks/glob-guard.js +104 -0
  28. package/templates/.claude/hooks/path-guard.sh +118 -0
  29. package/templates/.claude/hooks/self-review.sh +27 -0
  30. package/templates/.claude/hooks/sensitive-guard.sh +227 -0
  31. package/templates/.claude/settings.json +68 -0
  32. package/templates/docs/WORKFLOW.md +325 -0
  33. package/templates/docs/specs/.gitkeep +0 -0
  34. package/templates/hooks/specpipe-read-guard.sh +42 -0
  35. package/templates/hooks/specpipe-shell-guard.sh +65 -0
  36. package/templates/rules/specpipe-guards.md +40 -0
  37. package/templates/scripts/test-hooks.sh +66 -0
  38. package/templates/skills/sp-build/SKILL.md +776 -0
  39. package/templates/skills/sp-challenge/SKILL.md +255 -0
  40. package/templates/skills/sp-commit/SKILL.md +174 -0
  41. package/templates/skills/sp-explore/SKILL.md +730 -0
  42. package/templates/skills/sp-fix/SKILL.md +266 -0
  43. package/templates/skills/sp-humanize/SKILL.md +212 -0
  44. package/templates/skills/sp-investigate/SKILL.md +648 -0
  45. package/templates/skills/sp-md-render/SKILL.md +200 -0
  46. package/templates/skills/sp-md-render/components.md +415 -0
  47. package/templates/skills/sp-md-render/template.html +283 -0
  48. package/templates/skills/sp-plan/SKILL.md +947 -0
  49. package/templates/skills/sp-review/SKILL.md +268 -0
  50. package/templates/skills/sp-scaffold/SKILL.md +237 -0
  51. package/templates/skills/sp-scaffold/references/ARCHITECTURE.md.tmpl +228 -0
  52. package/templates/skills/sp-scaffold/references/DESIGN.md.tmpl +113 -0
  53. package/templates/skills/sp-scaffold/references/adr/NNNN-template.md +92 -0
  54. package/templates/skills/sp-scaffold/references/stack-profiles/react.md +36 -0
  55. package/templates/skills/sp-spec-render/SKILL.md +254 -0
  56. package/templates/skills/sp-spec-render/components.md +418 -0
  57. package/templates/skills/sp-spec-render/examples/user-auth.html +749 -0
  58. package/templates/skills/sp-spec-render/examples/user-auth.md +114 -0
  59. package/templates/skills/sp-spec-render/template.html +222 -0
  60. package/templates/skills/sp-voices/SKILL.md +1184 -0
@@ -0,0 +1,228 @@
1
+ # Architecture — <System Name>
2
+
3
+ <!--
4
+ WHAT THIS FILE IS: the source of truth for the system's *shape* — its boundaries,
5
+ invariants, and the few decisions that are expensive to reverse. It is a map, not an
6
+ atlas: bird's-eye view + named entities, NOT API docs and NOT how-it-works walkthroughs.
7
+ It stays current as the system grows (matklad's ARCHITECTURE.md discipline).
8
+
9
+ WHERE OTHER THINGS LIVE (do not duplicate them here):
10
+ - WHY each major choice was made → §12 ADRs (or docs/adr/ if they grow).
11
+ - Per-feature behaviour contract (Given/When/Then) → docs/specs/<feature>/<feature>.md
12
+ - Discovery / alternatives / scale rationale → docs/explore/<feature>.md (if used)
13
+
14
+ FILL RULE: replace every <placeholder>. Delete any section that genuinely does not apply
15
+ to this app-type (e.g. §10 for a system with no async work) — but say so in §2 non-goals
16
+ rather than leaving an empty heading. Keep prose tight; this is a map, not a novel.
17
+ -->
18
+
19
+ > Handoff-grade design doc. Source of truth for the system *shape*. Deep rationale lives in `docs/explore/`; the behaviour contract in `docs/specs/`.
20
+
21
+ ## 1. Overview & primary quality goal
22
+
23
+ <!-- 2-3 sentences: what the system does, for whom. Then name the ONE quality goal that
24
+ dominates design (correctness-under-concurrency / latency / data-integrity / security /
25
+ availability). Everything else is secondary — say so. This goal justifies the hard calls below. -->
26
+
27
+ <one-paragraph what + who>
28
+
29
+ **Primary quality goal:** *<the one property that dominates>* — <why it dominates, in one sentence>.
30
+
31
+ ## 2. Scope & non-goals
32
+
33
+ **In scope:** <bullet or sentence list of what ships>
34
+
35
+ **Non-goals (deliberate):**
36
+ - <thing not built> — <one-line why deferred / out of brief>
37
+
38
+ ## 3. System context (C4 L1)
39
+
40
+ <!-- Who/what is OUTSIDE the system and how they talk to it. One box = this system;
41
+ the rest are users + external parties. Keep external dependencies as external boxes so
42
+ they stay swappable. -->
43
+
44
+ ```mermaid
45
+ flowchart LR
46
+ user([<actor>])
47
+ sys[<This system>]
48
+ ext[[<External party / 3rd-party service>]]
49
+ user --> sys
50
+ sys --> ext
51
+ ```
52
+
53
+ ## 4. Container / component view (C4 L2)
54
+
55
+ <!-- The deployable/runnable units inside the system (frontend, API, worker, DB, cache,
56
+ queue) and the data/control flow between them. A "container" is a runnable unit or a
57
+ datastore — NOT a Docker container specifically. State the ONE boundary rule that must
58
+ never be crossed (e.g. "DB is the single source of truth; cache is transport only"). -->
59
+
60
+ ```mermaid
61
+ flowchart TB
62
+ subgraph A[<unit>]
63
+ a[<component>]
64
+ end
65
+ store[(<datastore>)]
66
+ a --> store
67
+ ```
68
+
69
+ **Boundary rule (non-negotiable):** <the one architectural boundary that must hold — what owns truth, what is allowed to talk to what>.
70
+
71
+ **Codemap — organizing principle + where things live**
72
+
73
+ <!-- matklad's codemap: LEAD WITH THE PRINCIPLE (stable), then an illustrative tree.
74
+ The PRINCIPLE is language-agnostic; the NAMES and the physical MECHANISM (folders vs
75
+ packages vs targets vs crates) vary by stack — adapt them, never copy one stack's tree
76
+ blindly. Keep this bird's-eye. sp-build reads THIS to decide where new code/tests go. -->
77
+
78
+ **Two layers under ONE root, as siblings — the split IS the architecture; the names are the project's.**
79
+
80
+ - **Core layer — reusable foundation, feature-independent.** The wrapper/plumbing every feature reuses: entrypoint/bootstrap, config & env, IO/filesystem/request plumbing, DI, error handling, logging, shared utils + base types. Changes shape rarely; nothing business-specific lives here.
81
+ - **Feature layer — business logic + the scaling axis.** One self-contained unit per capability; grow the app by ADDING a feature, never by editing core. This is the vertical slice a story builds.
82
+
83
+ Both live under the **same root, discoverable as siblings.** Do NOT scatter them into disconnected top-level trees, and do NOT bury the real code several levels deep inside a wrapper dir. (Anti-pattern seen in the wild: a `core/` package sitting next to a separate `app/` tree with the actual code at `core/Sources/<Pkg>/...` — that is two disconnected trees, not core+feature siblings.) The *mechanism* maps the two layers onto whatever the stack's unit of modularity is:
84
+
85
+ - **JS/TS:** `core/` + `features/` (or `modules/`) directories at root.
86
+ - **Swift/SPM:** one `Package.swift` at root; a `Core` target + per-feature targets under `Sources/`; the app/GUI target in the **same** package (or an Xcode project at root that depends on it) — never a buried `core/` sub-package beside a disconnected `app/` tree.
87
+ - **Go:** a `core`/`internal` package + per-feature packages. **Rust:** a core crate/module + feature modules. **C#/Java:** a Core project + feature projects in one solution.
88
+
89
+ Architecture layers (domain / use-case / infrastructure — Clean Architecture) are ORTHOGONAL and optional: they live *inside* core and *inside* each feature; they are NOT the top-level split.
90
+
91
+ ```
92
+ <root>/ # illustrative (JS names) — map to your stack's mechanism
93
+ ├── core/ # reusable foundation: bootstrap, config, IO plumbing, DI, errors, shared utils
94
+ ├── features/ # one unit per capability (the scale axis) — add here, don't edit core
95
+ │ └── <capability>/ # its own logic + types (tests per the test-layout rule below)
96
+ └── <tests/integration> # cross-feature / real-dependency tests
97
+ ```
98
+
99
+ **Test layout — one rule per tier, decided once and enforced.** The structure leaks when the convention is implicit. Unit tests live as close to the code as the language idiomatically allows; each higher tier moves one step outward into its own dir + own runner:
100
+
101
+ - **Unit / component → co-located.** JS/TS: sibling `foo.ts` → `foo.test.ts` (flat sibling, not `__tests__/`). Go: `foo_test.go` same package. Rust: `#[cfg(test)] mod tests` inline. Mocked deps; logic decidable without external state.
102
+ - **Integration → a separate dir INSIDE the package** (`tests/integration/`, or tag `*.int.test.ts` if sharing a dir). Real deps, NOT mocked, its own task.
103
+ - **e2e → a separate top-level dir / package** with its own runner + config — never in the unit runner's `include`. Monorepo: its own package (`e2e/`).
104
+ - **Naming: ONE suffix repo-wide** — `.test.*` for unit + integration; reserve a distinct tag for e2e (`.e2e.test.*` / `.e2e-spec.*`) so runners select disjoint sets by glob. NEVER mix `.spec` and `.test`.
105
+ - **Monorepo:** package-private tests in each package; cross-package e2e its own package; shared fixtures/config in one `test-utils`/`test-config` package, not duplicated.
106
+ - **Ecosystem escape hatch (general rule: tests go where the language idiomatically puts them — don't impose the JS `__tests__/` / `.test.` shape on other stacks):** Python → src-layout (`src/pkg/` + top-level `tests/` mirror, `test_*.py`, `conftest.py`); Java/Maven → `src/test` mirror; **Swift/SPM → `Tests/<Target>Tests/` mirror (`swift test`), not co-located siblings**; Go/Rust → the language rule above IS the layout (inline / `tests/` for Rust integration). When unsure, follow what the stack's official scaffolder/test runner expects.
107
+
108
+ **The split rule (correctness, not bookkeeping):** which tier a test belongs to is decided by *what its correctness depends on*. A test whose correctness IS the integration — SQL-level guarantees (conditional updates, unique constraints, locking); cross-surface data flow where one surface writes and another reads (test the seam, incl. write-twice / out-of-order); idempotency / exactly-once across endpoints; transactions — MUST be a real-dependency test. Mocking the thing under test there yields a vacuous test that passes while the real behaviour is broken.
109
+
110
+ ## 5. Data model
111
+
112
+ <!-- Entities, key fields, and the structural guarantees the storage layer enforces
113
+ (unique indexes, constraints, FKs). Note WHICH field is the guard for any contended state.
114
+ Schema/migration detail belongs here, never in a spec's acceptance scenarios. -->
115
+
116
+ | Entity | Key fields | Notes |
117
+ |---|---|---|
118
+ | `<entity>` | `<fields>` | <invariants this entity carries> |
119
+
120
+ **Structural guarantees (enforced by the store, not just app code):**
121
+ - <unique index / constraint / FK and the invariant it protects>
122
+
123
+ ## 6. Core flows & state machines
124
+
125
+ <!-- The 1-3 flows that carry the primary quality goal. Use a state diagram for any entity
126
+ with a lifecycle, a sequence diagram for any multi-actor flow (request → queue → worker → store).
127
+ Call out the guarded write: a state change that is allowed ONLY when a guard condition held. -->
128
+
129
+ ```mermaid
130
+ stateDiagram-v2
131
+ [*] --> <state>
132
+ <state> --> <state>: <transition + guard>
133
+ ```
134
+
135
+ <short prose for each core flow; name the guarded transitions>
136
+
137
+ ## 7. Invariants & correctness *(non-negotiable)*
138
+
139
+ <!-- THE most important section (matklad). List the properties that must ALWAYS hold,
140
+ across EVERY code path that could violate them — not just the path where they were first
141
+ conceived. Express as absences where possible ("never two confirmed reservations per seat",
142
+ "money never moves without a traceable record", "a request retried twice causes one effect").
143
+
144
+ CONVERGENCE WITH SPECS: each invariant here SHOULD become an `INV-NNN` in the feature spec,
145
+ with an `applies-to:` list naming every endpoint/surface that can break it — so the build
146
+ tests it at every surface, not only the obvious one. An invariant tested at one surface and
147
+ not another is the classic cross-surface bug (e.g. idempotency enforced on the webhook but
148
+ not on the separate intent-creation endpoint). State the mechanism that enforces each one. -->
149
+
150
+ - **INV-1 · <name>:** <the property> — enforced by <mechanism>; applies to <surfaces>.
151
+ - **INV-2 · <name>:** <…>
152
+
153
+ ## 8. API / interface contracts
154
+
155
+ <!-- The system's boundary surface: HTTP endpoints, CLI commands, library exports, or events.
156
+ One row per surface. Note auth requirement and error outcomes. For a producer/consumer split
157
+ (separate FE/BE), this table is the contract both sides build against — pin the seam here. -->
158
+
159
+ <envelope/format note if any>
160
+
161
+ | Surface | Auth | Request | Success | Errors |
162
+ |---|---|---|---|---|
163
+ | `<method · path / command / export>` | <auth> | `<in>` | `<out>` | `<errors>` |
164
+
165
+ ## 9. Auth & security
166
+
167
+ <!-- Authn (who you are) AND authz (what you may touch — ownership, not just session).
168
+ Session model, secret handling, CSRF/replay/injection guards relevant to this system.
169
+ Omit subsections that don't apply; never omit authz if the system has protected actions. -->
170
+
171
+ - **AuthN:** <mechanism, session model, lifetime, revocability>
172
+ - **AuthZ:** <ownership rule — a valid session is necessary but not sufficient>
173
+ - **Secrets/config:** <how secrets are supplied; never in the client; .env.example provided>
174
+ - **Boundary guards:** <CSRF / replay / rate-limit / input validation as applicable>
175
+
176
+ ## 10. Async / background processing
177
+
178
+ <!-- DELETE this section if the system has no async/queue/scheduled work. Otherwise:
179
+ ingest → queue → worker → store, with dedup/idempotency, retry/backoff/DLQ, and the
180
+ recovery path for "the event never arrived" (reconciliation / inbox drain). -->
181
+
182
+ - **Receive / enqueue:** <verify, dedup at the edge, fast-ack>
183
+ - **Process (worker):** <dedup again, transactional apply, guarded write>
184
+ - **Failure & recovery:** <retry/backoff/DLQ; reconciliation for missing events; bounded so it never loops forever>
185
+
186
+ ## 11. Cross-cutting concerns
187
+
188
+ <!-- Conventions applied everywhere: response/error format, validation, IDs, logging,
189
+ error hygiene (never leak internals to clients). Short bullets. -->
190
+
191
+ - <response/error envelope · validation · ID scheme · logging · error hygiene>
192
+
193
+ ## 12. Decisions (lightweight ADRs)
194
+
195
+ <!-- One ADR per significant, expensive-to-reverse choice (stack, storage, auth transport,
196
+ sync vs async). Format: Context → Decision → Consequence. These are immutable once made;
197
+ to change one, supersede it with a new ADR. If ADRs grow past ~6, move to docs/adr/NNNN-*.md
198
+ (see adr/NNNN-template.md). The tech-stack rationale lives HERE, not in §1. -->
199
+
200
+ **ADR-1 · <decision>.** *Context:* <forces>. *Decision:* <what was chosen over what>. *Consequence:* <what this commits us to>.
201
+
202
+ ## 13. Run & deploy
203
+
204
+ <!-- The shortest path from clone to running. Commands, env setup, what seeds/migrations
205
+ run on start, ports, dev credentials. The step-by-step runbook can live in README; this is
206
+ the deploy-shape summary. -->
207
+
208
+ ```bash
209
+ <clone → configure env → run>
210
+ ```
211
+
212
+ ## 14. Scale path & known risks
213
+
214
+ <!-- What you'd do when it grows (documented, NOT built — so reviewers see you know the
215
+ ceiling) + the honest risk list + accepted risks (by decision) + known gaps (config
216
+ defaults that aren't decided requirements). -->
217
+
218
+ **Scale path (documented, not built):** <levers for when this grows>
219
+
220
+ **Known risks:** <highest-likelihood/impact risks + mitigation>
221
+
222
+ **Accepted risks (by decision):** <risk + why acceptable here>
223
+
224
+ **Known gaps:** <config defaults or unresolved questions>
225
+
226
+ ---
227
+ <!-- Keep this file synced with the specs it describes; note the last sync below. -->
228
+ > Synced with `docs/specs/<feature>/<feature>.md` on <YYYY-MM-DD>.
@@ -0,0 +1,113 @@
1
+ # Design: <Feature Name>
2
+
3
+ <!--
4
+ WHAT THIS IS: a per-feature, forward-looking technical proposal — how to build a change
5
+ that doesn't exist yet, why this way, what was rejected. It is time-bound: once the feature
6
+ ships, this becomes a historical record of intent and is expected to go stale.
7
+
8
+ HOW IT DIFFERS FROM ITS NEIGHBOURS (don't duplicate):
9
+ - ARCHITECTURE.md = the LIVING system map (always current, no argument, no expiry).
10
+ - ADR = ONE immutable decision (this doc may SPAWN ADRs for its irreversible choices).
11
+ - docs/specs/<feature>/<feature>.md = the BEHAVIOUR contract (Given/When/Then acceptance
12
+ scenarios). THIS doc is the technical "how/why"; the spec is the testable "what". They are
13
+ companions — keep behaviour assertions in the spec, design reasoning here.
14
+
15
+ PIPELINE: explore → DESIGN.md (this) proposes & justifies → spawns ADRs for hard calls →
16
+ sp-plan turns the agreed behaviour into the spec → after build, durable consequences fold
17
+ into ARCHITECTURE.md. Not every feature needs a DESIGN.md — write one when the technical
18
+ design is non-trivial or contested. A simple feature can go straight to the spec.
19
+
20
+ FILL RULE: replace every <placeholder>. Keep the CORE sections; delete optional subsections
21
+ that don't apply rather than leaving them empty. A "mini" design can collapse to
22
+ Summary + Goals & Non-Goals + Proposed Design + Alternatives.
23
+ -->
24
+
25
+ ## Metadata <!-- CORE -->
26
+
27
+ - **Author(s):** <name>
28
+ - **Status:** Draft | In Review | Approved | Implemented | Superseded
29
+ - **Created / Updated:** <YYYY-MM-DD> / <YYYY-MM-DD>
30
+ - **Reviewers:** <names>
31
+ - **Related:** <ARCHITECTURE.md §N · ADR-NNNN · docs/specs/<feature> · ticket>
32
+
33
+ ## Summary <!-- CORE -->
34
+
35
+ <!-- One self-contained paragraph a reader can grasp without the rest. What changes, and why now. -->
36
+
37
+ <one paragraph>
38
+
39
+ ## Context & Background <!-- CORE -->
40
+
41
+ <!-- The problem, the current state, the constraints. Why this is worth doing. Link to the
42
+ explore doc / ticket for deep rationale rather than repeating it. -->
43
+
44
+ <the situation that motivates this design>
45
+
46
+ ## Goals & Non-Goals <!-- CORE -->
47
+
48
+ **Goals:**
49
+ - <what success looks like — measurable where possible>
50
+
51
+ **Non-Goals:**
52
+ - <explicitly out of scope, so the design isn't judged against it>
53
+
54
+ ## Proposed Design <!-- CORE -->
55
+
56
+ <!-- The heart of the doc. Lead with an overview, then only the subsections that carry weight
57
+ for THIS feature. Show the seam: where this feature touches existing surfaces. -->
58
+
59
+ **Overview:** <the approach in a few sentences>
60
+
61
+ <!-- OPTIONAL subsections — keep the ones that matter: -->
62
+ - **System-context / data flow:** <diagram or prose — where this sits, what it talks to>
63
+ - **APIs / interfaces:** <new or changed endpoints/commands/exports + their contract>
64
+ - **Data model / storage:** <new entities, fields, migrations, indexes>
65
+ - **Key logic:** <pseudo-code ONLY for genuinely novel algorithms — not routine CRUD>
66
+ - **Degree of constraint:** <how prescriptive this design is — what's fixed vs left to the implementer>
67
+
68
+ ## Alternatives Considered <!-- CORE -->
69
+
70
+ <!-- The real candidates, including "do nothing". For each: what it was and why it lost.
71
+ This is what separates a design doc from a spec — the reasoning, not just the chosen path. -->
72
+
73
+ - **<alternative>:** <what it was> — rejected because <reason>.
74
+ - **Do nothing:** <consequence of not building this>.
75
+
76
+ ## Trade-offs & Risks <!-- CORE -->
77
+
78
+ <!-- What this design costs, what could go wrong, what you're accepting. Be honest. -->
79
+
80
+ - <trade-off accepted / risk + mitigation>
81
+
82
+ ## Cross-cutting Concerns <!-- CORE — fill the ones that apply -->
83
+
84
+ <!-- Address each relevant axis. "N/A — <reason>" is a valid answer; an empty one is not.
85
+ TESTING ties to the build: name the invariants this feature must uphold (they should become
86
+ INV-NNN in the spec, tested at EVERY surface that can break them — not just the obvious one),
87
+ plus the negative/abuse cases (replay/double-submit, concurrent, terminal-state). -->
88
+
89
+ - **Security & Privacy:** <authz, secrets, data exposure — or N/A + reason>
90
+ - **Observability:** <logging, metrics, how you'll know it broke — or N/A + reason>
91
+ - **Testing:** <invariants to hold across all surfaces; negative/abuse cases; integration seam>
92
+ - **Rollout / Migration / Flags:** <how it ships safely; reversibility — or N/A + reason>
93
+ - **Dependencies:** <new libs/services; are they maintained/justified — or N/A>
94
+ - **Performance / Scale:** <hot paths, expected load, the ceiling — or N/A + reason>
95
+
96
+ ## Open Questions <!-- CORE -->
97
+
98
+ <!-- Unresolved decisions. Each should be answerable; an unanswered one blocks "Approved".
99
+ These map cleanly to GAP-NNN when this becomes a spec. -->
100
+
101
+ - <question needing an answer before / during build>
102
+
103
+ ## Timeline / Milestones
104
+
105
+ <!-- OPTIONAL. Phased delivery if the feature is large enough to stage. -->
106
+
107
+ ## Revisions
108
+
109
+ <!-- OPTIONAL. Material changes after first review, dated — so reviewers see what moved. -->
110
+
111
+ | Date | Change |
112
+ |---|---|
113
+ | <YYYY-MM-DD> | <what changed and why> |
@@ -0,0 +1,92 @@
1
+ # ADR-NNNN: <short noun-phrase title>
2
+
3
+ <!--
4
+ WHAT THIS IS: one architecture decision, captured immutably. An ADR is NOT a design doc
5
+ (that's DESIGN.md, per-feature, forward-looking) and NOT the system map (that's
6
+ ARCHITECTURE.md, living). It freezes ONE expensive-to-reverse choice — stack, storage,
7
+ auth transport, sync vs async, a boundary rule — with the forces that drove it.
8
+
9
+ WHEN TO WRITE ONE: a choice you'd want a future maintainer to understand the *why* of,
10
+ and that you can't cheaply undo. Trivial/reversible choices don't need an ADR.
11
+
12
+ IMMUTABILITY: once Status = accepted, never edit the Decision/Context. To change your mind,
13
+ write a NEW ADR and set this one's Status to "superseded by ADR-MMMM".
14
+
15
+ LOCATION & NAMING: docs/adr/NNNN-kebab-title.md, zero-padded sequential (0001, 0002…).
16
+ ADR-0001 is conventionally the meta-decision "Record architecture decisions". While the
17
+ project has ≤~6 decisions they may live inline in ARCHITECTURE.md §12 instead of here;
18
+ spill into docs/adr/ once they outgrow that.
19
+
20
+ TINY-DECISION SHORTCUT (Y-statement): for a small call, the whole ADR can be one line —
21
+ "In the context of <use case>, facing <concern>, we decided for <option> and neglected
22
+ <alternatives>, to achieve <benefit>, accepting that <trade-off>." Use the full form below
23
+ when the decision deserves the room.
24
+
25
+ FILL RULE: replace every <placeholder>. Keep the CORE four sections always; the others are
26
+ optional — delete a heading rather than leave it empty.
27
+ -->
28
+
29
+ - **Status:** proposed | accepted | deprecated | superseded by ADR-NNNN <!-- CORE -->
30
+ - **Date:** <YYYY-MM-DD>
31
+ - **Deciders:** <names / roles>
32
+
33
+ ## Context and Problem Statement <!-- CORE -->
34
+
35
+ <!-- The forces at play — technical, product, team, time. Value-neutral: describe the
36
+ tension, don't argue the answer yet. End with the question being decided. -->
37
+
38
+ <what's pushing on this decision, and the question it raises>
39
+
40
+ ## Decision Drivers
41
+
42
+ <!-- OPTIONAL. The criteria that actually matter for choosing — bullet them so the
43
+ Decision below is auditable against them. -->
44
+
45
+ - <driver / constraint>
46
+
47
+ ## Considered Options
48
+
49
+ <!-- OPTIONAL but recommended for non-obvious calls. List the real candidates, including
50
+ "do nothing". One line each here; details go in Pros and Cons below. -->
51
+
52
+ - <option A>
53
+ - <option B>
54
+ - <option C — e.g. do nothing>
55
+
56
+ ## Decision <!-- CORE -->
57
+
58
+ <!-- Active voice, full sentence: "We will …". State what was chosen AND what was rejected. -->
59
+
60
+ We will <chosen option>, over <rejected options>, because <the driver that broke the tie>.
61
+
62
+ ## Consequences <!-- CORE -->
63
+
64
+ <!-- ALL of them — positive, negative, and neutral. What does this commit the system to?
65
+ What new work / risk / constraint does it create? Negatives in the same list, not hidden. -->
66
+
67
+ - **Positive:** <benefit gained>
68
+ - **Negative:** <cost / new constraint / risk accepted>
69
+ - **Neutral:** <follow-on work, things now true>
70
+
71
+ ## Pros and Cons of the Options
72
+
73
+ <!-- OPTIONAL. Only when the trade-off is close enough that a reader will second-guess it.
74
+ Per option: a few good/bad points. Skip for a clear-cut decision. -->
75
+
76
+ ### <option A>
77
+ - Good: <…>
78
+ - Bad: <…>
79
+
80
+ ## Confirmation
81
+
82
+ <!-- OPTIONAL. How do we verify the decision is actually being followed in the code/build?
83
+ (a test, a lint rule, an architecture check, a review checklist item). -->
84
+
85
+ <how compliance is checked>
86
+
87
+ ## More Information / Links
88
+
89
+ <!-- OPTIONAL. The DESIGN.md this came from, related ADRs, the ARCHITECTURE.md section it
90
+ affects, tickets, external references. -->
91
+
92
+ - <links>
@@ -0,0 +1,36 @@
1
+ # Stack Profile — React (web frontend / full-stack FE)
2
+
3
+ <!--
4
+ A dated, research-VERIFIABLE starting suggestion — NOT a hard rule and NOT skill logic.
5
+ sp-scaffold MAY offer this as a default the user confirms; the Bootstrap Brief always wins,
6
+ and currency MUST be re-checked at scaffold time (versions and "best practice" move).
7
+ Override freely. Absence of a profile is fine — research the stack instead.
8
+
9
+ This file is the TEMPLATE for adding more profiles (laravel.md, fastapi.md, go-cli.md …):
10
+ keep them short, dated, opinion-as-data, with the "verify + don't over-install" cautions.
11
+
12
+ THIS IS A KIT-BUNDLED SEED. It is OVERWRITTEN on `devkit upgrade`. Do NOT hand-edit it as your
13
+ personal store — instead COPY it to `~/.claude/stack-profiles/<stack>.md` (your global defaults,
14
+ survives upgrades) or `./.claude/stack-profiles/<stack>.md` (this project). Lookup precedence:
15
+ project > user/global > this bundled seed; and the Bootstrap Brief overrides all of them.
16
+ -->
17
+
18
+ **Current as of:** 2026-06 — VERIFY each choice's currency with a web search at scaffold time before trusting it.
19
+
20
+ ## Conventions (the patterns the example module demonstrates)
21
+
22
+ - **Server state / data layer:** TanStack Query (React Query) — never keep server state in a client store.
23
+ - **Client state:** Zustand — only for genuine client-only state.
24
+ - **Validation:** Zod — schemas shared between forms and API boundaries.
25
+ - **Forms:** React Hook Form + Zod resolver.
26
+ - **UI kit:** shadcn/ui + Tailwind (or the team's kit).
27
+ - **Structure:** feature-based — `features/<name>/{components,hooks,services,types}`; `core/` for the request client + providers.
28
+ - **Tests:** per the ARCHITECTURE §4 test rule — unit co-located sibling (`.test.tsx`, one suffix repo-wide), e2e as its own package.
29
+
30
+ ## Why these
31
+
32
+ Widely adopted, composable, typed end-to-end. The scaffold's ONE example module wires a single slice through all of them — one query (React Query) → input validated by Zod → render — so every sp-build story copies an established pattern instead of improvising (this is what keeps cross-feature seams consistent).
33
+
34
+ ## Caution
35
+
36
+ **Do NOT pre-install what the skeleton doesn't exercise.** The walking skeleton demonstrates the pattern with ONE thin slice; it does not scaffold empty stores/forms/components for features that don't exist yet. Pre-built infrastructure with no consumer is orphan code.