Skip to content

Architecture Decision Records

This directory is the decision layer of data-lab. The running services prove the infrastructure works; these records explain why it is shaped the way it is. They are the part of the project that demonstrates architecture judgment rather than implementation — a documented choice, the alternatives weighed, and the consequences accepted.

Why ADRs

An Architecture Decision Record captures one significant, hard-to-reverse decision at the moment it is made: the forces in play, the options considered, the option chosen, and the tradeoffs that come with it. The value is not the conclusion — it is the reasoning, preserved so that a future reader (including future-me, or a reviewer) can understand the decision without reconstructing it, and can tell whether it still holds when the context changes.

A decision is ADR-worthy when it is significant (it constrains later work), cross-cutting (it affects more than one component), and costly to reverse. Routine, local, or easily-undone choices do not need a record.

Conventions

Numbering — sequential, zero-padded, never reused: 0001, 0002, … The number is an identifier, not a priority.

Status lifecycle — every ADR carries one of:

Status Meaning
proposed Drafted, not yet ratified. Open for revision.
accepted In force. This is how the system is built.
superseded by ADR-XXXX Replaced by a later decision. Kept for history.
deprecated No longer relevant, but not directly replaced.

Immutability — an accepted ADR is not edited to change its decision. If the decision changes, write a new ADR that supersedes it and update the old one's status. The history of decisions is itself information; rewriting it destroys that.

Index

ADR Title Status
0001 Single-node Docker Compose, no orchestrator accepted
0002 Traefik v3 as the edge reverse proxy with automatic TLS accepted
0003 Direct public exposure on a Hetzner VPS over Cloudflare Tunnel accepted
0004 HTTP-01 over DNS-01 for ACME certificate issuance accepted
0005 Monorepo with per-project plug-in to a shared CI/CD pipeline accepted
0006 Scheduled micro-batch as the media pipeline's default path, streaming built as the priced alternative accepted
0007 The streaming side is poll-fed, and we say so superseded by ADR-0015
0008 Redis Streams as the broker; no Kafka accepted
0009 Ephemeral comparisons as in-process run windows, not container spin-ups accepted
0010 Public triggers are rate-limited, capped, and shared accepted
0011 Same-origin /api on the apex: the one exception to the flat-subdomain scheme accepted
0012 Minimal dbt: a contract and four models, no medallion ceremony proposed (accept in CP13)
0013 Postgres + DuckDB dual engine, and what makes the benchmark fair proposed (accept in CP13)
0014 Exhibit resource numbers come from Prometheus, not a bespoke agent accepted
0015 Wikimedia EventStreams + Hacker News replace Twitch as the media pipeline's data sources accepted

Note: ADRs 0001–0005 record decisions already implemented and locked during CP1–CP4; they were written up (retroactively, as is normal for foundational choices) and added to this index during the CP9 documentation pass. ADR-0006, 0008–0010, and 0014 were accepted in CP10 once CP10.1–10.4 had actually implemented and live-verified each decision (batch/streaming both live, Redis Streams as the broker, in-process Redis-backed run windows, rate limiting, Prometheus reuse) — none needed their figures changed from proposal to implementation, only the status flip.

Note: Twitch developer-console registration was confirmed permanently blocked (Morocco) after CP9 shipped. ADR-0015 replaces Twitch with Wikimedia EventStreams (CP10's batch/streaming substrate) and the Hacker News API (CP12's sync/async substrate); ADR-0007, whose entire premise was a property of Twitch specifically, is superseded by it.