# Architecture-driver table Most requirements do not change a structure. Drivers are the few that do. A driver is ready when two plausible architectures would respond to it differently, the team can say why it matters to the outcome, and a check can prove whether the design meets it. Source: lesson 0043 · Find the Architecture Drivers. --- ## Blank ### Quality-attribute scenario — six parts > When **`[source]`** causes **`[stimulus]`** during **`[environment]`**, **`[artifact]`** > must **`[response]`**, measured by **`[number with a unit]`**. | Field | One-line guidance | | --- | --- | | Why it matters | The outcome, guardrail, regulatory, or operational consequence. If you cannot name one, this is context, not a driver. | | Design pressure | Which structural choices this scenario distinguishes. This is the test of whether it is a driver at all. | | Evidence | The test, fitness function, drill, or production measure that can fail. | | Owner / date | One name, one date. | ### The table | # | Quality | Scenario (source · stimulus · environment · artifact · response · measure) | Why it matters | Design pressure | Evidence | Owner | | --- | --- | --- | --- | --- | --- | --- | | 1 | `[availability / performance / security / modifiability / operability / cost / …]` | `[the six-part sentence]` | `[outcome or guardrail]` | `[what it rules in or out]` | `[test or measure]` | `[name]` | Pick **five to seven**, ranked by business impact, uncertainty, and structural reach. Fifty prioritized requirements are fifty unprioritized requirements. ### Conflicts Write down where two drivers pull against each other and how you resolved it, before an engineer discovers it mid-sprint. | Driver A | Driver B | The tension | Resolution | | --- | --- | --- | --- | ### Constraint vs. preference | Statement | Constraint or preference? | Why | | --- | --- | --- | A constraint is a fact you cannot change inside this initiative. "We already know Kafka" is a proposed decision wearing a constraint's clothes. --- ## Completed — returns resolution pilot Five drivers, not fifty, ranked by impact × uncertainty × structural reach. | # | Quality | Scenario | Why it is ranked here | Evidence mechanism · owner | | --- | --- | --- | --- | --- | | D1 | Availability | The carrier becomes unavailable for **30 minutes during peak returns traffic**. The returns module and label worker must continue to accept and decide eligible requests, and create **99% of the queued labels within 15 minutes** of carrier recovery. | Highest structural reach: it decides whether the carrier call sits inside the request. Uncertainty was highest too, until the A3 spike measured it. | Recovery drill in staging with the carrier sandbox forced to 100% timeouts, run before every exposure stage · Dana | | D2 | Performance | Customers submit returns at **40 requests/second at seasonal peak**. The eligibility decision path must return a decision within **800 ms at p95**, excluding label creation. | Carries the latency half of the outcome directly, and it is the driver that forces label creation off the request path. Conflicts with D1 — see below. | Load test at 40 rps against a production-shaped dataset in the pipeline; a production histogram with a p95 alert · Sam | | D3 | Security and privacy | A signed-in customer substitutes **another customer's order identifier**, in any environment including staging. The returns API must disclose **no field** of the other customer's order or return — in responses, errors, or logs — and must record the attempt. | Impact is unbounded and non-negotiable. Reach is moderate, but it constrains every read path and every log line. | Negative authorization tests in the contract suite; a log-scanning fitness function that fails the build on an unredacted order id · Ola | | D4 | Modifiability | The policy owner adds one eligibility rule, mid-quarter, **nine times a year**. One engineer must release it **within one working day**, changing no carrier adapter, no UI component, and no API contract. | Evidenced by A7 (nine changes a year, four mid-quarter). It is the reason eligibility is a module with its own seam rather than rules scattered through the journey. | Import-rule fitness function in the build; measured lead time on the last three policy changes · Dana | | D5 | Operability | The carrier starts failing: **label errors exceed 2% for five minutes** during any exposure stage. On-call must identify the carrier as the cause and **disable label attempts within ten minutes**, without refusing new returns and without leaving the worker retrying. | Lower reach than D1, but it is what makes D1's response reachable by a human at 02:00. Its rehearsal found a real defect. | An alert with a runbook link; the disable path exercised in a reversal rehearsal before each stage · Nils | ### Conflicts, written down before an engineer discovers them mid-sprint | Driver A | Driver B | The tension | Resolution | | --- | --- | --- | --- | | D2 · 800 ms decision | D1 · a label the customer can use | The A3 spike measured the carrier at p50 640 ms, p95 1.9 s, **p99 11.4 s**. A live label inside the request cannot satisfy both. | Return the eligibility decision quickly and make label creation a separately observable state. This is exactly the decision recorded in ADR 0003. It costs the customer a two-step mental model — "accepted", then "label ready" — which is the cost assumption A2's comprehension test exists to measure. | | D3 · nothing identifying in logs | D5 · on-call needs rich failure detail | On-call wants identifiers in log lines; D3 forbids them. | Correlation ids in logs; identifiers only behind an access-controlled lookup. Both drivers keep their measure. | | D4 · one-day policy change | D3 · authorization strictness | A module that can be changed quickly is also a module that could accidentally widen access. | Policy decides *eligibility*; it never decides *visibility*. Authorization sits outside the policy module and cannot be affected by a rule change — enforced by D4's own import rule. | ### Considered and rejected as drivers, with the reason | Proposed | Why it is not a driver here | | --- | --- | | "The system must scale." | No load, no operation, no horizon. Written out, the real load is 40 rps at seasonal peak (D2), which one deployable handles. No option in the option table responds differently to "scale", so it distinguishes nothing. | | "Must handle 10× current volume." | 10× is beyond the twelve-month demand horizon, and the pilot is 1% of one cohort. It would buy an architecture we cannot test and could not justify in ADR 0001. | | "Must be cloud-native / event-driven." | Mechanisms, not qualities. They belong in the option table as candidate answers — where both appear, and where both were rejected with a reason. | | "Must be maintainable." | Replaced by D4, which names the change (one policy rule), the person (one engineer), the elapsed time (one day), and the blast radius (no adapter or contract change). That version can fail a check; "maintainable" cannot. | | "99.99% uptime." | A number with no operation attached. The real requirement is D1: accepting requests must survive a carrier outage. Label creation may degrade; request acceptance may not. One number for the whole system would have hidden that distinction. | ### Constraint or preference? | Statement | Verdict | Why | | --- | --- | --- | | "The order platform stays authoritative for order truth" | Constraint | Another team owns it; changing that is a quarter of work outside this initiative. | | "The carrier contract is fixed for the pilot" | Constraint | Signed; renegotiation is outside the pilot window. | | "No payment card data enters the returns module" | Constraint | Compliance scope; the alternative is a PCI assessment. | | "Build inside the existing deployable rather than as a service" | **Decision, not constraint** | A choice with named reasons, recorded in ADR 0001 and revisitable. Calling it a constraint would hide the reasoning and make it unarguable. | | "Use our standard message broker" | **Preference** | No driver requires it. One database transaction already gives all-or-nothing across return, decision, and intent. Recorded as a rejected option rather than accepted as a fact. | **Traces to:** D1 and D2's conflict is the direct input to ADR 0003 in `option-table-spike-brief-and-adr.md`; D4 is the direct input to the module seam in `c4-review-checklist.md`; D5's disable path is what `rollout-contract.md` rehearses before every stage; A3 and A7 in `assumption-map.md` are the evidence behind D1 and D4.