Skip to content

Architecture Decision Records — Index

This index lists every ADR in ftl-docs/architecture/decisions/.

An ADR captures one decision that shaped the system: what we chose, why, what we rejected, and what we're now committed to maintaining. ADRs are append-only. Once accepted, only status: and superseded-by: may change.

See CHANGE-MANAGEMENT.md at the repo root for the protocol, and _TEMPLATE.md for the required structure.


All ADRs (newest first)

# Title Status Implementation Date Supersedes Superseded by Affects spec
0034 District standings rank by TOTAL member ROI (sum, not average) accepted implemented 2026-06-10 leaderboard
0033 Leaderboard ROI = cumulative per-trade realized ROI; single close-path writer accepted implemented 2026-06-10 0014 leaderboard
0032 Persistent instrument idx + lineup-sourced instrument universe accepted implemented 2026-06-09 amm-pricing, event-ingestion
0031 Event + stat ripple engine (role-weighted, both teams, all event/stat types) accepted implemented 2026-06-09 pricing-ripple-engine, amm-pricing, event-ingestion
0030 Noise engine + trading bot full removal (prices move only from events, stats, trades) accepted pending 2026-06-08 0018, 0021 amm-pricing, event-ingestion
0029 WS broadcast worker pool — Option C, W=16, heartbeat 30s/45s, drop-on-backpressure accepted pending 2026-06-08 realtime
0028 Position-aware 8-knob event propagation (team/opp × GK/DEF/MID/FWD) accepted pending 2026-06-08 0019 event-ingestion, amm-pricing
0027 persistencePct=100 / cooldownSecs=0 locked pricing model (every occurrence counts, no decay) accepted pending 2026-06-08 0025 event-ingestion, amm-pricing
0026 Event Type Registry + Impact Config (unified, registry-driven, hot-reload) accepted pending 2026-06-08 0024, 0025 event-ingestion, amm-pricing
0025 Per-event decay via persistence split (durable vs transient bump) superseded in-progress 2026-06-07 0026, 0027 event-ingestion
0024 Per-event admin config — enable / per-event cap / category superseded in-progress 2026-06-07 0026 event-ingestion
0023 Durable, lossless football-event capture (SP1 reliability layer) accepted in-progress 2026-06-07 event-ingestion
0022 Comprehensive event-bump coverage; key normalisation in EventBump accepted implemented 2026-06-04 amm-pricing
0021 Mean-reverting random-walk noise offset; near-real-time live-match ticks superseded implemented 2026-06-03 0030 amm-pricing
0020 Slippage measured against the published price; idempotency keys released on rejection accepted implemented 2026-06-03 amm-pricing, cfd-pricing-and-wallet
0019 Match-event propagation — team-fallback, opponent drop, durable event_score superseded implemented 2026-06-03 0028 amm-pricing, cfd-pricing-and-wallet
0018 Activity-gated, pattern-based synthetic noise superseded implemented 2026-06-03 0030 amm-pricing
0017 AMM permanent price impact — trades leave a decaying footprint accepted implemented 2026-06-03 amm-pricing, cfd-pricing-and-wallet
0016 Prevent and surface un-closeable zero-price CFD positions accepted implemented 2026-06-03 cfd-pricing-and-wallet, amm-pricing
0015 Durable wallet credit on position close — synchronous absolute PG snapshot accepted implemented 2026-06-03 wallet-and-margin
0014 Leaderboard ROI feed and read repoint — equity-based ROI% via evaluator + close path superseded in-progress 2026-06-03 0033 leaderboard
0013 Minimum hold (anti-flip) — 180 s hold set on OPEN, not post-CLOSE cooldown accepted implemented 2026-06-02 cfd-pricing-and-wallet
0013 Drop the lineupDetailTypes filter on livescores/latest polling accepted implemented 2026-06-02 amm-pricing
0012 Retire POST /api/trade; CFD as sole trading mechanism accepted implemented 2026-06-01 amm-pricing, cfd-pricing-and-wallet
0011 FT freeze must span both legacy auto-sell and CFD close-out steps accepted implemented 2026-06-01 amm-pricing
0010 Phone number policy — format + uniqueness, no SMS OTP accepted implemented 2026-05-22 signup-and-onboarding
0009 Referral attribution — codify v2 economics + wire per-invite tracking accepted implemented 2026-05-22 referrals
0008 Registration profile policy (single-name, age 18+, pre-login referral validation) accepted implemented 2026-05-22 signup-and-onboarding, referrals
0007 Coming-soon enforced as backend hard gate (not frontend-only) accepted implemented 2026-05-22 signup-and-onboarding
0006 Honest washout via backend tick-replay (online == offline outcome) accepted implemented 2026-05-22 amm-pricing, wallet-and-margin
0005 Close all open CFD positions at current_price at Full Time accepted implemented 2026-05-22 0003 amm-pricing
0004 Adopt CFD-style margin trading model (replace buy-and-hold AMM) accepted implemented 2026-05-22 0001 amm-pricing, wallet-and-margin
0003 FT freeze + drain wait + system-sell at flat price superseded implemented 2026-05-22 0005 amm-pricing
0002 Redis Lua for atomic trade execution (vs Service Bus FIFO) accepted implemented 2026-05-22 amm-pricing
0001 Linear bonding-curve AMM (price = base + k × net_shares_sold) superseded implemented 2026-05-22 0004 amm-pricing

Implementation column added 2026-05-22 to distinguish decision accepted from code shipped. See ../../PENDING.md for the un-implemented index and ../../CHANGE-MANAGEMENT.md §"Implementation status" for the convention.


Status legend

  • proposed — drafted, under review, not yet binding.
  • accepted — approved and in force as a decision. (See Implementation column for whether the code reflects it yet.)
  • superseded — replaced by a later ADR. The superseded-by: field links forward.
  • rejected — considered and declined. Kept in the directory as a record so the same proposal isn't re-litigated.

Implementation legend

  • pending — code change not yet shipped. ADR-as-build-guide. Listed in PENDING.md.
  • in-progress — paired code PR is open / merging.
  • implemented — code shipped; ADR matches live behavior.

Adding a new ADR

  1. Find the next number: ls architecture/decisions/ | grep -E '^[0-9]{4}-' | sort | tail -1.
  2. Copy _TEMPLATE.md to NNNN-<kebab-slug>.md. Use a descriptive slug (0004-amm-formula-add-volatility-damper.md, not 0004-changes.md).
  3. Fill in every YAML field. affects-specs: and affects-code: are required.
  4. If this ADR supersedes an older one: set supersedes: NNNN here, AND open the older ADR and set both status: superseded and superseded-by: <this number>.
  5. Add a row to the All ADRs table above (newest first).
  6. Update the affected spec's decisions: frontmatter list and rewrite the relevant section.

Numbers are never reused. Skipping a number (e.g. for a rejected proposal) is fine — keep the rejected file in place with status: rejected.