| name | architecture-design |
| description | [Architecture] Use when designing solution architecture across backend, frontend, data & consistency, integration & APIs, deployment, monitoring, testing, and code quality. Architecture laws, style-selection triggers, coupling taxonomy, trade-off tables and the anti-pattern catalog live in `.claude/docs/architecture-knowledge.md`. |
Codex compatibility note:
- Invoke repository skills with
$skill-name in Codex; this mirrored copy rewrites legacy Claude /skill-name references.
- Task tracker mandate: BEFORE executing any workflow or skill step, create/update task tracking for all steps and keep it synchronized as progress changes.
- User-question prompts mean to ask the user directly in Codex.
- Ignore Claude-specific mode-switch instructions when they appear.
- Strict execution contract: when a user explicitly invokes a skill, execute that skill protocol as written.
- Subagent authorization: when a skill is user-invoked or AI-detected and its protocol requires subagents, that skill activation authorizes use of the required
spawn_agent subagent(s) for that task.
- Do not skip, reorder, or merge protocol steps unless the user explicitly approves the deviation first.
- For workflow skills, execute each listed child-skill step explicitly and report step-by-step evidence.
- If a required step/tool cannot run in this environment, stop and ask the user before adapting.
Codex Project-Reference Loading (No Hooks)
Codex uses static project-reference loading instead of runtime-injected project docs.
When coding, planning, debugging, testing, or reviewing, open project docs explicitly using this routing.
Always read:
docs/project-config.json (project-specific paths, commands, modules, and workflow/test settings)
docs/project-reference/docs-index-reference.md (routes to the full docs/project-reference/* catalog)
docs/project-reference/lessons.md (always-on guardrails and anti-patterns)
Missing/stale context route: If docs/project-config.json, the docs index, lessons.md, CLAUDE.md, AGENTS.md, or any task-required reference doc is missing or stale, auto-run $project-init or the narrow setup route ($project-config, $docs-init, $scan-all, $scan --target=<key>, $claude-md-init) before ordinary project-specific work. If Codex mirrors or AGENTS.md are missing/stale, ask the user to run $sync-codex; do not auto-run it.
Situation-based docs:
- Project structure/architecture/tech-stack/deployment/setup (any layer — backend, frontend, or infra):
project-structure-reference.md
- Backend/CQRS/API/domain/entity changes:
backend-patterns-reference.md, domain-entities-reference.md
- Frontend/UI/styling/design-system:
frontend-patterns-reference.md, scss-styling-guide.md, design-system/README.md
- Spec authoring,
docs/specs/ pathing, or TC format: feature-spec-reference.md, spec-system-reference.md, spec-principles.md
- Behavior/public-contract changes or spec-test-code sync:
workflow-spec-test-code-cycle-reference.md plus the spec docs above
- Derived spec indexes/ERDs/reimplementation guides:
spec-system-reference.md and source Feature Specs under docs/specs/
- Integration test implementation/review:
integration-test-reference.md
- E2E test implementation/review:
e2e-test-reference.md
- Code review/audit work:
code-review-rules.md plus domain docs above based on changed files
Do not read all docs blindly. Start from docs-index-reference.md, then open only relevant files for the task.
[BLOCKING] Execute skill steps in declared order. NEVER skip, reorder, or merge steps without explicit user approval.
[BLOCKING] Before each step or sub-skill call, update task tracking: set in_progress when step starts, set completed when step ends.
[BLOCKING] Every completed/skipped step MUST include brief evidence or explicit skip reason.
[BLOCKING] If Task tools are unavailable, create and maintain an equivalent step-by-step plan tracker with the same status transitions.
Quick Summary
Goal: As solution architect, deliver a complete, evidence-backed, user-validated architecture decision report covering ALL concerns (backend, frontend, design patterns, library ecosystem, testing, CI/CD, deployment, monitoring, code quality, dependency management) — every concern researched with 3+ options, every recommendation carrying confidence % + cited evidence, every decision user-confirmed — so implementation proceeds on sound, owned architectural choices.
Summary:
- Decide mode FIRST (Step 1): greenfield researches every concern from scratch; brownfield reads reference docs + accepted ADRs, constrains research to existing stack — NEVER re-litigate a settled ADR-recorded decision without superseding-ADR rationale.
- Rank every decision by REVERSIBILITY first (Step 2): one-way door (data model, tenancy, consistency model, service boundaries, public contracts, sync-vs-async) → ADR + user validation MANDATORY; two-way door → decide and move. — why: architecture IS the set of decisions expensive to reverse; treating a one-way door as reversible is the costliest error this skill can make.
- Drive style choice with NUMBERS, not adjectives: quantify Step-2 quality-attribute scenarios (latency p95/p99, throughput, SLO, RPO/RTO, data growth, concurrency); pick ≤3 DRIVING attributes and name which ones you SACRIFICE; any unknown target becomes explicit
Unresolved question, never a silent guess.
- Simplicity is the default; complexity must be BOUGHT with a measured requirement — modulith-first, distribute only against a named + measured extraction trigger (Step 3A). Reason FROM
.claude/docs/architecture-knowledge.md (laws, coupling taxonomy, style triggers, trade-off + anti-pattern catalogs) — never from familiarity or fashion.
- Every concern needs 3+ researched options with cited evidence (stars, last release, downloads, CVE scan) + confidence % — familiarity alone never sufficient grounds for a recommendation.
- Interrogate before deciding, DESIGN IT TWICE, then self-audit: run the 15-question pre-decision script (§20.1) on every one-way door (Step 2-2) · produce ≥2 MATERIALLY different candidates per one-way door before choosing (Step 3A) · run the 11 thinking red flags (§20.3) against your own draft before emitting. Prescribe the TACTIC (§2), never the product. — why: a first-idea design with no rejected alternative and no named falsifier is a belief, not a decision.
- Produce the two binding downstream contracts or the chain breaks: emit an ADR per hard-to-reverse decision (
architecture-review Cat 9 enforces) and the Scaffold Handoff tool-choices table (scaffold/harness-setup consume), then run the MANDATORY Step-12 user-validation interview before confirming.
- Main steps/tasks (run in order, track each): 1 Load Context (+pick greenfield/brownfield mode) → 2 Derive Architecture Requirements (+reversibility ranking, ≤3 driving attributes, 6-part quality-attribute scenarios, 2-2 pre-decision interrogation, user-validate) → 3A Backend Styles (selection procedure incl. DESIGN IT TWICE + extraction triggers) → 3B Backend Design Patterns → 3C Data & Consistency Architecture (store per access pattern, one writer per dataset, consistency model + staleness budget, transaction/aggregate boundary, tenancy, keys/partitioning, migrations, retention) → 3D Integration & API Architecture (sync-vs-async, API style, versioning, contract tests, outbox, idempotency, event granularity) → 4 Frontend Architecture (styles + patterns) → 4B UI System Architecture (styling/tokens/components/responsive, user-validate; skip if backend-only) → 5 Library Ecosystem Research (3 options/concern) → 6 Testing Architecture → 7 CI/CD & Deployment (+expand–contract migrations, backward AND forward compat) → 8 Observability & Monitoring → 9 Code Quality + Scaffold Handoff table → 10 Dependency Risk Assessment → 11 Generate Report + emit ADRs → 12 User Validation Interview (8-12 questions, mark
confirmed) → Next Steps + always-offer council escalation. — why: AI keeps forgetting the skill's own steps; this is the recovery anchor.
Workflow (12 steps):
- Load Context — Read domain model, tech stack, business evaluation, refined PBI
- Derive Architecture Requirements — Rank by reversibility, pick ≤3 driving quality attributes, quantify 6-part scenarios, run the 2-2 pre-decision interrogation on every one-way door
- Backend Architecture — 3A styles (selection procedure) · 3B design patterns · 3C data & consistency · 3D integration & APIs
- Frontend Architecture — Research top 3 frontend architecture styles + design patterns
- Library Ecosystem Research — Best-practice libraries per concern (validation, caching, logging, utils, etc.)
- Testing Architecture — Unit, integration, E2E, performance testing frameworks + strategy
- CI/CD & Deployment — Pipeline design, containerization, orchestration, IaC
- Observability & Monitoring — Logging, metrics, tracing, alerting stack
- Code Quality & Clean Code — Linters, analyzers, formatters, enforcement tooling
- Dependency Risk Assessment — Package health, obsolescence risk, maintenance cost
- Generate Report — Full architecture decision report with all recommendations
- User Validation — Present findings, ask 8-12 questions, confirm all decisions
Key Rules:
- MANDATORY IMPORTANT MUST ATTENTION research minimum 3 options per architecture concern with web evidence
- MANDATORY IMPORTANT MUST ATTENTION include confidence % with evidence for every recommendation
- MANDATORY IMPORTANT MUST ATTENTION run user validation interview at end (never skip)
- Delegate to
solution-architect agent for complex architecture decisions
- All claims must cite sources (URL, benchmark, case study, or codebase evidence)
- Base every recommendation on evidence, never on familiarity alone
Be skeptical. Apply critical thinking, sequential thinking. Every claim needs traced proof, confidence percentages (Idea should be more than 80%).
Inputs & Handoffs (consume vs produce)
Skill sits mid-workflow — consumes settled upstream decisions, produces artifacts downstream steps build on. Do NOT re-derive what upstream step already owns; do NOT leave downstream consumer without its needed artifact. — why: re-deriving settled decisions wastes effort and risks divergence from the recorded choice.
| Consumes (read, don't re-derive) | From | Produces (named deliverable) | Consumed by |
|---|
| Bounded contexts, aggregates, domain events, ERD | domain-analysis | Architecture decision report ({plan-dir}/research/...) | plan, plan-execute |
| Confirmed languages/frameworks/databases | tech-stack-research | Confirmed decisions ({plan-dir}/phase-02b-architecture.md) | plan, scaffold |
| Expected scale, compliance, budget constraints | business-evaluation | Scaffold Handoff table (tooling + fitness rules) | scaffold, harness-setup |
| Existing stack/patterns/ADRs (brownfield) | reference docs, docs/adr/** | ADRs for hard-to-reverse decisions (docs/adr/) | architecture-review (conformance) |
If upstream artifact missing, capture minimum needed here and note gap — NEVER silently re-run full upstream analysis. — why: a silent re-run hides the missing-input gap that the owning step should resolve.
Step 1: Load Context
Mode (decide first): Greenfield (new project, e.g. via workflow-greenfield-init) → research every concern from scratch, full 3-options-per-concern. Brownfield (large feature in existing codebase, e.g. workflow-big-feature) → FIRST read project reference docs + accepted ADRs, constrain research to existing stack/patterns, propose changes only where new requirement genuinely outgrows them — NEVER re-litigate settled ADR-recorded decision without superseding-ADR rationale. — why: re-deciding a recorded choice churns the codebase and breaks downstream conformance checks.
Read artifacts from prior workflow steps (search plans/ and team-artifacts/):
- Domain model / ERD (complexity, bounded contexts, aggregate count)
- Tech stack decisions (confirmed languages, frameworks, databases)
- Business evaluation (scale, constraints, compliance)
- Refined PBI (scope, acceptance criteria)
- Discovery interview (team skills, experience level)
Extract, summarize:
| Signal | Value | Source |
|---|
| Bounded contexts | ... | domain model |
| Aggregate count | ... | domain model |
| Cross-context events | ... | domain model |
| Confirmed tech stack | ... | tech stack phase |
| Expected scale | ... | business eval |
| Team architecture exp. | ... | discovery |
| Compliance requirements | ... | business eval |
| Real-time needs | Yes/No | refined PBI |
| Integration complexity | Low/Med/High | domain model |
| Deployment target | ... | business eval |
Step 2: Derive Architecture Requirements
Reason FROM the knowledge body, not from memory. .claude/docs/architecture-knowledge.md is AUTHORITATIVE for architecture laws (CAP/PACELC, Conway, Amdahl, USL, Little, Gall, Hyrum, Parnas), the coupling taxonomy + four coupling dimensions, style-selection triggers, the trade-off cheat sheet, and the ~100-entry anti-pattern catalog. Read the sections relevant to this design before recommending. Honor the catalog's provenance markers in §3/§8/§9/§10 — a row (or section banner) marked — VERIFY is an UNVERIFIED assertion, so cite it as a hypothesis to check against the named source where one is named (a [model-knowledge] row names none — check the project's own docs or a primary source instead), NEVER as settled fact in a recommendation. The project's own reference docs and accepted ADRs OUTRANK that catalog on any conflict — the catalog supplies universal reasoning, the project supplies binding convention. — why: universal names hardcoded as project rules rot against real repos.
2-0: Rank every decision by REVERSIBILITY (do this FIRST)
Architecture = the set of decisions expensive to reverse; everything cheap to reverse is design — leave it to implementers. Classify each decision BEFORE researching it, because the classification sets how much rigour it earns.
| Class | Meaning | Required treatment |
|---|
| One-way door | Reversal costs a migration, a rewrite, or a breaking change to consumers | ADR (Step 11) + user validation (Step 12) MANDATORY — research 3+ options, name the rejected alternative AND the measurable revisit trigger |
| Two-way door | Reversal is a refactor inside one module | Decide, record one line, move on — NEVER burn a validation question on it |
One-way doors (assume MANDATORY ADR unless proven otherwise): data model + primary-key strategy · tenancy model · consistency model per read path · sync-vs-async at a boundary · public API/event contract · service boundary lines · cloud-primitive lock-in · auth/identity model · data residency + retention.
MANDATORY IMPORTANT MUST ATTENTION never treat a one-way door as a two-way door to save a step — why: an unreviewed irreversible decision is the single most expensive failure mode of this skill, and it surfaces months later as a migration.
Map signals to architecture constraints:
| Signal | Architecture Requirement | Priority |
|---|
| Many bounded contexts | Clear module boundaries, context isolation | Must |
| High scale | Horizontal scaling, stateless services, caching strategy | Must |
| Complex domain | Rich domain model, separation of domain from infra | Must |
| Cross-context events | Event-driven communication, eventual consistency | Must |
| Small team | Low ceremony, fewer layers, convention over configuration | Should |
| Compliance | Audit trail, immutable events, access control layers | Must |
| Real-time | Event sourcing or pub/sub, WebSocket/SSE support | Should |
| High integration complexity | Anti-corruption layers, adapter pattern, API gateway | Should |
Quality-Attribute Scenarios (quantify — these drive the style choice)
Qualitative "Must/Should" cannot decide, e.g., modular monolith vs microservices. Capture measurable targets; ask user for any unknown by asking the user directly (guess acceptable only when labelled an assumption with confidence %). These targets become ADR-recorded budgets architecture-review Category 9 later checks changes against. — why: a style chosen without numbers is a guess, not an enforceable decision.
| Quality attribute | Scenario (stimulus → measurable response) | Target (fill in) |
|---|
| Latency | p95 / p99 response time for the hottest read and write paths | e.g. p99 < 300ms |
| Throughput | Sustained req/s and peak burst the system must absorb | e.g. 500 rps peak |
| Availability / SLO | Target uptime and error budget | e.g. 99.9% |
| Data durability (RPO) | Max acceptable data loss on failure | e.g. ≤ 5 min |
| Recovery (RTO) | Max acceptable time to restore service | e.g. ≤ 30 min |
| Data-volume growth | Row/document/event growth → storage, index, partition strategy | e.g. 10M rows/yr |
| Concurrency | Concurrent users/sessions and contention hot spots | e.g. 2k concurrent |
| Compliance/retention | Regulated data, retention window, residency, audit | e.g. GDPR, 7yr |
| Cost unit economics | $/request, $/tenant, $/MAU — and whether unit cost RISES with scale | e.g. <$0.002/req |
Scenario template — all SIX parts, none optional: [SOURCE: who/what triggers] [STIMULUS: the event] on [ARTIFACT: which component] under [ENVIRONMENT: the conditions] SHALL produce [RESPONSE] within [MEASURE: threshold + instrument]. "Must be scalable" decides nothing; "5,000 concurrent checkout sessions at 400 rps SHALL complete p99 < 800 ms, ≤0.1% errors, verified by the CI k6 profile" selects a structure.
MUST ATTENTION a scenario missing SOURCE or ARTIFACT is untestable — you cannot write a fitness function for "the system" under "load", so name the actor and the component. — why: an unattributed scenario gets no owner, no test and no budget, so it is never verified and silently degrades.
Rule: any target left unknown is explicit Unresolved question (Step 11), NEVER a silent omission — an architecture chosen without scale numbers is a guess, not a decision.
Move each attribute with a TACTIC, not a product. Once a target is unmet or at risk, select the mechanism from the tactics inventory in .claude/docs/architecture-knowledge.md §2 (availability · performance · modifiability · security · testability · usability) — "bulkhead a pool per dependency" is a design decision; "add Kubernetes" is a shopping list. — why: the tactic is portable across stacks and makes the trade-off legible, the product imports costs nobody asked for.
2-1: Pick ≤3 DRIVING attributes — and name what you SACRIFICE
Quality attributes CONFLICT, and that conflict IS the architecture: consistency↔availability · latency↔durability · flexibility↔simplicity · security↔usability · cost↔redundancy · performance↔modifiability.
MANDATORY IMPORTANT MUST ATTENTION name at most 3 DRIVING attributes and explicitly record which attributes are being SACRIFICED to buy them — a design claiming to maximize everything has decided nothing — why: unnamed sacrifices resurface as production surprises nobody agreed to.
| Field | Record |
|---|
| Driving attributes (≤3) | ... + the quantified target for each (from the table above) |
| Explicitly sacrificed | ... + the acceptable degradation, e.g. "search may lag ≤5 s" |
| Trade-off purchased | Use the "buy this / pay with this" table in .claude/docs/architecture-knowledge.md §19 — state cost, never just benefit |
Availability arithmetic (compute it, never assert it): dependencies in a request path MULTIPLY — five 99.9% deps ⇒ ~99.5% (≈43 h/yr down). Redundancy in PARALLEL adds 9s only when failure modes are genuinely independent; shared config, control plane, DNS and the deploy pipeline are the usual hidden serial term. Ladder: 99% = 3.65 d/yr · 99.9% = 8.77 h · 99.95% = 4.38 h · 99.99% = 52.6 min · 99.999% = 5.26 min.
Cost is a quality attribute, not a later phase. Model unit economics now — an architecture whose UNIT cost RISES with scale fails eventually regardless of elegance. Biggest web-system drivers: egress + cross-AZ/cross-region traffic · idle over-provisioned compute · unbounded log/metric/trace retention and cardinality · per-request managed-service pricing at steady high volume · always-on non-prod. Serverless vs always-on inverts with utilization — model it, don't assume it.
MANDATORY IMPORTANT MUST ATTENTION validate derived requirements with user by asking the user directly before proceeding.
2-2: Pre-Decision Interrogation (MANDATORY for every one-way door from 2-0)
Answer the 15-question pre-decision script in .claude/docs/architecture-knowledge.md §20.1 for each one-way door BEFORE researching options. Record answers in the Step 11 report; any question answered "unknown" becomes an Unresolved question, never a silent gap.
The five that most often expose a wrong decision — never skip these:
| # | Question | Why it changes the answer |
|---|
| 3 | Is this a one-way or two-way door, and what makes it so? | Sets how much rigour the decision earns; misclassification is this skill's most expensive failure |
| 5-6 | Expected load NOW and at 10× — and what breaks FIRST? | Names the actual bottleneck instead of the imagined one; 10×, never 1000× |
| 8 | What is the consistency requirement PER read path, and what staleness is acceptable? | Consistency is decided per path, never once globally |
| 14 | What existing thing could be used instead of building? | Generic subdomains (auth, billing, notifications, search) are the top source of wasted architecture budget |
| 15 | What would have to be TRUE for this to be the WRONG choice — and how would I detect it? | Becomes the ADR's measurable revisit trigger |
MANDATORY IMPORTANT MUST ATTENTION a one-way door with no answer to question 15 is a BELIEF, not a decision — NEVER emit its ADR without a named falsifier and a measurable revisit trigger. — why: with no trigger nobody ever revisits it, so the decision outlives the constraints that justified it.
Architecture & Scalability Scorecard Inputs (feeds architecture-scalability-review)
Record these decisions now so the init-time architecture-scalability-review scorecard (mode=init) can grade them later against enforceable mechanisms, not intent. Each row is a design decision, not a finding — capture the choice AND where it is enforced. Leave any unknown as explicit Unresolved question (Step 11), never a silent omission. — why: a scorecard can only grade decisions actually recorded with an enforcement home.
| Scorecard input | Design prompt (decide + record where enforced) | Enforcement handoff |
|---|
| Build & CI scalability | As the codebase grows, how are build/CI times kept bounded? Decide incremental builds, changed/affected-only detection, local + remote cache strategy, and CI test/build parallelism. Name the build-system fit (single-package vs monorepo tool such as Nx / Turborepo / Bazel) as an evaluated option, not a default. | Step 7 (CI/CD provider parallelism + caching) |
| Horizontal scaling budgets | From the Step 2 scale targets, decide stateless app nodes, load balancing, caching tiers, async/queue + back-pressure, DB scale plan (sharding/partitioning/replication), connection pooling, rate limits, and a SPOF scan of every single-instance dependency. | ADR + Step 8 observability SLOs |
| Strategic DRY | Decide the strategic DRY / shared-knowledge strategy: monorepo, shared domain lib, custom platform / util lib — AND explicitly when NOT to share. Keep domain concepts OUT of generic/shared/infra layers (a shared layer coupled to one consumer's domain is no longer reusable). | Step 9 arch-rules + scaffold foundation |
| Dependency-boundary enforcement | Decide explicit dependency directions between modules/contexts and the mechanism that enforces them (no circular deps). | Step 9 "Arch rules / fitness" handoff → linter-setup |
These inputs are graded at init/audit by architecture-scalability-review; per-change regressions are caught by architecture-review. Do NOT turn this step into an auditor — record decisions here and route grading to those skills.
Step 3: Backend Architecture
3A: Architecture Styles
WebSearch top 3 backend architecture styles. Candidates:
| Style | Best For | Research Focus |
|---|
| Clean Architecture | Complex domains, long-lived projects | Dependency rule, testability, flexibility |
| Hexagonal (Ports+Adapt) | Integration-heavy, multiple I/O adapters | Port contracts, adapter isolation |
| Vertical Slice | Feature-focused teams, rapid delivery | Slice isolation, code locality |
| Modular Monolith | Starting simple, eventual decomposition | Module boundaries, migration path |
| Microservices | Large teams, independent deployment | Service boundaries, operational overhead |
| CQRS + Event Sourcing | Audit-heavy, complex queries | Read/write separation, event store |
| Layered (N-Tier) | Simple CRUD, small teams | Layer responsibilities, coupling risk |
Full 16-style matrix with per-style buys / costs / choose-when / avoid-when → .claude/docs/architecture-knowledge.md §5.
Style selection procedure (MANDATORY order — never shortcut)
- Take the ≤3 quantified driving attributes from Step 2-1.
- ELIMINATE every style that cannot meet them (state which attribute eliminated it).
- DESIGN IT TWICE — produce ≥2 MATERIALLY different surviving candidate designs (not two spellings of one idea) and write what each SACRIFICES. — why: committing to the first idea that occurred to you is the most common architecture failure and the one nobody records; a second real candidate is what makes the first one a choice.
- Among survivors take the SIMPLEST — not the most capable.
- Emit an ADR (Step 11) naming the rejected alternative AND the measurable trigger that would revisit the choice.
MANDATORY IMPORTANT MUST ATTENTION design-it-twice applies to EVERY one-way door from 2-0, not only the style choice — data model, tenancy model, consistency model per read path, sync-vs-async at a boundary. NEVER emit a one-way-door ADR whose "Alternatives considered" section was written to justify a decision already made. — why: a retrofitted alternative is advocacy, not evaluation, and it hides the sacrifice the reviewer needs to see.
Styles COMPOSE — modular monolith + event-driven integration + 2-3 extracted services is the most common good real answer. Recommending a single pure style is usually a sign step 2 was skipped.
MANDATORY IMPORTANT MUST ATTENTION — modulith-first default. Default to a modular monolith with CI-ENFORCED module boundaries (architecture tests, Step 9) and extract services ONLY against a named, measured trigger from the table below. Microservices are a destination reached under pressure, NEVER a starting point — the 2025-2026 industry correction is documented: many organizations re-consolidated after debugging complexity, ops overhead and network latency outweighed autonomy gains. — why: distribution bought speculatively pays every distributed cost immediately and collects the benefit never.
| Legitimate extraction trigger (record BEFORE building) | NOT a trigger (reject these) |
|---|
| Independent scaling profile ≥10x divergent | "The codebase feels big" |
| Different compliance / data-residency boundary | "Microservices are best practice" |
| Different availability requirement | A resume, a conference talk, or framework support |
| A team boundary PROVABLY blocked by shared deploys | One slow endpoint (fix the endpoint) |
| Genuinely different runtime need (GPU, language, memory profile) | A new team was hired |
| Fault isolation for a KNOWN-unreliable dependency | The domain has many entities |
MUST ATTENTION verify platform maturity before recommending microservices: CI/CD, IaC, distributed tracing, on-call, and a platform team. Microservices without them is the most reliable predictor of a failed migration — recommend the modulith and say so explicitly.
MUST ATTENTION draw boundaries around capabilities/behaviors (Checkout, Fulfilment, Pricing), NEVER around nouns/data (UserService, ProductService). Entity-per-service guarantees every real use case must synchronously traverse many services — a distributed monolith produced by design. The unit of extraction is the bounded context, not the entity.
3B: Backend Design Patterns
Evaluate applicability per layer:
| Pattern | Layer | When to Apply |
|---|
| Repository | Data Access | Abstract data store, enable testing |
| CQRS | Application | Separate read/write models, complex queries |
| Mediator | Application | Decouple handlers from controllers |
| Strategy | Domain/App | Multiple interchangeable algorithms |
| Observer/Events | Domain | Cross-aggregate side effects |
| Factory | Domain | Complex object creation with invariants |
| Decorator | Cross-cutting | Add behavior without modifying (logging, caching) |
| Adapter | Infrastructure | Isolate external dependencies |
| Specification | Domain | Composable business rules, complex filtering |
| Unit of Work | Data Access | Transaction management across repositories |
| Saga/Orchestr. | Cross-service | Distributed transactions, compensating actions |
| Outbox | Messaging | Reliable event publishing with DB transactions |
| Circuit Breaker | Infrastructure | External service resilience |
Per recommended pattern document: Apply to, Why, Example, Risk if skipped.
MUST ATTENTION patterns are a VOCABULARY for a solution you already need, never a menu to shop from — applying patterns to demonstrate knowledge produces the gas factory anti-pattern. The right number of patterns is the SMALLEST number that removes a DEMONSTRATED pain. Watch the chronically over-applied ones: Singleton (global mutable state → prefer one DI registration), Service Locator (hides dependencies from compiler and tests), CQRS on simple CRUD, event sourcing used as an audit log (an audit table is the right answer).
Step 3C: Data & Consistency Architecture
Skip if: the change touches no persistence, no consistency boundary, and no tenant-scoped data. Otherwise MANDATORY.
Data outlives every service, framework and team — this is the MOST irreversible step in this skill. Treat every row below as a one-way door (Step 2-0) until proven otherwise: each needs an ADR and a Step-12 validation question.
| Decision | Decide + record | Failure if skipped |
|---|
| Store per access pattern | Pick each store from the ACCESS PATTERN, not familiarity: relational (relations/transactions/ad-hoc queries — the correct default) · document (aggregate-shaped reads) · key-value (lookup/session) · wide-column (huge writes, known queries) · graph (traversal) · time-series (append + rollups) · search (relevance/facets) · vector (semantic/ANN) · columnar (aggregation scans) · object storage (blobs). Each ADDITIONAL store needs its own justification — polyglot persistence costs per store (ops, backup, monitoring, expertise, and transactional impossibility across stores). | Golden-hammer: the wrong store makes the dominant query permanently expensive |
| One writer per dataset | Name the single owning module/service for every dataset. Many READERS are fine — via API, replica, or published event stream. | Shared write access is shared coupling with NO contract; data diverges and nobody owns correctness |
| NEVER integrate through the database | External consumers get an API, an event stream, or at most a published view/replica — never your tables. | Fastest known path to a distributed monolith and to "we can never change this table" |
| Consistency model per read path | Per read path choose strong / causal / session guarantees (read-your-writes, monotonic reads) / eventual — and write the STALENESS BUDGET ("search index may lag ≤5 s") as a monitored SLI (Step 8). | Unbounded, unmeasured lag IS the defect. Most user-visible "consistency bugs" are missing read-your-writes from a lagging replica, NOT missing linearizability |
| Isolation level + check-then-act protection | NAME the isolation level per critical write path — "we use transactions" says nothing about correctness. Read Committed permits write skew AND lost update; snapshot isolation permits write skew and — on any engine whose REPEATABLE READ is not true first-committer-wins SI — lost update too, so name the ENGINE as well as the level and protect every check-then-act invariant one of FOUR deliberate ways: a DB constraint (unique/check/exclusion — cheapest and most durable) · SELECT … FOR UPDATE on the rows read · Serializable + an app-side retry loop for serialization failures · a single atomic conditional write (UPDATE … WHERE version = n). An invariant spanning rows that DO NOT YET EXIST (no double-booking, no overlapping shift, at most N per tenant) cannot be protected by row locks. Full anomaly table → .claude/docs/architecture-knowledge.md §8. | Two concurrent transactions both pass their check and both write — the classic on-call corruption bug that passes every single-user test |
| Storage engine + index strategy | Choose B-Tree (mixed read/write, ad-hoc queries, strong secondary indexes) vs LSM (write-heavy ingest with known query shapes — pay with compaction stalls in p99 and space amplification). Record the WAL/fsync policy as the durability↔latency knob the RPO depends on. Index rules: composite indexes obey the leftmost-prefix rule ((a,b,c) never serves b alone) · covering indexes remove the row fetch · every index slows writes, so index-per-query-shape has a ceiling · size the connection pool by Little's Law. | An unpooled service DOSes its own database; a wrong engine makes the dominant workload permanently expensive; fsync settings chosen by default silently violate the stated RPO |
| Distributed lock / leader election — fencing | If any flow takes a distributed lock or elects a leader, name the fencing token (monotonic, rejected by the storage layer when stale), the lease duration, and the behaviour when the lease expires mid-operation. Consensus (Raft/Paxos) needs a MAJORITY — a 2-node or even-sized cluster buys nothing — and stays OFF the hot path. NEVER order distributed events, compute expiry, or resolve conflicts by wall clock — use versions/sequences, logical/vector clocks, or HLC. | An unfenced lock fails exactly once — under a GC/VM pause, at peak, writing corrupted state — and looks correct in every test (split brain) |
| Transaction / aggregate boundary | One aggregate per transaction; reference other aggregates by ID only; keep aggregates SMALL; cross-aggregate consistency is EVENTUAL via domain events. Money movement, uniqueness, inventory decrement and auth state stay strong inside ONE aggregate/DB transaction. | Large aggregates cause lock contention; cross-aggregate transactions force 2PC or silent divergence |
| Cross-boundary transaction mechanism | Local ACID (ALWAYS prefer) → saga + compensation → reservation/TCC. AVOID 2PC/XA in web-scale distributed systems. Compensations are NEW BUSINESS FACTS (RefundIssued), not technical rollbacks — design them as product decisions, and design for the intermediate state being USER-VISIBLE. | "We'll use a distributed transaction" is a non-answer that blocks on coordinator failure |
| Tenancy model | Shared-schema tenant_id (default for most B2B SaaS) · schema-per-tenant · DB-per-tenant (regulated / residency / white-label / large enterprise) · hybrid tiering (pooled small + siloed whales — the mature scale-up shape). | Retrofitting tenancy is a full data migration |
| Tenant isolation ENFORCEMENT | In a pooled model, name the LOWEST-layer mechanism: database row-level security, an ORM global filter/interceptor, or a mandatory repository base injecting tenant from the authenticated principal — plus a test asserting cross-tenant reads return zero rows (Step 6 + Step 9 fitness rule). NEVER take tenant_id from a client-supplied field. | One missing WHERE tenant_id = ? is a cross-tenant breach that passes every functional test |
| Keys & partitioning | Prefer time-ordered IDs (UUIDv7/ULID/Snowflake) — sequential ints leak volume and are enumerable; UUIDv4 destroys index locality on write. NEVER expose an internal sequential PK publicly. Partition key must be uniformly distributed AND query-aligned; plan resharding (consistent hashing / virtual buckets) BEFORE needing it. | Hot partitions (time-based ⇒ hot latest; tenant-based ⇒ whale tenants) and write amplification |
| OLTP / OLAP separation | Analytics go to a replica, CDC, or warehouse — never the transactional primary. | Reports saturating production is a top incident cause |
| Denormalization / caching as a PURCHASE | For each denormalized copy or cache, name the mechanism keeping it correct and its invalidation strategy (TTL + jitter · event-driven · versioned/namespaced keys). Bound every cache (max size + eviction). NEVER cache authorization decisions or per-tenant data under a key omitting the identity/tenant/permission dimension. | Cache-key omission is a recurring cross-tenant leak that passes all functional tests; unbounded caches OOM |
| Migration strategy | Expand–contract (add nullable → dual write → backfill → switch reads → stop writing old → drop), forward-only, idempotent, non-blocking on large tables, deployable independently of the code using it. | A breaking migration in one deploy breaks old pods during a rolling deploy and makes rollback impossible |
| Lifecycle: classification, retention, residency, deletion | Classify (PII/PHI/PCI/public), set retention + archival tiering + deletion (GDPR/CCPA erasure) + residency NOW. | Retrofitting deletion into an event-sourced or heavily-denormalized system is brutally expensive — and erasure conflicts with immutable event stores by design |
| RPO / RTO per dataset | Set them PER DATASET (they drive topology and cost) and schedule a restore drill. | "We have backups" is a hypothesis; an undrilled DR plan has an RTO of "unknown" |
MANDATORY IMPORTANT MUST ATTENTION emit an ADR for the store choice, the tenancy model, the consistency model per read path, and the key strategy — these four are the least reversible decisions in the entire design — why: each one reversed later is a full data migration with downtime, not a refactor.
Step 3D: Integration & API Architecture
Skip if: no boundary is crossed — no external consumer, no second service, no message bus, no third-party integration. Otherwise MANDATORY.
| Decision | Decide + record | Failure if skipped |
|---|
| Sync vs async per boundary | Synchronous only when the caller genuinely cannot proceed without the answer (user-awaited QUERIES). Asynchronous for EFFECTS (notification, fan-out, work completable later). A sync chain deeper than 2-3 hops is an availability + latency defect — flatten, cache, or make it an event. | Sync chains MULTIPLY availability (five 99.9% deps ⇒ 99.5%) and SUM latency |
| API style per consumer | REST/HTTP+JSON (public, broad compat, HTTP caching) · GraphQL (client-driven queries, aggregation — needs depth/complexity limits + persisted queries + dataloader or it becomes a DoS and N+1 surface) · gRPC (low-latency internal, streaming, codegen) · webhooks (push to third parties — needs retries + signature verification) · WebSocket/SSE (real-time; SSE when one-way suffices). | Wrong style makes the dominant interaction chatty or uncacheable |
| Versioning + deprecation policy | Version from day one (URL path versioning is the pragmatic default); version the CONTRACT, not every field; support ≥N-1 with a published deprecation policy + per-version usage telemetry. | Versionless contracts mean any producer change breaks consumers — and you cannot tell who |
| Contract-first + contract tests in CI | OpenAPI / protobuf / AsyncAPI as the source of truth; consumer-driven contract tests are what make independent deploys SAFE (Step 6 + Step 9 gate). Tolerant reader — unknown fields ignored, never fatal. | Without contract tests, "independently deployable" is an aspiration, not a property |
| Write-then-publish ⇒ transactional outbox or CDC | MANDATORY whenever a flow writes the DB and publishes. NEVER two independent operations. | Dual-write: DB commits + publish fails ⇒ silent divergence; publish succeeds + DB rolls back ⇒ phantom downstream data |
| Idempotency everywhere | Exactly-once DELIVERY is impossible (Two Generals/FLP) ⇒ effectively-once via idempotency. Idempotency keys (with the stored RESULT + TTL) on all unsafe mutations; consumers dedup on message ID; prefer naturally idempotent operations (SET status='paid' over balance += x); optimistic concurrency via version/ETag. Assume duplicate, out-of-order and delayed arrival — carry a version/sequence and discard backward transitions. | Duplicate side effects: double charge, double email, double shipment |
| Message taxonomy — never conflate | Command ("do this", one handler, may be rejected) vs Event/fact ("this happened", 0..N subscribers, cannot be rejected) vs query vs document message. An "event" with exactly one permitted consumer that MUST handle it, whose failure means the flow failed, is a COMMAND in an event costume — name it a command and own the coupling honestly. | You pay async debugging difficulty AND keep sync coupling |
| Event granularity per stream | Deliberate choice: thin/notification (ID only — restores temporal coupling + read load) vs fat/state-transfer (self-contained, leaks more model, bigger payloads) vs hybrid (thin event + queryable snapshot endpoint). NEVER leak raw DB rows as events — CDC without a mapping layer publishes your internal schema as a frozen public contract (Hyrum). | Consumers become coupled to columns you can then never rename |
| Schema evolution | Versioned, registered, backward-compatible event schemas with a CI compatibility check. In event sourcing, event schemas are public contracts forever. | One producer change silently breaks every consumer |
| Broker semantics — ordering, replay, durability | Decide the three properties BEFORE naming a vendor: required ordering scope (global / per-entity-key / none) · required replay window (queue = consume-and-gone; log = offset-based replay by many consumer groups) · durability acknowledgement (replication factor + min-in-sync-replicas + producer acks — acks=1 accepts data loss on leader failure, and acks=all waits for the replicas CURRENTLY in the ISR — so min.insync=1 still waits for a healthy 3-replica ISR but silently degrades to acks=1 durability once the ISR shrinks to the leader alone). Log partition count is hard to raise without rekeying, and ordering on a key costs parallelism on that key. Health SLI: queue depth + oldest-message age, or consumer lag for a log. | Vendor picked first ⇒ the one property you actually needed (ordering, replay, or durability) turns out to be the one that is expensive to change |
| Load-balancing + rate-limiting algorithm | LB: least-outstanding-requests is the best general default (routes away from slow hosts automatically) · power-of-two-choices · consistent hashing only for cache/shard affinity (accept hot keys) · slow-start for new instances so a cold cache/JIT node is not handed full traffic. Rate limiting: token bucket for burst-tolerant public APIs · sliding-window counter for accuracy · concurrency/in-flight limiter when per-request cost is unknown or highly variable (it bounds the resource, not the count). Limit BY the protected dimension (tenant/principal/endpoint), never only by IP; always return Retry-After. Distributed enforcement needs a shared counter (new hot-path dependency) or per-node quota division (accept N× slack) — state which. | Round-robin ignores request cost and feeds a dying host; fixed-window limiters permit a 2× burst across the boundary; sticky sessions become the reason state was never externalized |
| Queue hygiene | Bounded queues + DLQ + a redrive procedure + DLQ-depth alerting; capped exponential backoff with jitter; poison-message handling. | An unbounded queue converts a throughput problem into unbounded latency then OOM; a DLQ nobody watches is data loss with extra steps; unjittered retries synchronize into a thundering herd |
| Resilience config on EVERY outbound call | Timeout (derived from the caller's remaining budget) on every network call, lock and query · capped jittered retries for idempotent ops ONLY · retry BUDGET as a % of traffic · circuit breaker with a defined fallback · bulkheads per dependency/tenant · load shedding at the edge by priority. | A missing timeout is the single most common resilience defect; retry amplification turns a blip into an outage. The dangerous failure is SLOW, not down — it exhausts your resources while looking healthy |
| Graceful degradation per feature | Pre-decide the degraded mode per feature (stale data / hide module / read-only) — a PRODUCT decision, made now, not during the incident. | Undesigned degradation becomes a total outage |
| Trust boundary rules | Validate at the boundary (allow-list); NEVER trust client-supplied authorization data — IDs, roles, prices, tenant IDs come from the authenticated principal. Machine-readable error contract (stable code, message, details, traceId; RFC 9457 problem+json is a good default) — NEVER leak stack traces. Propagate a correlation/trace ID through EVERY hop including async. | Broken access control is the #1 real-world risk; untraceable async hops make incidents unexplainable |
| Edge component responsibilities | Gateway = TLS, routing, authn, rate limiting, quotas, versioning — NEVER business logic (smart-gateway anti-pattern: a shared bottleneck every team queues for). BFF only when a client genuinely needs its own aggregation AND the frontend team owns it — skip it with one client or when GraphQL already fills the role. | A gateway or BFF holding domain rules duplicates the domain in a layer no team owns |
MANDATORY IMPORTANT MUST ATTENTION every sync-vs-async choice at a boundary and every public API/event contract is a one-way door — ADR + Step-12 validation, no exceptions — why: consumers you cannot see will depend on both, and Hyrum's Law makes every observable behavior a contract you must then keep.
Step 4: Frontend Architecture
4A: Architecture Styles
WebSearch top 3 frontend architecture styles. Candidates:
| Style | Best For | Research Focus |
|---|
| MVVM | Data-binding heavy, forms-over-data apps | ViewModel responsibility, two-way binding |
| MVC | Server-rendered, traditional web apps | Controller routing, view separation |
| Component Architecture | Configured SPA/component framework | Component isolation, props/events, reuse |
| Reactive Store (Redux) | Complex state, multi-component sync | Single source of truth, immutable state |
| Signal-based Reactivity | Fine-grained reactivity in frameworks that support signals | Granular updates without broad change detection |
| Micro Frontends | Multiple teams, independent deployment | Module federation, routing, shared state |
| Feature-based Modules | Large monolith SPA, lazy loading | Feature boundaries, route-level splitting |
| Server Components (RSC) | SEO, initial load performance | Server/client boundary, streaming |
4B: Frontend Design Patterns
| Pattern | Layer | When to Apply |
|---|
| Container/Presentational | Component | Separate logic from UI rendering |
| Reactive Store | State | Centralized state, cross-component communication |
| Facade Service | Service | Simplify complex API interactions |
| Adapter/Mapper | Data | Transform API response to view model |
| Observer (RxJS) | Async | Event streams, real-time data, debounce/throttle |
| Strategy (renderers) | UI | Conditional rendering strategies per entity type |
| Composite (components) | UI | Tree structures, recursive components |
| Command (undo/redo) | UX | Form wizards, canvas editors, undoable actions |
| Lazy Loading | Performance | Route/module-level code splitting |
| Virtual Scrolling | Performance | Large lists, infinite scroll |
Step 4B: UI System Architecture
Skip if: Backend-only project, no frontend component.
Research, recommend project design system architecture. Use ask the user directly for each decision.
4B-1: Styling Approach
WebSearch top 3 styling approaches for confirmed frontend framework:
| Approach | Best For | Research Focus |
|---|
| Utility-first (Tailwind CSS) | Rapid prototyping, design enforcement | JIT, custom config, design tokens |
| CSS Modules / Scoped CSS | Component isolation, no global conflicts | Naming, composition patterns |
| SCSS/SASS with BEM | Complex theming, token variables | BEM methodology, mixin libraries |
| CSS-in-JS | Dynamic styling, theme providers | Runtime perf, SSR support |
| CSS Custom Properties | Native theming, framework-agnostic | Browser support, fallback strategy |
4B-2: Design Token Strategy
| Decision | Options | Default |
|---|
| Token format | CSS custom properties / JSON / SCSS variables | CSS custom properties |
| Token categories | Color, spacing, typography, breakpoints, shadows, z-index | All |
| Token naming | Semantic (--color-primary) vs Functional (--btn-bg) | Semantic first |
| Theming | Light/dark toggle / Multi-brand / Single theme | Single + dark mode |
4B-3: Component Library Strategy
| Decision | Options | Default |
|---|
| Library | Build custom / Headless (Radix, Headless UI) / Full kit (MUI, Ant, PrimeNG) | Based on team and timeline |
| Component tiers | Common → Domain-Shared → Page (per ui-wireframe-protocol) | Standard 3-tier |
| Documentation | Storybook / Docusaurus / In-code only | Based on team size |
4B-4: Responsive Strategy
| Decision | Options | Default |
|---|
| Approach | Mobile-first / Desktop-first / Adaptive | Mobile-first |
| Breakpoints | 320/768/1024/1280 / Custom | Standard |
| Grid system | CSS Grid / Flexbox / Framework grid | CSS Grid + Flexbox |
MANDATORY IMPORTANT MUST ATTENTION validate all UI system decisions with user by asking the user directly before proceeding to Step 5.
Step 5: Library Ecosystem Research
Per concern below, WebSearch top 3 library options for confirmed tech stack. Evaluate: maturity, community, bundle size, maintenance activity, license, learning curve.
MUST ATTENTION never recommend a library from familiarity alone — every pick needs cited evidence (stars, release date, downloads, CVE scan). — why: familiarity bias ships unmaintained or insecure dependencies.
Library Concerns Checklist
| Concern | What to Research | Evaluation Criteria |
|---|
| Validation | Input validation, schema validation, form validation | Type safety, composability, error messages |
| HTTP Client / API Layer | REST client, GraphQL client, API code generation | Interceptors, retry, caching, type generation |
| State Management | Global store, local state, server state caching | DevTools, SSR support, bundle size |
| Utilities / Helpers | Date/time, collections, deep clone, string manipulation | Tree-shakability, size, native alternatives |
| Caching | In-memory cache, distributed cache, HTTP cache, query cache | TTL, invalidation, persistence |
| Logging | Structured logging, log levels, log aggregation | Structured output, transports, performance |
| Error Handling | Global error boundary, error tracking, crash reporting | Source maps, breadcrumbs, alerting integration |
| Authentication / AuthZ | JWT, OAuth, RBAC/ABAC, session management | Standards compliance, SSO, token refresh |
| File Upload / Storage | Multipart upload, cloud storage SDK, image processing | Streaming, resumable, size limits |
| Real-time | WebSocket, SSE, SignalR, Socket.io | Reconnection, scaling, protocol support |
| Internationalization | i18n, l10n, pluralization, date/number formatting | ICU support, lazy loading, extraction tools |
| PDF / Export | PDF generation, Excel export, CSV | Server-side vs client-side, template support |
Per-Library Evaluation Template
### {Concern}: Top 3 Options
| Criteria | Option A | Option B | Option C |
| ---------------- | ----------------- | -------- | -------- |
| GitHub Stars | ... | ... | ... |
| Last Release | ... | ... | ... |
| Bundle Size | ... | ... | ... |
| Weekly Downloads | ... | ... | ... |
| License | ... | ... | ... |
| Maintenance | Active/Slow/Stale | ... | ... |
| Learning Curve | Low/Med/High | ... | ... |
**Recommendation:** {Option} — Confidence: {X}%
Step 6: Testing Architecture
Research best testing tools, strategy for confirmed tech stack:
| Testing Layer | What to Research | Top Candidates to Compare |
|---|
| Unit Testing | Test runner, assertion library, mocking framework | Repository's configured unit-test stack |
| Integration Testing | API testing, DB testing, service testing | Supertest, TestContainers, WebAppFactory |
| E2E Testing | Browser automation, BDD, visual regression | Playwright/Cypress/Selenium, SpecFlow |
| Performance Testing | Load testing, stress testing, benchmarking | k6/Artillery/JMeter/NBomber, BenchmarkDotNet |
| Contract Testing | API contract validation between services | Pact, Dredd, Spectral |
| Mutation Testing | Test quality validation | Stryker, PITest |
| Coverage | Code coverage collection, reporting, enforcement | Istanbul/Coverlet, SonarQube |
| Test Data | Factories, fixtures, seeders, fakers | Bogus/AutoFixture/Faker.js |
Test Strategy Template
### Test Pyramid
- **Unit (70%):** {framework} — {what to test}
- **Integration (20%):** {framework} — {what to test}
- **E2E (10%):** {framework} — {what to test}
### Test-Strength Targets
- Line coverage (diagnostic only — NEVER fail the build on a coverage %): Unit: {X}% | Integration: {X}% | E2E: critical paths only
- Gate: mutation score ({tool}) in CI pipeline — fail build on surviving mutants / mutation-score regression, not on a line-coverage %
Step 7: CI/CD & Deployment
Research deployment architecture, CI/CD tooling:
| Concern | What to Research | Top Candidates to Compare |
|---|
| CI/CD Provider | Pipeline orchestration, parallelism, caching | Repository's configured CI/CD tooling |
| Containerization | Container runtime, image building, registry | Docker/Podman, BuildKit, ACR/ECR/GHCR |
| Orchestration | Container orchestration, service mesh, scaling | Kubernetes/Docker Compose/ECS/Nomad |
| IaC (Infra as Code) | Infrastructure provisioning, drift detection | Terraform/Pulumi/Bicep/CDK |
| Artifact Management | Package registry, versioning, vulnerability scanning | NuGet/npm/Artifactory/GitHub Packages |
| Feature Flags | Progressive rollout, A/B testing, kill switches | LaunchDarkly/Unleash/Flagsmith |
| Secret Management | Vault, key rotation, environment variables | Azure KeyVault/HashiCorp Vault/SOPS |
| Database Migration | Schema versioning, rollback, seed data | EF Migrations/Flyway/Liquibase/dbmate |
Deployment Strategy Comparison
| Strategy | Risk | Downtime | Complexity | Best For |
|---|
| Blue-Green | Low | Zero | Medium | Critical services |
| Canary | Low | Zero | High | Gradual rollout |
| Rolling | Med | Zero | Low | Stateless services |
| Recreate | High | Yes | Low | Dev/staging environments |
| Feature Flags | Low | Zero | Medium | Feature-level control |
Release-safety rules (decide + record — these bind Step 3C/3D contracts to the pipeline)
| Rule | Requirement |
|---|
| Decouple deploy from release | Flags / canary with SLI gates + auto-rollback. A flag needs an EXPIRY date or it becomes permanent branching complexity |
| Backward AND forward compatible for one version | MANDATORY — a rolling deploy runs both versions SIMULTANEOUSLY. Applies to APIs, event schemas AND database schemas alike |
| Expand–contract migrations | Add nullable → dual write → backfill → switch reads → stop writing old → drop. Forward-only, idempotent, non-blocking, deployed INDEPENDENTLY of the code using it. NEVER a breaking schema change in one deploy |
| One artifact, external config | Build once, promote the same artifact across environments (12-factor); config and secrets injected per environment |
| Graceful shutdown | Stop accepting → drain in-flight with a deadline → flush buffers/metrics → close pools → exit. Without it EVERY deploy sheds requests |
| Liveness ≠ readiness | Readiness reflects dependencies; liveness must NOT (or one dependency blip restarts the whole fleet). Add startup probes for slow boots |
| Legacy replacement | Strangler fig (facade + capability-by-capability routing) or branch by abstraction, with parallel run / shadow compare for high-risk replacements. NEVER a big-bang rewrite of a system you don't fully understand — you inherit all undocumented behavior as invisible requirements |
| DORA as delivery SLIs | Deploy frequency, lead time, change-failure rate, MTTR — measure outcomes, never proxy metrics (Goodhart) |
MANDATORY IMPORTANT MUST ATTENTION if the design changes a database schema or a published contract, the migration plan is part of THIS design, not an implementation detail deferred to plan-execute — why: a schema change designed without expand–contract makes the whole release irreversible.
Step 8: Observability & Monitoring
| Concern | What to Research | Top Candidates to Compare |
|---|
| Structured Logging | Log format, correlation IDs, log levels, aggregation | Serilog/NLog/Winston/Pino |
| Log Aggregation | Centralized log search, dashboards, alerts | ELK/Loki+Grafana/Datadog/Seq |
| Metrics | Application metrics, custom counters, histograms | Prometheus/OpenTelemetry/App Insights |
| Distributed Tracing | Request tracing across services, span visualization | Jaeger/Zipkin/OpenTelemetry/Tempo |
| APM | Application performance monitoring, auto-instrumentation | Datadog/New Relic/App Insights/Elastic |
| Alerting | Threshold alerts, anomaly detection, on-call routing | PagerDuty/OpsGenie/Grafana Alerting |
| Health Checks | Liveness, readiness, startup probes | AspNetCore.Diagnostics/Terminus |
| Uptime Monitoring | External availability monitoring, SLA tracking | UptimeRobot/Pingdom/Checkly |
Observability Decision: 3 Pillars
### Recommended Observability Stack
| Pillar | Tool | Why |
| -------- | ------ | ----------- |
| Logs | {tool} | {rationale} |
| Metrics | {tool} | {rationale} |
| Traces | {tool} | {rationale} |
| Alerting | {tool} | {rationale} |
Step 9: Code Quality & Clean Code Enforcement
Research, recommend tooling for automated code quality:
| Concern | What to Research | Top Candidates to Compare |
|---|
| Linter (Backend) | Static analysis, code style, bug detection | Roslyn Analyzers/SonarQube/StyleCop/ReSharper |
| Linter (Frontend) | JS/TS linting, accessibility, complexity | ESLint/Biome/oxlint |
| Formatter | Auto-formatting, consistent style | Prettier/dotnet-format/EditorConfig |
| Code Analyzer | Security scanning, complexity metrics, duplication | SonarQube/CodeClimate/Codacy |
| Pre-commit Hooks | Git hooks, staged file validation | Husky+lint-staged/pre-commit/Lefthook |
| Editor Config | Cross-IDE consistency | .editorconfig/IDE-specific configs |
| Architecture Rules | Layer dependency enforcement, naming conventions | ArchUnit/NetArchTest/Dependency-Cruiser |
| API Design Standards | OpenAPI validation, naming, versioning | Spectral/Redocly/swagger-lint |
| Commit Conventions | Commit message format, changelog generation | Commitlint/Conventional Commits |
| Code Review Automation | Automated PR review, suggestion bots | Danger.js/Reviewdog/CodeRabbit |
Enforcement Strategy
### Code Quality Gates
| Gate | Tool | Trigger | Fail Criteria |
| ----------- | ------ | -------------- | --------------------- |
| Pre-commit | {tool} | git commit | Lint errors, format |
| PR Check | {tool} | Pull request | Surviving mutants / mutation-score regression, issues (line-coverage diagnostic only) |
| CI Pipeline | {tool} | Push to branch | Build fail, test fail |
| Scheduled | {tool} | Weekly/nightly | Security vulns, debt |
Scaffold Handoff (MANDATORY — consumed by $scaffold)
After code-quality research, produce this handoff table in the architecture report. $scaffold reads it to generate actual config files — without it, scaffold cannot auto-configure quality tooling. — why: the handoff table is the only contract scaffold has for tool choices.
### Scaffold Handoff — Tool Choices
| Concern | Chosen Tool | Config File | Rationale |
| -------------- | ----------------- | ----------- | --------- |
| Linter (FE) | {tool} | {filename} | {why} |
| Linter (BE) | {tool} | {filename} | {why} |
| Formatter | {tool} | {filename} | {why} |
| Pre-commit | {tool} | {filename} | {why} |
| Arch rules / fitness | {tool: ArchUnit / NetArchTest / Dependency-Cruiser} | {filename} | {layer + dependency rules and Step-2 NFR budgets to enforce} |
| Error handling | {pattern} | {files} | {why} |
| Loading state | {pattern} | {files} | {why} |
| Docker | {compose pattern} | {files} | {why} |
Also include: Error handling strategy (4-layer pattern), loading state approach (global vs per-component), Docker profile structure. Specific tool choices → docs/project-reference/ or project-config.json. The Arch rules / fitness row MUST encode Step-2 quality-attribute budgets and layer/dependency rules as executable checks — harness-setup wires these into CI so recorded ADR decisions stay enforced, not merely documented. — why: documented-but-unenforced budgets erode silently as code changes.
Example patterns to scaffold (golden-path reference set): the handoff MUST also name the worked, copy-me examples $scaffold emits under an isolated, production-excluded examples/ tree — one per applicable pattern, using the scaffolded base abstractions, so the post-scaffold $architecture-review-full has real code to grade. Target set (≥ 11 when a UI is present; skip absent layers and log why):
### Scaffold Handoff — Golden-Path Examples
| Layer | Example patterns (one worked `*.example.*` each) |
| --------- | ------------------------------------------------------------------------------------------------------ |
| Backend | command · query · command/query handler · entity-with-invariants · value-object · repository (concrete) · domain event + event handler |
| Frontend | form component · list component · state store · API service *(only if a UI stack is present)* |
| Tests | one integration test exercising an example command/query on BOTH the happy path AND a failure path |
Every example carries the GOLDEN-PATH EXAMPLE — copy into src/ …; NOT compiled into the production build header, contains NO secrets/real endpoints (placeholders only: EXAMPLE_API_KEY, example.invalid), and compiles/lints under the CI (non-production) target. — why: empty base abstractions are unverified skeletons; one worked example per pattern turns each into demonstrated, reviewable, copy-me usage.
Step 10: Dependency Risk Assessment
Per recommended library/package, evaluate maintenance, obsolescence risk:
Package Health Scorecard
| Criteria | Score (1-5) | How to Verify |
|---|
| Last Release Date | ... | npm/NuGet page — stale if >12 months |
| Open Issues Ratio | ... | GitHub issues open vs closed |
| Maintainer Count | ... | Bus factor — single maintainer = high risk |
| Breaking Change Freq. | ... | Changelog — frequent major versions = churn cost |
| Dependency Depth | ... | npm ls --depth / dependency graph depth |
| Known Vulnerabilities | ... | Snyk/npm audit/GitHub Dependabot |
| License Compatibility | ... | SPDX identifier — check viral licenses (GPL) |
| Community Activity | ... | Monthly commits, PR merge rate, Discord/forums |
| Migration Path | ... | Can swap to alternative if abandoned? |
| Framework Alignment | ... | Official recommendation by framework team? |
Risk Categories
| Risk Level | Criteria | Action |
|---|
| Low | Active, >3 maintainers, recent release, no CVEs | Use freely |
| Medium | 1-2 maintainers, release <6mo, minor CVEs patched | Use with monitoring plan |
| High | Single maintainer, >12mo stale, open CVEs | Find alternative or plan exit strategy |
| Critical | Abandoned, unpatched CVEs, deprecated | DO NOT USE — find replacement |
Dependency Maintenance Strategy
### Recommended Practices
1. **Automated scanning:** {tool} (Dependabot/Renovate/Snyk) — weekly PR for updates
2. **Lock file strategy:** Commit lock files, pin major versions, allow patch auto-update
3. **Audit schedule:** Monthly `npm audit` / `dotnet list package --vulnerable`
4. **Vendor policy:** Max {N} dependencies per concern, prefer well-maintained alternatives
5. **Exit strategy:** For each High-risk dependency, document migration path to alternative
Step 11: Generate Report
Write report to {plan-dir}/research/architecture-design.md with sections:
- Executive summary (recommended architecture in 8-10 lines)
- Architecture requirements table + reversibility ranking (one-way vs two-way doors) + ≤3 driving attributes and what is SACRIFICED + cost unit economics (from Step 2)
- Backend architecture — style comparison with the elimination rationale per rejected style + the recorded extraction trigger + recommended patterns (Step 3A/3B)
- Data & consistency architecture — stores per access pattern, dataset writer ownership, consistency model + staleness budget per read path, transaction/aggregate boundaries, tenancy model + isolation enforcement mechanism, keys/partitioning, migration strategy, retention/residency, RPO/RTO per dataset (Step 3C)
- Integration & API architecture — sync-vs-async per boundary, API style per consumer, versioning + deprecation policy, contract tests, outbox/CDC, idempotency strategy, event granularity + schema evolution, queue hygiene, resilience config, degradation modes (Step 3D)
- Frontend architecture — style comparison + recommended patterns (Step 4)
- Library ecosystem — per-concern recommendations with alternatives (Step 5)
- Testing architecture — pyramid, tools, coverage targets, contract tests + tenant-isolation test (Step 6)
- CI/CD & deployment — pipeline design, deployment strategy, expand–contract migration plan + rolling-deploy compatibility (Step 7)
- Observability stack — 3 pillars + alerting + the staleness/lag SLIs declared in Step 3C (Step 8)
- Code quality — enforcement gates, tooling, fitness functions per architectural rule (Step 9)
- Dependency risk matrix — high-risk packages, mitigation (Step 10)
- Architecture diagram (Mermaid — all layers, data flow, trust boundaries and failure domains)
- Cost model —
$/request or $/tenant, the dominant drivers, and whether unit cost rises with scale
- Risk assessment for overall architecture — including the anti-patterns deliberately accepted and why
- Unresolved questions
MUST ATTENTION every diagram needs a legend, a date and an owner — an undated diagram is a rumor. Show trust boundaries and failure domains explicitly: that is the entire point of drawing a deployment view.
Emit ADRs for hard-to-reverse decisions (MANDATORY)
For each decision significant AND costly to reverse — every one-way door classified in Step 2-0: backend/frontend style, data model + key strategy, tenancy model, consistency model per read path, sync-vs-async at a boundary, public API/event contract, service boundary lines, auth/identity model, data residency + retention, messaging approach, a Step-2 quality-attribute budget, a rejected-with-reason alternative — write one ADR to docs/adr/{NNNN}-{slug}.md following the repo's existing ADR format (Status, Date, Context, Decision, Consequences [Positive/Negative/Neutral], Alternatives Considered, Related; see docs/adr/0001-skill-lifecycle.md for canonical shape). Start Status: Proposed; promote to Accepted after Step-12 user validation confirms it. These ADRs are the binding record architecture-review Category 9 checks changed code against — a decision not written as an ADR cannot be enforced downstream. Route ADR authoring through the architect sub-agent for cross-service/security/performance impact analysis.
ADR minimum content — the two most-skipped fields are the most valuable: Context (forces, constraints, quantified attributes) · Decision · Alternatives considered WITH why each was rejected (prevents relitigating, and later explains the constraint to whoever is tempted to break it) · Consequences (what we now CANNOT do easily) · Status · Revisit trigger (the measurement that would reopen this decision).
MUST ATTENTION an architectural rule NOT automatically verified is a SUGGESTION and will be violated within one quarter. Every ADR-recorded constraint that CAN be machine-checked MUST also land in the Step-9 Scaffold Handoff as an executable fitness rule (layer/dependency rules, no module cycles, domain purity, API + event schema compatibility, tenant-isolation test, "every outbound call has a timeout", bundle/latency budgets, cost-per-request regression). Pay existing architectural debt with a RATCHET — block new violations in CI, then decrement the existing count — never with a "cleanup sprint later" that never happens.
Architecture Diagram Template
```mermaid
graph TB
subgraph "Frontend"
UI[SPA / Micro Frontend]
STORE[State Management]
end
subgraph "API Gateway"
GW[Gateway / BFF]
end
subgraph "Backend Services"
CMD[Commands / Handlers]
QRY[Queries / Read Models]
SVC[Domain Services]
ENT[Entities / Aggregates]
end
subgraph "Infrastructure"
DB[(Database)]
CACHE[(Cache)]
MSG[Message Bus]
SEARCH[(Search Index)]
end
subgraph "Observability"
LOG[Logging]
METRIC[Metrics]
TRACE[Tracing]
end
subgraph "CI/CD"
PIPE[Pipeline]
REG[Container Registry]
K8S[Orchestration]
end
UI --> GW --> CMD & QRY
CMD --> SVC --> ENT --> DB
QRY --> CACHE & SEARCH
ENT -.-> MSG
CMD & QRY -.-> LOG & METRIC & TRACE
PIPE --> REG --> K8S
```
Step 12: User Validation Interview
MANDATORY IMPORTANT MUST ATTENTION present findings, ask 8-12 questions by asking the user directly:
Required Questions
- Driving attributes + sacrifices — "I optimized for {≤3 attributes} and am SACRIFICING {list} — e.g. {concrete degradation}. Correct priorities?"
- Backend architecture — "I recommend {style}; I eliminated {alternatives} because {attribute}. The trigger that would make us extract services is {measurable trigger}. Agree?"
- Consistency model + staleness budget (one-way door) — "{read path} will be eventually consistent with a ≤{N}s staleness budget; {other path} stays strongly consistent. Acceptable to the business?"
- Tenancy + isolation (one-way door) — "Tenancy is {model}, isolation enforced by {mechanism}. Any tenant needing stronger isolation or its own residency?"
- Sync vs async boundaries (one-way door) — "{boundary} is async, so {effect} completes eventually and the user sees {intermediate state}. Acceptable UX?"
- Frontend architecture — "I recommend {style} with {state management}. Agree?"
- Design patterns — "Recommended backend patterns: {list}. Frontend patterns: {list}. Any to add/remove?"
- Key libraries — "For {concern}, I recommend {lib} over {alternatives}. Agree?"