aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-22 15:03:30 -0500
committerCraig Jennings <c@cjennings.net>2026-05-22 15:03:30 -0500
commit8bbc7937c54e251dc6640fe327665ca28c998a0a (patch)
treea41e7ea1f2b1e602f191f49755c2f77bae9effa7
parent35c32a5bbbe757e3510830a57c6a21aacacceb8b (diff)
downloadrulesets-8bbc7937c54e251dc6640fe327665ca28c998a0a.tar.gz
rulesets-8bbc7937c54e251dc6640fe327665ca28c998a0a.zip
docs(commands): strengthen arch-design security inputs and paradigm model
Two audit fixes. A new Phase 4 (Trust, Data, and Compliance) surfaces trust boundaries, data classification, abuse cases, privacy, compliance evidence, and ownership before the paradigm shortlist, so the architecture is drawn around them rather than retrofitted by a later security-check. Phase 5 now splits the choice in two: pick one paradigm (monolith, microservices, event-driven, and so on), then compose tactical patterns onto it (DDD, hexagonal, CQRS, event sourcing), with composition examples and an anti-pattern against treating a pattern as an alternative to a paradigm.
-rw-r--r--.claude/commands/arch-design.md94
1 files changed, 78 insertions, 16 deletions
diff --git a/.claude/commands/arch-design.md b/.claude/commands/arch-design.md
index 141951d..9e65723 100644
--- a/.claude/commands/arch-design.md
+++ b/.claude/commands/arch-design.md
@@ -25,13 +25,14 @@ Elicit the problem, surface the real drivers, propose a fit, and commit it to wr
## Workflow
-The skill runs in five phases. Each produces a section of the output brief. Do not skip phases — the trade-off analysis is only as good as the intake.
+The skill runs in six phases. Each produces a section of the output brief. Do not skip phases — the trade-off analysis is only as good as the intake.
1. **Intake** — elicit stakeholders, domain, scale, timeline, team
2. **Quality attributes** — prioritize (can't have everything)
3. **Constraints** — technical, organizational, legal, cost
-4. **Candidate paradigms** — shortlist 2-4 with honest trade-off analysis
-5. **Recommendation** — pick one, justify it, flag open questions for ADRs
+4. **Trust, data, and compliance** — trust boundaries, data classification, abuse cases, privacy, compliance evidence, ownership
+5. **Candidate paradigms** — shortlist 2-4 with honest trade-off analysis
+6. **Recommendation** — pick one, justify it, flag open questions for ADRs
## Phase 1 — Intake
@@ -91,40 +92,86 @@ Enumerate what's fixed. Each constraint narrows the design space — make them e
- **Timeline**: hard dates from business, regulatory deadlines
- **Compatibility**: backward-compatibility with existing clients, API contracts, data formats
-## Phase 4 — Candidate Paradigms
+## Phase 4 — Trust, Data, and Compliance
-Pick 2-4 candidates that plausibly fit the quality-attribute ranking and constraints. Analyze each honestly — include the reasons it would fail, not just succeed.
+Security is one quality attribute in Phase 2, but several security and privacy concerns shape the structure itself, not just a later hardening pass. Surface them here, before the paradigm shortlist, so the architecture is drawn around them rather than retrofitted by a downstream `security-check`. These answers feed directly into where boundaries fall, how data flows, and which paradigms stay viable.
-Common paradigms to consider:
+**Trust boundaries**
+- Where does control change hands? (public internet → edge, edge → service mesh, service → data store, tenant → tenant)
+- Which components are trusted, which are hostile-by-default, and what authenticates across each boundary?
+- What's the blast radius if any one component is compromised?
+
+**Data classification**
+- What sensitivity of data flows where? Classify it (public, internal, confidential, regulated — PII, PHI, payment, secrets).
+- Which stores and which paths carry the most sensitive class? That path constrains the design more than the average one.
+- Where does sensitive data cross a trust boundary, and what protects it there (encryption in transit/at rest, tokenization, field-level controls)?
+
+**Abuse and misuse cases**
+- Who would attack this, and to what end? (fraud, exfiltration, denial of service, account takeover, abuse of a feature for an unintended purpose)
+- For the top abuse cases, what's the architectural mitigation? (rate limiting at the edge, isolation between tenants, an audit trail that can't be tampered with)
+- These are the inverse of user stories — name the attacker's goal, then design against it.
+
+**Privacy constraints**
+- What data minimization, retention, deletion, and consent obligations apply? (right to erasure, purpose limitation, data residency)
+- Do any of these force a structural choice — separable per-user data, region-pinned stores, a deletion path that reaches every copy?
+
+**Compliance evidence**
+- What must be *provable* to an auditor, not just true? (access logs, change history, encryption attestation, data-flow records)
+- Generating that evidence is an architectural requirement — an immutable audit log or a tamper-evident event store may be load-bearing, not optional.
+
+**Operational ownership**
+- Who owns each component in production — on-call, patching, secret rotation, incident response?
+- Conway's Law applies to security too: a boundary no team owns is a boundary no one defends.
+
+Document the trust boundaries, the data classification, and the top abuse cases in the brief. They become inputs to the trade-off analysis in the next phase and seed open decisions for ADRs.
+
+## Phase 5 — Candidate Paradigms
+
+Two distinct choices live here, and conflating them is a classic mistake. First pick the **paradigm** — the top-level structural choice that decides how the system is deployed and how its pieces relate. Then layer on the **tactical patterns** that compose onto that paradigm. They are not mutually exclusive options on one menu. A modular monolith built with DDD and CQRS in one module is a coherent, common choice — not a contradiction.
+
+### Step 1 — Pick the paradigm
+
+The paradigm is a whole-system decision; you choose one. Pick 2-4 candidates that plausibly fit the quality-attribute ranking and constraints. Analyze each honestly — include the reasons it would fail, not just succeed.
| Paradigm | Fits when… | Doesn't fit when… |
|---|---|---|
| **Modular monolith** | Small team, fast iteration, strong module boundaries, single deployment OK | Independent team scaling, different availability SLAs per module, polyglot requirements |
| **Microservices** | Multiple teams, independent deploy cadences, polyglot, different scaling needs | Small team, tight transactional consistency needs, low operational maturity |
| **Layered (n-tier)** | CRUD-heavy, clear request/response, team familiar with MVC | Complex domain logic, event-driven needs, async workflows dominate |
-| **Hexagonal / Ports & Adapters** | Business logic isolation, multiple interface types (HTTP + CLI + queue), testability priority | Trivial domains, overhead outweighs benefit |
| **Event-driven / pub-sub** | Async workflows, fan-out to multiple consumers, decoupled evolution | Strong ordering + consistency needs, small team, low operational maturity |
-| **CQRS** | Read/write workload asymmetry, different optimization needs, audit trail required | Simple CRUD, no asymmetry, overhead not justified |
-| **Event sourcing** | Audit trail critical, temporal queries needed, reconstruction from events valuable | Simple state, team lacks event-sourcing expertise, storage cost prohibitive |
| **Serverless (FaaS)** | Event-driven + variable load + fast iteration + accept vendor lock-in | Steady high load, latency-sensitive, long-running processes, tight cost control |
| **Pipe-and-filter / pipeline** | Data transformation workflows, ETL, stream processing | Interactive request/response, low-latency |
| **Space-based / in-memory grid** | Extreme throughput, elastic scale, in-memory OK | Strong durability required from day one, small scale |
+
+### Step 2 — Compose tactical patterns onto it
+
+Tactical patterns refine the internal structure of a chosen paradigm, often per-module or per-service rather than system-wide. You can adopt several at once, or none. They sharpen how a part of the system is built; they don't replace the paradigm. Map each candidate paradigm to the tactical patterns worth applying inside it.
+
+| Tactical pattern | Apply when… | Skip when… |
+|---|---|---|
| **DDD (tactical)** | Complex domain, domain experts available, long-lived system | Simple CRUD, no real domain complexity, short-lived system |
+| **Hexagonal / Ports & Adapters** | Business logic isolation, multiple interface types (HTTP + CLI + queue), testability priority | Trivial domains, overhead outweighs benefit |
+| **CQRS** | Read/write workload asymmetry, different optimization needs, audit trail required | Simple CRUD, no asymmetry, overhead not justified |
+| **Event sourcing** | Audit trail critical, temporal queries needed, reconstruction from events valuable | Simple state, team lacks event-sourcing expertise, storage cost prohibitive |
+
+Examples of composition: a modular monolith with hexagonal modules and CQRS on the reporting module; microservices where two services use DDD aggregates and one uses event sourcing for its audit-critical ledger; a pipeline whose stages are hexagonal for testability. The paradigm is the frame; the tactical patterns are how you build inside it.
For each candidate, document:
- **Summary** — one paragraph on what the architecture would look like
+- **Tactical patterns** — which patterns from Step 2 compose onto it, and where (which module or service)
- **Why it fits** — map to the ranked quality attributes
- **Why it might not** — the honest cons for this specific context
- **Cost** — team learning curve, operational overhead, infra impact
- **Open questions** — what would need to be answered or decided via ADR
-## Phase 5 — Recommendation
+## Phase 6 — Recommendation
-Choose one paradigm. Justify it by:
+Choose one paradigm and name the tactical patterns that compose onto it. Justify it by:
- Which top-3 quality attributes the choice serves
- Which constraints it respects
+- How it answers the trust boundaries, data classification, and abuse cases from Phase 4
- Why the rejected alternatives were rejected (not just "we picked X"; say why *not* Y)
- What you're trading away (be explicit)
@@ -181,20 +228,31 @@ Write the final brief to `.architecture/brief.md` in the project root. Use this
- **Cost:** …
- **Timeline:** …
-## 6. Candidates Considered
+## 6. Trust, Data, and Compliance
+
+- **Trust boundaries:** … (where control changes hands; what authenticates across each)
+- **Data classification:** … (sensitivity classes and the paths/stores that carry them)
+- **Top abuse cases:** … (attacker goal → architectural mitigation)
+- **Privacy constraints:** … (minimization, retention, deletion, residency)
+- **Compliance evidence:** … (what must be provable to an auditor)
+- **Operational ownership:** … (who owns each component in production)
+
+## 7. Candidates Considered
### Candidate A — <paradigm>
-Summary. Fit. Cons. Cost. Open questions.
+Summary. Tactical patterns composed on it (and where). Fit. Cons. Cost. Open questions.
### Candidate B — <paradigm>
-## 7. Recommendation
+## 8. Recommendation
**Chosen paradigm:** …
+**Tactical patterns composed onto it:** … (e.g. DDD + CQRS in the orders module)
+
**Rationale:**
- …
@@ -204,12 +262,12 @@ Summary. Fit. Cons. Cost. Open questions.
**Rejected alternatives and why:**
- …
-## 8. Open Decisions (Candidates for ADRs)
+## 9. Open Decisions (Candidates for ADRs)
- [ ] Primary database — driver: …
- [ ] …
-## 9. Next Steps
+## 10. Next Steps
- Run `arch-decide` for each open decision above
- Run `arch-document` to produce the full arc42 document
@@ -222,7 +280,9 @@ Before marking the brief Accepted:
- [ ] Every quality attribute is ranked; no "all critical"
- [ ] Every constraint is explicit; no "we probably can't"
+- [ ] Trust boundaries, data classification, and top abuse cases are documented — not deferred to a later security pass
- [ ] At least 2 candidates considered; each has real cons
+- [ ] Recommendation names a single paradigm plus the tactical patterns composed onto it
- [ ] Recommendation names what it's trading away
- [ ] Open decisions listed; each will become an ADR via `arch-decide`
- [ ] Stakeholders have seen and (ideally) approved
@@ -232,6 +292,8 @@ Before marking the brief Accepted:
- **"All quality attributes are critical."** They aren't. Force ranking.
- **"Let's go microservices."** Without a ranking, constraints, and team context, that's cargo-culting.
- **Single candidate.** One option means the user already decided; you're documenting, not designing.
+- **Paradigm vs. pattern confusion.** Treating DDD, CQRS, or event sourcing as alternatives to a modular monolith or microservices. The paradigm is the structural frame; tactical patterns compose inside it. Pick one paradigm, then layer patterns onto it.
+- **Security deferred to later.** Treating trust boundaries, data classification, and abuse cases as a hardening pass after the design is set. They shape where boundaries fall — surface them in Phase 4, not after.
- **Silent trade-offs.** If you choose availability, you're trading latency or cost. Say so.
- **No open decisions.** A real architecture has open questions. Listing none means you haven't looked hard.
- **"Design doc" with no implementation implications.** The brief must be actionable — it drives ADRs, documentation, and evaluation.