Segun Kolade
Segun Kolade

AOS for Architecture Review

The best architecture reviews do not end in agreement. They end in a decision with the disagreement written next to it.

Security review was the easy Council to trust, because a missed vulnerability is a fact. Architecture is harder. The right call is often not a single confident recommendation, it is a decision plus the dissent that should follow it into the next review.

Why architecture wants dissent

A security finding is right or wrong. Org A can read Org B's row or it cannot. An architecture decision is a bet under uncertainty, and it does not resolve on the day you make it. It resolves quarters later, in a migration, when the load finally arrives or the requirement you waved off shows up with a customer attached. The losing arguments in that room are the only early-warning system you get. They are the recorded reasons the bet might go bad, filed under the exact conditions that would make them right. A single confident recommendation throws all of that away. It ships the conclusion and burns the reasoning.

That is why an ADR should carry its dissent. The losing arguments are how the next engineer knows what to watch for the day the decision is finally under load.

The profile

The `architecture-review` profile fields eight agents: a neutral Arbiter and seven perspectives, the same machinery as every other Council. Four of the seven are required: the Architect leads on feasibility and system design, the Pathfinder pushes the 10x alternative, the Operator grounds it in what a small team can actually ship, and the Provocateur speaks last, so whatever the room agrees on has to survive one more hit before it counts. The other three, Catalyst, Sentinel, and Steward, ride along by default.

The structure that matters here is the tension pairs: [architect, pathfinder] and [operator, provocateur]. Ideal against radical. Buildable against stress-tested. The disagreement is in the config before the run starts, by design. Canon for this issue: the Architect, doing arithmetic in an architecture room, and dissent that survives into the artifact.

The decision under review

Same auth system this newsletter has carried since Issue 6. The Crew chose server-side Postgres sessions in Issue 6, built them in Issue 7, and the security Council reviewed them in Issue 9. Now the architecture Council reviews the choice itself. Multi-tenant B2B, NA plus EU users, a few-ms p99 budget, a three-engineer team. The brief fills the profile's four sections (## Architecture, ## Scale Requirements, ## Constraints, ## Key Question), and the Key Question is the one everyone with a sessions table eventually asks: does the per-request database read become the bottleneck we regret, and should we move to stateless JWT or put a cache in front before it does? Real risk, or premature optimization?

Then aos run architecture-review, session 2026-07-01-architecture-review-mr2938s0.

The debate, with the dissent kept

The Architect opened by refusing the premise.

Let me do the arithmetic before we debate architecture, because the premise contains an assumption I want to kill.
Architect, Round 1

Then it did the arithmetic and never softened it.

at 2,000 rps against ~30K resident session rows, the per-request read is a sub-millisecond memory-resident index lookup with 10–25x headroom, so it's the right architecture; the risks that actually bite are connection exhaustion, hot-path write churn, and EU residency, not the read itself.
Architect, later round

That settled the headline. The read everyone fears is a memory probe with an order of magnitude of headroom. The room converged fast: keep the Postgres sessions, do not move to JWT. Every seat got there. On a cache it was nearly unanimous too, the Steward the lone conditional yes.

This is where a lesser review stops, writes "consensus: keep-but-harden," and files a clean recommendation. The value was in the two places the room refused to leave it there.

First, the case against the roads not taken. Both alternatives got a recorded argument for why they are wrong here, not a shrug. The Operator:

Bolting on a cache or a token scheme to solve a throughput problem you don't have is the over-build failure mode you named, executed by a 3-engineer team, and it quietly reintroduces the staleness you chose sessions to escape.
Operator, Round 1

The Pathfinder, the seat whose whole job is the radical 10x move, used its turn to name the compromise itself as the trap.

the incremental trap here is the compromise: "keep-but-harden, and add a little caching to be safe." That bolts staleness back onto the one property we chose this architecture to guarantee (instant revocation) ... a negative asymmetric bet: tiny upside, real downside.
Pathfinder, Round 1

That is the dissent an ADR is built to preserve. A cache is a TTL, and a TTL is staleness, and staleness is the exact thing server-side sessions were chosen to avoid. Write that down and the next engineer who proposes "just add Redis to be safe" reads the reason it was already rejected.

Second, and sharper, the Provocateur challenged the question.

Before I answer, I'm going to challenge the question, because the most dangerous assumption in this room is baked into how it's phrased.
Provocateur, Round 1

Speaking last, it agreed with the keep-but-harden verdict and then went after its justification.

The architect hardened the read. But the read was never the risk. He's benchmarked the cheap version of this system and claimed the property of the expensive one ... keep-but-harden. But harden the write path, not the read path.
Provocateur, later round

Here is the load-bearing dissent. Denormalize org_id and role onto the session row and you get the sub-millisecond read the whole room just celebrated. But that field is now a snapshot. When an admin drops a user to viewer, "effective next request" needs a write that fans out to every session that user holds, across every device, across every org.

That fan-out is the whole game, and it's your least-tested code path, because revocation is rare. The one time it matters (you're firing a compromised admin), the revoke UPDATEs a table, the app reads the stale denormalized field, and the attacker keeps access ...
Provocateur, later round

The cheap read and the instant-revocation promise, the Provocateur argued, describe two different architectures, and the review was claiming both at once. Nobody had said it out loud. The Provocateur speaks last for exactly this: to stop the room banking a comfortable answer before the argument is done.

The room did not fully resolve that, and it should not have. The Steward resisted JWT outright on compliance grounds: GDPR Art. 32 requires appropriate access controls, and anything that keeps a revoked session alive, a stateless token or a cache TTL, works against them. That is a compliance concern before it is an engineering one. The Architect kept pointing back to the risks his arithmetic had already named, not the read. Those did not average into one number.

The ADR with preserved dissent

Here is the honest part. The report.md never rendered. The report-format renderer did not write a file, a different failure from the one Issue 9 hit but the same result: no clean machine artifact at the end. So what follows is not a generated report. It is the agents' own findings, assembled by hand, which is the only thing I am willing to show you.

Framed as an ADR:

  • Decision. Keep server-side Postgres sessions. Harden in place. Do not adopt stateless JWT plus a revocation list. Do not add a read-through cache.
  • Assessment. At target scale the per-request session read is a memory-resident indexed point-read, sub-millisecond, with 10–25x headroom before it touches a replica. The feared bottleneck is not where the brief assumed.
  • Key Question, answered. Premature optimization. A cache or a token scheme spends a three-engineer team's scarce capacity to fix a throughput problem the numbers say does not exist, and both quietly trade away instant revocation, a security promise to B2B buyers.
  • Preserved dissent, load-bearing. The read is not the risk. The revocation write-path fan-out is, and it is the least-tested path in the system. Harden the write path. This is the argument that names the failure mode: the day you fire a compromised admin and a stale denormalized role keeps them in.
  • Recorded case against the roads not taken. JWT trades a real security property for throughput you do not have. A cache reintroduces the staleness sessions were chosen to eliminate.
  • Real risks, ranked above the read. Connection-pool exhaustion, hot-path write churn, EU data residency.

A normal ADR launders all of that into one line: "Decided: keep Postgres sessions." This one keeps the counter-arguments attached to the decision, each tied to the situation that would prove it right. That is synthesis, not averaging, pointed at architecture. The Arbiter did not split the difference between keep and rewrite. It committed to the position and kept the disagreement next to it.

An ADR with no dissent section is not a decision. It is a press release.

When to preserve dissent, and when to resolve it

Not every disagreement earns a place in the artifact. Some is noise, and preserving noise just makes the next reader wade through it. The test is whether a dissent is load-bearing: does it predict a specific failure mode under conditions you can name? The Provocateur's write-path argument does. It names the failure (stale role after revocation), the moment it bites (firing someone with live sessions), and the reason nobody caught it (the fan-out is never exercised). That belongs in the ADR permanently, because the day it comes true it is the first place anyone will look.

Bikeshedding does not. Preferences with no predicted failure behind them get resolved in the room and left there. The judgment the review has to make is which is which. It is the same call a good senior engineer makes: what goes in the "considered and rejected" section, and what stays in the meeting notes.

Next

Architecture is where documented dissent earns its keep. Next issue we take the same machinery somewhere it has no business working and watch it work anyway: product and strategy, where the evidence standards are nothing like engineering. Issue 11. The profile is at harness.aos.engineer.

All stories