The Proposal Was Technically Correct. That Was Not Enough.
A Technical Lead with a defensible architecture proposal. Three named pushbacks from three different angles. The first ADR a program ever writes is the one that decides what an ADR is for.
A Better Architecture Is Not Always a Better Decision.
Priya Raman walked into the Tuesday architecture sync with three slides and a recommendation. Replace Kafka and RabbitMQ. Move to Apache Pulsar. The argument was well-prepared and substantively serious: tiered storage would solve a retention problem Falcon had not yet hit but would eventually face; native multi-tenancy would simplify the per-market deployment model that already strained the Hazelcast layer; the unified pub-sub-and-queue model would collapse two operational footprints into one. Raman did not propose this lightly. She had been thinking about it for six weeks.
The room reacted the way technically capable rooms do when a competent proposal lands: the engineers leaned forward. Pulsar's case is real. Its production deployments at scale are growing. Falcon was eight months from go-live in Market A and Raman was raising the question of whether the messaging architecture in front of them was the messaging architecture that should ship.
Replace Kafka (currently carrying audit and regulatory event streams) and RabbitMQ (currently carrying service-to-service async traffic) with a single Apache Pulsar deployment. Justification: tiered storage, native multi-tenancy, unified semantics, smaller operational surface area. Source: Priya Raman, Technical Lead. Forum: weekly architecture sync, 19 August 2025. Pre-circulated as a 3-slide deck the previous Friday.
Three pushbacks landed within the first twenty minutes, from three different angles, and none of them disputed the technical case. Jin-ho Park (Development Lead) spoke first, with the operational position. Abebe Alemu (CTO) followed, citing the program charter. Dmitri Volkov (Platform Integrator Lead) closed, with the contract.
Five Dimensions, One Sufficient Answer.
The PM’s job in this room was not to decide on technical grounds. Raman was the technical authority on messaging architecture; her judgement on Pulsar versus Kafka in isolation deserved deference. The PM’s job was the harder one: to evaluate whether technical merit was sufficient to overturn an in-flight build, when operational maturity, contract scope, and audit posture were each carrying weight in the other direction.
The PM put a five-row comparison on the whiteboard the same afternoon. The dimensions were not chosen to favour the answer. They were chosen because every prior pushback had named one of them.
| Dimension | Current Stack — Kafka + RabbitMQ | Proposal — Apache Pulsar |
|---|---|---|
| Operational maturity | Production-stable, 12 months. Known failure modes; on-call runbooks complete; team fluency proven across 19 services. | Bank-grade adoption emerging. Falcon team has zero operational experience; runbooks would be authored from scratch under Phase 2 pressure. |
| Refactor cost | Zero incremental. All 19 services already integrated; no migration work. | $180–260K internal, 3 sprints. Producer/consumer semantics rewrite across 19 services (Park estimate, 19 August). |
| Contract scope | In scope. PI-2024-11 cl. 4.1 explicitly covers Kafka and RabbitMQ delivery. | Out of scope. Scope amendment estimated $90–140K plus 6–8 week renegotiation (Volkov, indicative). |
| Regulatory audit posture | Cleared. Audit firm SA-2025-03 has signed off on Kafka audit-event flow against Market A Tech Audit Standard 4.7.2. | Re-attestation required. Estimated 6-week regulatory loop; collides with Phase 3 UAT window starting 1 January 2026. |
| Revisit signal | Not applicable. Status quo is the baseline. | Open door, future window. Post-go-live architectural review (Q3 2026 or later) with v1 production telemetry as input. |
On four of five dimensions the current stack outperformed the proposal at the present date. The fifth dimension, revisit signal, was not a Pulsar advantage on the spot: it was the discipline of leaving the door open. Within an hour of the matrix being on the table the substantive decision was clear. The harder question was what to do with the proposal itself.
How Do You Reject Something Without Erasing It?
Falcon had been making architectural decisions for seven months without writing any of them down as architectural decisions. The Kubernetes sizing debate (Post 02) was paged through steering minutes. The R07 indexing decision (Post 10) lived in the risk register. The observability ownership split (Post 11) lived in the RACI. Each of those artifacts did its own job. None of them was a decision record per se. Ahmed Hassan (PMO Lead) raised the gap during the prep call.
Park’s pushback was operational, not principled.
The resolution went out by Slack the same evening. Five sections, one page (front-and-back at most), five-business-day review cycle, status field with four values. Hassan custodian. Alemu signs as Accountable for architecture decisions per the Post 11 RACI; Raman or proposing technical lead signs as Responsible for the draft. ADRs are required for any cross-cutting architectural change touching more than one service or one infrastructure tier.
Status field convention: Proposed, Accepted, Rejected, Superseded. Five-day review cycle. Single-page template (Status, Context, Decision, Consequences, Alternatives, Revisit). Custodian: Hassan. Accountable signer: Alemu (architecture). Responsible drafter: proposing lead. Storage: Confluence under Architecture / Decisions. Numbering: ADR-001 onward, never reused.
For ADR drafting the prompt uses Before-After-Bridge. BAB has lighter adoption than CRAFT or RISEN; it earns its place here because the artifact’s own structure mirrors BAB exactly. Context is Before. Decision is After. Consequences are the Bridge that links the two. The lighter framework matches the lighter artifact. The principle from Post 11 holds: framework complexity should match task complexity, not exceed it.
A Competent Draft With Three Things Missing.
The AI returned a workmanlike ADR draft within ninety seconds. Five sections, present tense, contract clauses cited inline as instructed, no invented detail. As a structural baseline the draft was usable. As a decision artifact for a regulated banking program it was three things short, and the AI itself flagged one of them.
Status: Rejected.
Context: Project Falcon currently runs Apache Kafka for audit and regulatory event streams and RabbitMQ for service-to-service async traffic. Both have been production-stable for 12 months across 19 microservices. On 19 August 2025 Priya Raman (Technical Lead) proposed replacing both with Apache Pulsar.
Decision: Atlas Bank will not adopt Apache Pulsar.
Consequences: Falcon retains the current messaging architecture. The 3-sprint refactor cost is avoided. The integrator contract PI-2024-11 remains in scope. The audit firm sign-off against Market A Tech Audit Standard 4.7.2 remains valid.
Alternatives Considered: Apache Pulsar was evaluated and not adopted. Status quo retained.
The AI’s flag was correct and the human-written prompt had not asked for it. The PM had specified five sections; the AI noticed that a sixth was operationally necessary. This is the kind of catch that justifies the AI in the loop in the first place. It also exposed two further gaps the AI did not flag.
The Decision sentence (“Atlas Bank will not adopt Apache Pulsar”) was technically true and operationally ambiguous. It did not say when or under what conditions the door was closed. The Consequences block listed four positive outcomes (cost avoided, scope preserved, sign-off intact, refactor avoided) but assigned no owner to any of them. And the Alternatives section was a single sentence treating Pulsar versus status quo as the only two options, when a hybrid pilot in a non-critical service was a third option that the prep conversation had explicitly considered.
The AI produced a draft. The human shaped it into a decision record.
Architecture Decision Record — 001.
Project Falcon runs Apache Kafka for audit and regulatory event streams and RabbitMQ for service-to-service async traffic. Both have been production-stable for 12 months across 19 microservices. The audit firm SA-2025-03 has cleared the Kafka audit-event flow against Market A Tech Audit Standard 4.7.2 (sign-off 14 July 2025). Integrator contract PI-2024-11 cl. 4.1 scopes vendor delivery explicitly against the current stack.
On 19 August 2025 Priya Raman (Technical Lead) proposed replacing both systems with a single Apache Pulsar deployment, citing tiered storage, native multi-tenancy, unified pub-sub-plus-queue semantics, and reduced operational surface area.
Atlas Bank elects to retain Apache Kafka and RabbitMQ as the Project Falcon messaging tier for the duration of Phase 2 (Build and Integration) and Phase 3 (UAT and Certification). The Pulsar proposal is rejected as an in-flight architectural change. The decision is not a permanent verdict on Pulsar; it is a verdict on Pulsar at this point in the build, against the operational, contractual, and regulatory state recorded in Section 1. The proposal is preserved for revisit per Section 6.
No 3-sprint refactor of producer/consumer semantics across 19 services. Sprint capacity remains directed at M3a/M3b integration. Existing Kafka and RabbitMQ runbooks remain authoritative; on-call rotation unchanged.
Owner: Park (Dev Lead)$180–260K internal cost avoided. $90–140K integrator scope amendment avoided. No drawdown against unallocated reserve ($328K, per Post 09 Financial Plan). Phase 2 budget envelope unchanged.
Owner: Richter (CFO)PI-2024-11 cl. 4.1 remains in scope with no amendment. Audit firm SA-2025-03 sign-off against Tech Audit Standard 4.7.2 remains valid. No re-attestation loop pre-UAT.
Owner: Volkov / Okonkwo| Option | Summary | Verdict |
|---|---|---|
| A · Status quo | Retain Kafka + RabbitMQ. No change to architecture, contract, or audit posture. | Adopted |
| B · Full Pulsar migration | Replace both systems with Apache Pulsar across all 19 services in Phase 2. | Rejected: 4-of-5 dimensions unfavourable; refactor and contract costs not budgeted; audit re-attestation collides with UAT window. |
| C · Hybrid pilot | Pilot Pulsar in a single non-critical service while retaining Kafka and RabbitMQ elsewhere. | Deferred to revisit window: pilot in production-equivalent conditions cannot be cleanly bounded inside Phase 2; defer to post-go-live (Section 6). |
Proposed draft circulated for 5-day review. Accepted ratified at architecture sync; logged in Confluence under Architecture / Decisions. Rejected not adopted; preserved with revisit trigger. Superseded replaced by a later ADR; both ADRs cross-referenced.
This ADR is revisited at the post-go-live architectural review (Q3 2026 or later, after 3 months of v1 production telemetry from Market A). Revisit may also be triggered earlier by any one of: (a) a sustained operational issue with Kafka or RabbitMQ that cannot be resolved within the existing operational envelope; (b) integrator contract renewal cycle (PI-2024-11 expires Q2 2027); (c) Pulsar production maturity reaching bank-grade adoption thresholds defined by Alemu and Raman. The new evaluation will use v1 production data, not architectural argument.
- Added Revisit Trigger as a first-class section. AI flagged the gap; PM made it Section 6 of the template, not an appendix. Rejection without revisit conditions becomes permanent by inertia. The trigger names three specific conditions that re-open the decision and the evidence type required (v1 production data, not architectural argument).
- Expanded Alternatives from one sentence to a three-option matrix. AI treated Pulsar versus status quo as the only options. PM added Option C (hybrid pilot in a single non-critical service), which had been raised in the prep conversation and was the most defensible middle path. Documenting it as Deferred (not Rejected) preserves it for the revisit window.
- Split Consequences into operational, financial, contractual. AI listed four positive outcomes in flat prose with no ownership. PM split into three blocks with named owners (Park, Richter, Volkov / Okonkwo) and made each consequence checkable rather than declarative. Consequences without owners do not get verified.
- Added the Status Field Convention as a permanent template element. AI used Status: Rejected as a label. PM made the four-value vocabulary (Proposed, Accepted, Rejected, Superseded) part of every ADR going forward, with explicit semantics for each. ADR-001 is the first record; the convention is meant to be the first habit.
- Tightened Decision wording to remove permanence. AI wrote “Atlas Bank will not adopt Apache Pulsar.” PM rewrote to “retain the current stack through Phase 2 and Phase 3 ... not a permanent verdict on Pulsar; a verdict on Pulsar at this point in the build.” The original sentence closed the door. The replacement documented it.
Twelve months after Market A go-live, ADR-001 will be re-opened in the Lessons Learned review. By then Kafka and RabbitMQ will have a production track record under real customer load: clean, partial, or degraded. If clean, the rejection is reaffirmed and the ADR closes with new evidence. If partial or degraded, Option C (hybrid pilot) re-enters the conversation with v1 telemetry as input rather than architectural argument. Either path is the ADR working as designed. An ADR that prevents a future re-litigation is the ADR earning its keep.
A fictional case study for teaching purposes. Atlas Bank, Project Falcon and all named individuals are invented. Technologies are industry-standard and publicly available.