@therocketcode/gsd-core 1.6.1 → 1.7.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gsd-core",
3
3
  "displayName": "GSD Core",
4
- "version": "1.6.1",
4
+ "version": "1.7.0",
5
5
  "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
6
6
  "author": {
7
7
  "name": "TheRocketCodeMX",
@@ -71,11 +71,13 @@ This ensures verification checks that plans follow project-specific conventions.
71
71
  | `## Decisions` | LOCKED — plans MUST implement these exactly. Flag if contradicted. |
72
72
  | `## Claude's Discretion` | Freedom areas — planner can choose approach, don't flag. |
73
73
  | `## Deferred Ideas` | Out of scope — plans must NOT include these. Flag if present. |
74
+ | `## Canonical References` | MUST-read docs (incl. any DOMAIN-MODEL.md / architecture ADR / TEST-STRATEGY.md). Read them; plans MUST follow them. |
74
75
 
75
76
  If CONTEXT.md exists, add verification dimension: **Context Compliance**
76
77
  - Do plans honor locked decisions?
77
78
  - Are deferred ideas excluded?
78
79
  - Are discretion areas handled appropriately?
80
+ - **Do plans honor the canonical discovery artifacts?** Flag a HIGH concern if a task contradicts the architecture ADR's per-subdomain rung (e.g. CRUD where a Domain Model is mandated), the DOMAIN-MODEL classification, or the TEST-STRATEGY's test levels (e.g. unit-mocking the DB where integration via Testcontainers is required, or float money where integer minor units are mandated).
79
81
  </upstream_input>
80
82
 
81
83
  <core_principle>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gsd-core",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "GSD Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads gsd's operating context into every Gemini CLI session.",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
@@ -30,10 +30,23 @@ Use the core subdomain's complexity from DOMAIN-MODEL. Apply per subdomain: the
30
30
  1. **Multiple independent teams** needing independent deploy cadence (Conway / Team Topologies).
31
31
  2. **CD / monitoring / DevOps maturity** already in place.
32
32
  3. **Bounded contexts well-understood** already (not still being discovered).
33
- If **any** is "no" → recommend **modular monolith and stop**, regardless of complexity. (The "microservice premium": below a complexity+org threshold the distributed tax is pure loss.)
33
+ If **any** is "no" → recommend **modular monolith and stop**, regardless of complexity (deferred, not forbidden — record the promotion trigger; see *Evolving the topology* below). (The "microservice premium": below a complexity+org threshold the distributed tax is pure loss.)
34
34
  - **Component-level split (Hard Parts):** for a specific component, score the **6 disintegrators** (low cohesion · divergent volatility · divergent scalability · fault isolation · differential security · independent extensibility) against the **4 integrators** (ACID across the data · tightly-coupled workflow · heavy shared code · tight data relationships). Net disintegrators ≫ integrators → candidate extraction; otherwise keep it in the monolith.
35
35
  - **Distributed monolith** (services that can't deploy independently) is the failure mode — you pay the premium and get none of the autonomy. Avoid.
36
36
 
37
+ The "modular monolith and stop, regardless of complexity" rule is about *not splitting prematurely* — it is **not** "never split." It means the split is deferred until a gate flips, and the modular boundaries are built now so the split is cheap later (a **sacrificial / evolutionary** architecture). Record the **promotion trigger** — the concrete future signal (a second team forms, a component's scaling diverges, a bounded context stabilizes) that would justify revisiting Axis B.
38
+
39
+ ## Evolving the topology — decomposition & migration (when a gate later flips)
40
+
41
+ When a promotion trigger fires and a component genuinely warrants extraction, the *data* is the hard part — splitting logic is easy, splitting a shared database is not. Recommend, in order:
42
+
43
+ - **Strangler Fig** — route new behavior to the new component while the old path keeps serving, shrinking the monolith incrementally. Never a big-bang rewrite.
44
+ - **Anti-Corruption Layer (ACL)** — a translation seam at the new boundary so the extracted component's model isn't polluted by the legacy/shared schema's vocabulary. The ACL is also the right tool when integrating a third-party/legacy system whose model differs from yours.
45
+ - **Data decomposition** — pull the component's tables behind its own schema/owner first (enforce "no cross-module DB access" as a fitness function *before* extracting), then separate the datastore. Identify the data that must move vs. the data that stays shared (and gets an API/ACL instead).
46
+ - **Sagas / outbox for cross-service consistency** — once a transaction spans two services you lose ACID; replace it with a **saga** (a sequence of local transactions + compensating actions) and the **transactional outbox** pattern for reliable event publishing. If a workflow genuinely needs one ACID transaction, that's an *integrator* — a reason to **keep it together**, not split it.
47
+
48
+ The same tools run in reverse for a brownfield monolith you're decomposing — strangle, wrap legacy in an ACL, decompose the data behind module boundaries first.
49
+
37
50
  ## Non-functional drivers (quick matrix)
38
51
 
39
52
  | Driver | Low → | High → pushes toward |
@@ -0,0 +1,62 @@
1
+ # Contract Testing — Verifying Integrations Without the Real Thing
2
+
3
+ How-to reference for testing the boundary between two services (or your app and a 3rd party) without standing up the real dependency in every test. Read when a component integrates with an external API/service you **can't run or seed in CI**. Pairs with `test-strategy.md` (its "contract tests where a 3rd-party can't be seeded" line).
4
+
5
+ ## When to use it
6
+
7
+ - A consumer depends on a provider you can't run in CI (a partner API, another team's service, a paid 3rd party).
8
+ - You want to catch "the provider changed and broke us" **without** slow, flaky end-to-end tests against the real provider.
9
+ - Microservice boundaries: each side tested independently but kept compatible.
10
+
11
+ **Not** for: pure in-process logic (unit), or a dependency you *can* run real in CI — use an integration test with Testcontainers instead (see `test-containers.md`).
12
+
13
+ ## Consumer-Driven Contracts (the dominant model — Pact-style)
14
+
15
+ The **consumer** defines what it needs from the provider as a contract (example request → expected response shape). Two halves:
16
+
17
+ 1. **Consumer test** — runs the consumer against a *mock* provider that replays the contract. Proves the consumer works given that response shape, and **publishes** the contract.
18
+ 2. **Provider verification** — the *real* provider is replayed the contract's requests and its actual responses are checked against the contract. Proves the provider still satisfies what the consumer needs.
19
+
20
+ A **broker** (Pact Broker / PactFlow) stores contracts and tracks which consumer/provider versions are compatible (`can-i-deploy`).
21
+
22
+ ```ts
23
+ // Consumer side (Pact JS) — declare the interaction, test the client against the mock
24
+ provider.addInteraction({
25
+ state: 'customer 42 exists',
26
+ uponReceiving: 'a request for customer 42',
27
+ withRequest: { method: 'GET', path: '/customers/42' },
28
+ willRespondWith: { status: 200, body: { id: 42, email: like('a@b.com') } }, // match shape, not exact value
29
+ });
30
+ // run your client against provider.mockService.baseUrl; assert it parses the response.
31
+ // → writes a pact file the provider must later verify.
32
+ ```
33
+ ```ts
34
+ // Provider side — replay the published pacts against the REAL provider
35
+ await new Verifier({
36
+ provider: 'customers-api',
37
+ pactBrokerUrl: process.env.PACT_BROKER_URL,
38
+ providerBaseUrl: 'http://localhost:8080',
39
+ stateHandlers: { 'customer 42 exists': () => seedCustomer(42) },
40
+ }).verifyProvider();
41
+ ```
42
+
43
+ ## Contract vs integration vs e2e — when each
44
+
45
+ - **Integration (Testcontainers):** the dependency you *can* run real → test against it.
46
+ - **Contract:** the dependency you *can't* run/seed → test the boundary shape on both sides independently.
47
+ - **E2E:** a few critical journeys end-to-end (slow; keep lean — see `e2e-tiering.md`).
48
+
49
+ Contract testing replaces the temptation to mock the 3rd party in an integration test and call it covered — a mock proves nothing about the *real* provider; a **verified contract** does.
50
+
51
+ ## Schema/spec-based alternative
52
+
53
+ When both sides share a spec (REST/gRPC/events) and you control them, schema-driven checks — OpenAPI/AsyncAPI validation, JSON Schema, protobuf backward-compat, Spring Cloud Contract — are a lighter alternative to full consumer-driven contracts.
54
+
55
+ ## Anti-patterns
56
+
57
+ - Mocking a 3rd party in an integration test and believing it's covered (the mock can drift from reality; a verified contract can't).
58
+ - Asserting the **full** response (brittle) — assert only the fields the consumer uses (Pact matchers: `like`, `eachLike`, `term`).
59
+ - Publishing a consumer pact but never running **provider verification** (the pact alone proves nothing about the provider).
60
+ - Using contract tests where a real integration test (Testcontainers) would be cheaper and stronger.
61
+
62
+ *Sources: pact.io (consumer-driven contracts, broker, can-i-deploy); Fowler "ContractTest" / "IntegrationContractTest"; Spring Cloud Contract; OpenAPI/AsyncAPI schema validation.*
@@ -51,7 +51,25 @@ Only when the domain is non-trivial. A **Big-Picture event storming** pass surfa
51
51
  2. For each: *who triggers it? who reacts? what decision follows?*
52
52
  3. Group events by actor/responsibility → each cluster is a candidate **bounded context**.
53
53
 
54
- Boundaries often fall where the **language changes** (the same word means different things) or where the **rate of change** differs. If boundaries are unclear, **defer** them — say so explicitly and let planning refine them. Do not run design-level (aggregate-level) event storming here; that is tactical and belongs to a core subdomain you've already identified.
54
+ Boundaries often fall where the **language changes** (the same word means different things) or where the **rate of change** differs. If boundaries are unclear, **defer** them — say so explicitly and let planning refine them.
55
+
56
+ A **Process-level** pass is the optional middle gear between Big-Picture and Design-level storming: take one important event flow (e.g., "Order → Payment → Fulfillment") and walk its commands, policies ("whenever X, then Y"), and read-models. It sharpens *one* boundary and its hand-offs without dropping to aggregates. Use it only when a single flow's boundary is genuinely contested; otherwise stay Big-Picture. Do **not** run design-level (aggregate-level) event storming here — that is tactical and belongs to a core subdomain you've already identified.
57
+
58
+ ## 4. Context mapping (only when there are ≥2 bounded contexts)
59
+
60
+ Once two contexts exist, name the **relationship** at each boundary — it dictates integration and team coupling downstream. The vocabulary (pick the one that fits; don't apply all):
61
+
62
+ | Pattern | When it applies |
63
+ |---|---|
64
+ | **Shared Kernel** | two contexts share a small agreed model; changes need both teams' consent (high coupling — keep tiny) |
65
+ | **Customer/Supplier** | downstream's needs are honored in the upstream's roadmap (upstream agrees to flex) |
66
+ | **Conformist** | downstream just accepts the upstream model as-is (no leverage to negotiate) |
67
+ | **Anticorruption Layer (ACL)** | downstream translates the upstream model at the seam to protect its own — the safe default against a messy/legacy/3rd-party upstream |
68
+ | **Open Host Service (OHS)** | upstream publishes a well-defined protocol many consumers use |
69
+ | **Published Language** | a shared, well-documented interchange format (e.g. a schema/spec) the integration speaks |
70
+ | **Separate Ways** | the cheapest answer — don't integrate at all; duplicate the little that's needed |
71
+
72
+ Capture each as `Context A —[relationship]→ Context B`. The **ACL** here is the same tool architecture uses when later extracting a service — naming it now tells planning where a translation seam belongs. Strategic only: name the relationship, don't design the translator.
55
73
 
56
74
  ## What this skill does NOT do
57
75
 
@@ -65,6 +83,8 @@ Boundaries often fall where the **language changes** (the same word means differ
65
83
  - → **`recommend-architecture`**: subdomain complexity drives the domain-logic axis (Transaction Script ↔ Domain Model ↔ Hexagonal). Core+complex ⇒ richer; supporting/generic ⇒ simple.
66
84
  - → **`testing-strategy`**: where the behavior lives drives test shape — a rich core wants more unit tests; CRUD-over-DB edges want integration tests.
67
85
 
86
+ **Anemic vs rich is an architecture decision, deferred — but flag it.** Whether the core's logic lives *in* the domain objects (rich) or in services over data-bags (anemic) is decided by `recommend-architecture`, not here. But if distillation found a genuinely complex, differentiating core, note it for downstream: a thin/anemic model over that core is the classic under-engineering tell. Just flag the expectation ("core 'X' is rich → expect a Domain Model, not a service-over-DTOs"); don't design the aggregates.
87
+
68
88
  ## When to run / when to skip
69
89
 
70
90
  **Run** after `/gsd:new-project`, before planning, when: the domain has real business rules, multiple stakeholder vocabularies, distinct business areas, or a genuine competitive core.
@@ -14,6 +14,8 @@ Reference for `/gsd:discover-product`. An **optional** front-of-funnel step that
14
14
  - **Find the narrowest wedge:** the smallest version someone would pay for this week — the hair-on-fire segment.
15
15
  - **Frame the vision as an opportunity/outcome** (it must admit >1 solution) so it informs but doesn't over-constrain architecture.
16
16
  - **Cover the four risks** (Cagan): value, usability, feasibility, viability.
17
+ - **Make outcomes measurable** (Ulwick ODI): state desired outcomes as *direction + metric + object* — "minimize the time to reconcile an invoice" — not vague goals, so "is it working?" is answerable. When real users exist, rank candidate outcomes by importance × (dis)satisfaction to find the under-served one.
18
+ - **Discovery is a loop, not a gate** (Torres): the brief is a *hypothesis to keep testing*, not a verdict. Its open assumptions feed an ongoing cadence (revisit after a handful of customer conversations), organized as an opportunity → solution → assumption tree.
17
19
 
18
20
  ## The forcing posture
19
21
 
@@ -22,10 +24,10 @@ The first answer is polished — push 2–3 times with concrete specifics, not s
22
24
  ## Distilled question set (ordered; skip any block already evidenced)
23
25
 
24
26
  0. **Frame:** what customer behavior/metric do we want to change (not a feature)? If we skipped discovery entirely, what assumption would we be betting the whole build on?
25
- 1. **Job & user:** who *specifically* — and for whom is the problem most acute, frequent, expensive, unavoidable? State the job solution-free. Job story: *"When [situation], I want to [motivation], so I can [outcome]."*
27
+ 1. **Job & user:** who *specifically* — and for whom is the problem most acute, frequent, expensive, unavoidable? State the job solution-free. Job story: *"When [situation], I want to [motivation], so I can [outcome]."* Capture 2–3 **measurable desired-outcome statements** for the job (direction + metric + object, e.g. "reduce the time to find an open class slot") — these are what "better" is measured against. Note if the job-population is heterogeneous (different segments → different outcomes; don't average them away).
26
28
  2. **Demand vs interest:** "Tell me about the *last time* you hit this." "What are you doing about it *today*?" "What does that workaround cost (time/money)?" "What *real* evidence exists — pre-pay, LOI, pilot, converted signups?" (Never "would you use X?")
27
29
  3. **Wedge & under-served outcome:** which single opportunity, solved, most moves the outcome? The narrowest version that fully solves it for one user? Can we imagine >1 solution? (If no — we smuggled in a solution; re-frame.)
28
- 4. **Four risks** (only the unvalidated ones): **value** (evidence they'll choose this over the status quo), **usability** (where they'll get stuck), **feasibility** (riskiest technical unknown), **viability** (pricing/legal/sales/brand). For the least-validated risk, the *cheapest assumption test* before building.
30
+ 4. **Four risks** (only the unvalidated ones): **value** (evidence they'll choose this over the status quo), **usability** (where they'll get stuck), **feasibility** (riskiest technical unknown), **viability** (pricing/legal/sales/brand). First **enumerate the leap-of-faith assumptions** behind the chosen wedge (what must be true for it to work); then run the *cheapest test on the riskiest* one — not just a single test on the least-validated risk.
29
31
  5. **Scope & prioritization:** end-to-end journey → the thin first slice (walking skeleton). RICE on the candidate list — Reach × Impact × Confidence ÷ Effort; table-stakes/dependencies legitimately override the score.
30
32
  6. **Success:** how will we know it worked (the outcome metric, by when)? What would make ≥40% of target users "very disappointed" to lose it? (Sean Ellis PMF proxy — necessary, not sufficient; survey only users who used the core.)
31
33
 
@@ -38,7 +40,7 @@ The first answer is polished — push 2–3 times with concrete specifics, not s
38
40
  ## Handoff
39
41
 
40
42
  - Produces `PRODUCT-BRIEF.md`: outcome statement, target user + wedge, demand evidence, job story, four-risks status, prioritized scope, explicit "not in scope."
41
- - Feeds `PROJECT.md` (vision / JTBD / persona / metrics) and `model-domain` (the job + journey → domain events and subdomains). Per Patton this is collaborative co-work, not a serial handoff keep the vision at the outcome level so the domain and architecture stay open.
43
+ - Feeds `PROJECT.md` (vision / JTBD / persona / metrics) and `model-domain` (the job + journey → domain events and subdomains). Discovery is collaborative, *continuous* work (Torres) — not a serial handoff or a one-time gate; keep the vision at the outcome level so the domain and architecture stay open. (Slicing the journey into releases downstream is **story mapping** — Patton.)
42
44
 
43
45
  ## Anti-patterns
44
46
 
@@ -64,6 +64,7 @@ When the strategy calls for real-dependency integration tests, auth, or e2e, loa
64
64
  - `@~/.claude/gsd-core/references/auth-in-tests.md` — authenticate-once/storageState, token minting, multi-role, JWT vs cookie, one-account-per-worker.
65
65
  - `@~/.claude/gsd-core/references/realistic-test-data.md` — synthetic factories by default; anonymized/subset dumps only.
66
66
  - `@~/.claude/gsd-core/references/e2e-tiering.md` — persistent smoke vs transient e2e; keep e2e lean.
67
+ - `@~/.claude/gsd-core/references/contract-testing.md` — for an external dependency you can't run/seed in CI: consumer-driven contracts + provider verification (a verified contract, not a mock).
67
68
  - `@~/.claude/gsd-core/references/flaky-test-checklist.md` — fixed clock, seeded RNG, poll-don't-sleep, per-worker isolation.
68
69
 
69
70
  ## Anti-patterns
@@ -40,9 +40,14 @@ Strategic classification — drives where to invest and (downstream) the archite
40
40
  |---------|----------------------|-------------------|----------|-------------------|
41
41
  | [Name] | [What it's responsible for] | [Events] | [Other contexts] | [Where its terms differ] |
42
42
 
43
- **Context map (optional):**
43
+ **Context map (relationships — only with ≥2 contexts):** name each boundary's relationship (Shared Kernel / Customer-Supplier / Conformist / ACL / Open Host Service / Published Language / Separate Ways). Default to an ACL against a messy/legacy/3rd-party upstream. Relationship only — no translator design.
44
+
45
+ | From | Relationship | To | Note |
46
+ |------|-------------|----|------|
47
+ | [Context A] | [ACL / OHS / Shared Kernel / …] | [Context B] | [why this relationship] |
48
+
44
49
  ```
45
- [ASCII sketch of context relationships, if useful]
50
+ [Optional ASCII sketch of the context map]
46
51
  ```
47
52
 
48
53
  ## Notes for downstream phases
@@ -1,12 +1,20 @@
1
1
  # Product Brief — [PROJECT_TITLE]
2
2
 
3
3
  **Created:** [DATE] via `/gsd:discover-product`
4
- **Scope:** Product definition (what/why) — feeds `PROJECT.md` and `/gsd:model-domain`. Outcome-framed so the domain and architecture stay open.
4
+ **Scope:** Product definition (what/why) — feeds `PROJECT.md` and `/gsd:model-domain`. Outcome-framed so the domain and architecture stay open. **This brief is a hypothesis, not a verdict** — its open assumptions feed an ongoing discovery cadence (Torres), not a one-time gate.
5
5
 
6
6
  ## Outcome (not output)
7
7
 
8
8
  [The customer behavior or business metric we want to change — not a feature. e.g., "Shippers get a priced, matched carrier in seconds instead of days."]
9
9
 
10
+ ## Desired outcomes (measurable — Ulwick ODI)
11
+
12
+ State 2–3 as *direction + metric + object* so "is it working?" is answerable. If the population is heterogeneous, list per-segment — don't average them away.
13
+
14
+ | Desired outcome (direction + metric + object) | For which segment | Under-served? (importance × dissatisfaction) |
15
+ |---|---|---|
16
+ | [e.g., "minimize the time to reconcile an invoice"] | [segment] | [high / unknown] |
17
+
10
18
  ## Target user & job
11
19
 
12
20
  - **Specific user:** [the actual human/role for whom this is most acute/frequent/expensive]
@@ -49,7 +57,14 @@
49
57
  ## Handoff notes
50
58
 
51
59
  - **For `model-domain`:** [the job + journey steps and the key domain nouns/events to model]
52
- - **Open questions / assumptions to test next:** [...]
60
+
61
+ ## Assumptions to re-test (leap-of-faith)
62
+
63
+ The brief is a hypothesis. List the assumptions that must hold for the wedge to work, riskiest first, each with the cheapest next test — revisit after a handful of customer conversations (continuous discovery, not a gate).
64
+
65
+ | Leap-of-faith assumption | Riskiest? | Cheapest next test |
66
+ |---|---|---|
67
+ | [what must be true] | [yes / no] | [the test] |
53
68
 
54
69
  ---
55
70
  *Product brief. Next: `/gsd:new-project` (if not done) → `/gsd:model-domain` → `/gsd:recommend-architecture`.*
@@ -52,16 +52,16 @@ Write a minimal PRODUCT-BRIEF.md (outcome + the prioritized list + "discovery sk
52
52
  Run the ordered question set from the reference. **Posture: the first answer is polished — push 2–3 times for concrete specifics (the actual human, the actual consequence), reflect back, confirm. One thread at a time.** Ask about the PAST, never hypotheticals. Skip any block already evidenced.
53
53
 
54
54
  - **Step 3 — Frame (outcome):** "What customer behavior or metric do we want to change — not a feature?" "If we skipped discovery, what assumption would we be betting the whole build on?"
55
- - **Step 4 — Job & user:** "Who *specifically* — and for whom is this most acute, frequent, expensive, unavoidable?" Capture the solution-free job and a job story ("When … I want to … so I can …"). If after 2–3 pushes the user still can't name a specific acute role (answers "everyone"/"all X"), do NOT record a generic user — record the target user as **UNRESOLVED** and make "identify the acute user" the first open question. A non-specific user is a discovery red flag, not a finding.
55
+ - **Step 4 — Job & user:** "Who *specifically* — and for whom is this most acute, frequent, expensive, unavoidable?" Capture the solution-free job and a job story ("When … I want to … so I can …"). Then capture **2–3 measurable desired outcomes** for the job as *direction + metric + object* ("reduce the time to find an open class slot") — these are what "better" is measured against later. If the job-population is heterogeneous, capture outcomes **per segment** (different segments want different things — don't average them away). If after 2–3 pushes the user still can't name a specific acute role (answers "everyone"/"all X"), do NOT record a generic user — record the target user as **UNRESOLVED** and make "identify the acute user" the first open question. A non-specific user is a discovery red flag, not a finding.
56
56
  - **Step 5 — Demand vs interest:** "Tell me about the *last time* you hit this." "What are you doing about it *today*, and what does it cost?" "What *real* evidence exists — pre-pay, LOI, pilot, converted signups?" Mark each signal strong (behavior/money) vs weak (interest). **Never** ask hypotheticals — neither "would you use X?" nor "would you pay $Y?"; redirect any "they'd pay $Y" answer to "tell me about the last time someone actually paid for a workaround."
57
57
  - **Step 6 — Wedge:** "Which single opportunity, solved, most moves the outcome? What's the narrowest version that fully solves it for one user this week?" Check: can we imagine >1 solution? (If no, we smuggled in a solution — re-frame.)
58
- - **Step 7 — Four risks** (only the unvalidated): value / usability / feasibility / viability. For the least-validated, the cheapest assumption test before building. Do not rely on the user's self-rating — if a risk is dismissed without evidence ("it's fine," "AI can do it"), treat it as **open**. Independently name any obvious risk the user omitted (e.g., legal/consent, data privacy, platform dependency) and mark it open with a test.
58
+ - **Step 7 — Four risks** (only the unvalidated): value / usability / feasibility / viability. First **enumerate the leap-of-faith assumptions** behind the chosen wedge (what must be true for it to work), order them by risk, and run the *cheapest test on the riskiest* — not just one test on the least-validated risk. Do not rely on the user's self-rating — if a risk is dismissed without evidence ("it's fine," "AI can do it"), treat it as **open**. Independently name any obvious risk the user omitted (e.g., legal/consent, data privacy, platform dependency) and mark it open with a test. Record the surviving assumptions in the brief's "Assumptions to re-test" table — the brief is a hypothesis to keep testing, not a verdict.
59
59
  - **Step 8 — Scope & prioritization:** the end-to-end journey → the thin first slice; RICE the candidate list; record explicit "not in scope."
60
60
  - **Step 9 — Success:** the **outcome metric** (a change in customer behavior or business result) + by when; the PMF check (what would make ≥40% of core users "very disappointed"). **Reject vanity/output metrics — signups, waitlist size, downloads, page views, "launched" — and push to the behavior/result they proxy for (retained paying users, task completion, % of the target behavior achieved). A user-count is an output unless tied to retained value.**
61
61
 
62
62
  ## Step 10: Write PRODUCT-BRIEF.md
63
63
 
64
- Render `@~/.claude/gsd-core/templates/product-brief.md` (fill `[DATE]` with today's date, `[PROJECT_TITLE]` from PROJECT.md or — if none exists — a short **outcome-level** working title that does NOT encode the solution, marked "(working title)"). Keep the outcome at the behavior/metric level — **do not encode a solution or architecture**. Fill the Handoff notes for `model-domain` (the job + journey + key domain nouns).
64
+ Render `@~/.claude/gsd-core/templates/product-brief.md` (fill `[DATE]` with today's date, `[PROJECT_TITLE]` from PROJECT.md or — if none exists — a short **outcome-level** working title that does NOT encode the solution, marked "(working title)"). Keep the outcome at the behavior/metric level — **do not encode a solution or architecture**. Fill the **measurable desired-outcomes** table (per segment if heterogeneous), the **Assumptions to re-test** table (riskiest first, each with its cheapest next test), and the Handoff notes for `model-domain` (the job + journey + key domain nouns).
65
65
 
66
66
  Write to `.planning/PRODUCT-BRIEF.md`.
67
67
 
@@ -32,6 +32,7 @@ Exit.
32
32
  ## Step 2: Load context (internal grounding — do not show the user yet)
33
33
 
34
34
  ```bash
35
+ cat .planning/PRODUCT-BRIEF.md 2>/dev/null || true
35
36
  cat .planning/PROJECT.md 2>/dev/null || true
36
37
  cat .planning/REQUIREMENTS.md 2>/dev/null || true
37
38
  cat .planning/ROADMAP.md 2>/dev/null || true
@@ -107,6 +108,10 @@ If set, run a **Big-Picture** pass (timeline of events, not aggregates):
107
108
  3. Group events by actor/responsibility. Each cluster = a candidate bounded context. Boundaries fall where the **language changes** or the **rate of change** differs.
108
109
  4. If boundaries are unclear, say so and **defer** them. Do NOT drill into aggregates (that's tactical, out of scope here).
109
110
 
111
+ **Context mapping (only if you end with ≥2 contexts):** for each boundary, name the *relationship* using the reference's vocabulary (Shared Kernel / Customer-Supplier / Conformist / **ACL** / Open Host Service / Published Language / Separate Ways) and record it as `Context A —[relationship]→ Context B`. Default to an **ACL** at any seam against a messy, legacy, or third-party upstream. Name the relationship only — do not design the translator (that's tactical/architecture).
112
+
113
+ **Process-level pass (optional, only for one genuinely contested boundary):** walk a single flow's commands → policies ("whenever X, then Y") → read-models to sharpen that one boundary and its hand-offs. Don't drop to aggregates. Skip entirely if Big-Picture already settled the boundaries.
114
+
110
115
  ## Step 6: Write DOMAIN-MODEL.md
111
116
 
112
117
  Render `@~/.claude/gsd-core/templates/domain-model.md` (fill `[DATE]` with today's date and `[PROJECT_TITLE]` from PROJECT.md), filling:
@@ -335,6 +335,8 @@ If spike/sketch findings skills exist, read their SKILL.md files to inform the q
335
335
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
336
336
  ```
337
337
 
338
+ **If `.planning/PRODUCT-BRIEF.md` exists, read it first.** It is a validated product definition from `/gsd:discover-product` (outcome, target user, narrowest wedge, demand evidence, four-risks status, prioritized scope, explicit "not in scope"). Ground the questioning in it — **confirm and fill gaps rather than re-asking what it already answers** — and carry its outcome, wedge, and prioritized scope into PROJECT.md (Core Value / What This Is) and the requirements (Steps 4 and 7). Frame PROJECT.md around the brief's *outcome*, not a re-derived feature list.
339
+
338
340
  **Open the conversation:**
339
341
 
340
342
  Ask inline (freeform, NOT AskUserQuestion):
@@ -72,6 +72,8 @@ If **any** is "no" → **Modular Monolith. Say so and stop here on Axis B** (not
72
72
 
73
73
  If all three pass, OR a single component looks special, run the **Hard-Parts scan** on that component: score the 6 disintegrators (low cohesion · divergent volatility · divergent scaling · fault isolation · differential security · independent extensibility) vs the 4 integrators (ACID across data · tight workflow · shared code · tight data relationships). Net disintegrators ≫ integrators → extract it; otherwise keep it modular. Warn explicitly against a **distributed monolith** (services that can't deploy independently).
74
74
 
75
+ When recommending the monolith (a gate failed), **record the promotion trigger** — the concrete future signal that would justify revisiting Axis B (a second team forms, a component's scaling diverges, a bounded context stabilizes). The monolith is **sacrificial/evolutionary**, not permanent: note that the eventual split, if it comes, uses **Strangler Fig + an Anti-Corruption Layer + data-decomposition-behind-module-boundaries-first (+ sagas/outbox for cross-service consistency)** — never a big-bang rewrite. Enforcing "no cross-module DB access" as a fitness function now is what makes that future split cheap. (See *Evolving the topology* in the reference.)
76
+
75
77
  ## Step 5: Over-/under-engineering check (the meta-tell)
76
78
 
77
79
  Run this check in **both directions** — it is a first-class gate, not a formality:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@therocketcode/gsd-core",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
4
4
  "description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
5
5
  "bin": {
6
6
  "gsd-core": "bin/install.js",