Skip to content

Pending Implementation — Index

This file lists every ADR or spec that has been decided / designed but not yet implemented in code. It's the single place to look when you want to know "what's the latest un-implemented feature that's been discussed?"

How something gets on this list:

  • An ADR with implementation-status: pending (or in-progress) lives here until its code ships.
  • A spec with status: proposed lives here until it's authored as active against shipping code.

How something leaves this list:

  • The paired code PR merges. In the same PR, the ADR flips to implementation-status: implemented (and any superseded older ADRs get their status: superseded + superseded-by set). Move the row to the Recently shipped section at the bottom of this file (kept for ~6 weeks as historical context, then pruned).

This file is hand-maintained in the same PR as any ADR/spec status change. Future work may script generation from frontmatter — for now, the human-written list is small enough that keeping it in sync is trivial.

See CHANGE-MANAGEMENT.md for the full protocol and the doc change protocol in contributing.md §"Doc change protocol" for the operative rules.


Currently pending (newest first)

ADR / Spec What it ships Implementation status Date queued Owner
ADR-0030 Delete noise engine (noise.go, noise_pattern.go, flusher noise sampling, 3 tests, 10 config fields, NOISE_ENABLED block in YAML, Lua last_noisy_price refs, ws_minimal.js) + delete trading bot engine (internal/bot/, config BotEnabled, main.go wiring, scheduler wiring, trader_bots.js, smart_event_traders.js) + add AND u.role != 'bot' leaderboard filter. Supersedes ADR-0018, ADR-0021. pending 2026-06-08 @amalkrsihna
ADR-0029 hub.go: BroadcastJob type + W=16 worker goroutines + per-frame parallel dispatch + drop-on-backpressure + ws_broadcast_total/drops_total/worker_queue_depth metrics. Heartbeat 30s ping / 45s read deadline on WS connections. WS_WORKER_COUNT env var (default 16). Phase 2: SelectivePriceSubscriber.tsx replaces GlobalPriceSubscriber.tsx; openInstrumentIds/visibleInstrumentIds/viewed instrumentId store additions. pending 2026-06-08 @amalkrsihna
ADR-0028 event_impact_config gets 8 position knobs (team_gk/def/mid/fwd_pct, opp_gk/def/mid/fwd_pct). PropKnobs type + EventPropagationKnobs accessor + canonicalPosition(). applyTeamEventBump rewritten: knob-driven, actor exclusion, always-on team propagation. bumpInstrumentEventSplit fixes G-03 (writes event_score only, not both). isGoalEvent() deleted. event_bump_log gains impact_type/actor_player_id/affected_player_id columns populated by propagation inserts. Supersedes ADR-0019. pending 2026-06-08 @amalkrsihna
ADR-0027 Migration 000052 Step 3: UPDATE admin_settings event_config → persistencePct=100 for all event types (fixes G-12 — critical pre-launch gate). MicroBumpCapPercentOfBase raised 10.0 → 25.0. cooldownSecs=0 code comment added. Verification SQL required post-migration (STOP gate). Supersedes ADR-0025. pending 2026-06-08 @amalkrsihna
ADR-0026 Migrations 000046–000052: event_bump_log extension (+14 audit columns), price_ticks source index, fixture_stat_snapshots table, event_type_registry, event_impact_config (+8 propagation knobs, persistence_pct DEFAULT 100, cooldown_secs DEFAULT 0), event_impact_config_versions (audit log), seed ~128 types with behavior-preserving impact_pct + persistencePct=100. loadEventImpactConfig() hot-reload via admin_settings:changed. auto-register goroutine for unknown types. Admin API: 7 new endpoints. Supersedes ADR-0024, ADR-0025. pending 2026-06-08 @amalkrsihna
ADR-0014 Leaderboard ROI feed: equity-based ROI% via evaluator + close path write, global + district repoint in-progress 2026-06-03 @amalkrsihna

Recently shipped (last ~6 weeks; older entries are pruned)

ADR / Spec What it shipped Date shipped Branch
ADR-0006 Backend internal/margin/ evaluator + tick-replayer. WS reconnect hook (user:reconnect pub/sub) replays price_ticks since last_seen:{userId} and closes any positions that breached 50% at the breach price. 5-minute backstop sweeper catches stranded offline users. Pre-FT replay closes pre-FT washouts at their breach price before the FT snapshot. 2026-05-24 feat/amm-cfd-redesign-v1 (backend), feat/amm-cfd-redesign-v1-impl (docs)
ADR-0005 internal/sportmonks/postmatch.go extended with CFDCloser + MarginReplayer interfaces. positions.Service.CloseAtFTSnapshot enumerates every open position for the FT'd instrument and closes each at the snapshot current_price with reason=auto_exit_ft. Legacy buy-and-hold path runs alongside during rollout. 2026-05-24 feat/amm-cfd-redesign-v1 (backend), feat/amm-cfd-redesign-v1-impl (docs)
ADR-0004 Migrations 000024–000026 (cfd_positions, margin_events, instrument imbalance/k_mod cols). Two new Lua scripts (position_open.lua, position_close.lua) with atomic equity walk + cross-instrument margin checks. New REST surface POST/GET/PATCH/POST /api/positions/... via internal/positions/. SL/TP worker (internal/positions/stopwatch.go) tails price:*. Per-system-close push notifications (washout, SL/TP, FT auto-exit, margin call). FE BookPositionModal + PositionsPage + portfolio WS consumer + API client. 2026-05-24 feat/amm-cfd-redesign-v1 (backend + frontend), feat/amm-cfd-redesign-v1-impl (docs)
ADR-0010 Partial UNIQUE index on users.phone (legacy empty rows allowed); 409 phone_taken error path on duplicate. Closes the "one phone, N accounts" abuse vector. No SMS OTP — explicit cost/UX trade-off. 2026-05-22 feat/pre-reg-backend, feat/pre-reg-frontend, feat/pre-reg-docs
ADR-0009 Frontend: fixed 3 misleading "+500 bonus" strings to match v2 economics (referrer-only, on first trade). Removed the fake WelcomeCelebration referee toast. Wired ?invite=<id> end-to-end alongside ?ref= so per-link analytics works. Backend already correct — pure FE work + comment tightening in bonus.go. 2026-05-22 feat/pre-reg-backend, feat/pre-reg-frontend, feat/pre-reg-docs
ADR-0008 Single-name registrations allowed (BE drops empty-lastName check; FE tightens nameLock to split.first && split.last). Age min 18, no upper bound (both tiers). New public route GET /api/public/referral/validate that the form calls on debounce. 2026-05-22 feat/pre-reg-backend, feat/pre-reg-frontend, feat/pre-reg-docs
ADR-0007 New Fiber middleware ComingSoonGate(store, allowAdmin=true) on the protected route group (returns 503). Frontend gate stays as UX layer. Closes the curl-around-frontend gap and resolves the tutorial-vs-coming-soon redirect loop as a free consequence (FE guards added in Register.tsx, TutorialOverlay.tsx, App.tsx). 2026-05-22 feat/pre-reg-backend, feat/pre-reg-frontend, feat/pre-reg-docs
ADR-0021 Mean-reverting noise walk: offset carries across pattern windows, gentle global reversion offset -= offset/tauTicks (NOISE_MEANREVERT_MINUTES env, default 10; 0 disables), noiseOffsetClamp tightened 0.25 → 0.08, NOISE_DELTA_SKIP_PCT default 0 (was 1%), processPlayerStats stamps live_match_until=now+30s instead of HDELing noise_pattern_*. 2026-06-03 feat/noise-mean-revert-docs (docs), feat/noise-mean-reverting-walk (backend)
ADR-0020 Slippage measured against last_published_price (fallback last_noisy_priceserver_price); tolerance default 0.5% → 2.5% (TRADE_SLIPPAGE_TOLERANCE_PCT); reject() helper DELs freshly-claimed idem key on every pre-mutation rejection so retries re-evaluate cleanly; ErrDuplicateInFlight → 409; ErrInvalidSLTP → 422; post-close equity-snapshot loop is best-effort (skips evicted siblings); client mints fresh clientRequestId on PRICE_MOVED. 2026-06-03 bug/trade-slippage-idempotency-docs (docs), bug/trade-price-moved-500 + bug/trade-price-moved-retry (backend)
ADR-0019 Match-event propagation: team-fallback goal bump, opponent drop, durable event_score field written into the instrument hash on every goal/card event. 2026-06-03 feat/noise-and-event-propagation-docs (docs), feat/event-propagation + feat/reactive-event-markers (backend)
ADR-0018 Activity-gated, pattern-based synthetic noise engine; live_match_until gate replaces the old HDEL approach for live-match players. 2026-06-03 feat/noise-and-event-propagation-docs (docs), feat/noise-activity-gate + feat/noise-pattern-engine (backend)
ADR-0017 AMM permanent price impact: permanent_impact accumulator written on each trade, k_mod default 0.01 → 0.05, flusher decay loop. 2026-06-03 feat/amm-permanent-impact
ADR-0016 Zero-price position guard in Lua + Go + schema; closeErrorStatus returns 409/503 instead of 500 for zero-price and corrupt-state paths. 2026-06-03 bug/cfd-zero-price-stuck-position
ADR-0015 Durable wallet credit on close: synchronous absolute Postgres snapshot on every close, eliminating the async-flush gap that could leave wallet balance stale after a crash. 2026-06-03 Remediation 2026-06-02 (#26)
ADR-0013 (cooldown) 180-second minimum hold set on OPEN (not post-CLOSE): position_open.lua sets last_open:{userId}:{instrumentId} with 180s TTL; position_close.lua rejects early user-close if key active. System closes (SL/TP, washout, FT auto-exit) bypass the hold. 2026-06-02 Remediation 2026-06-02 (#26)
ADR-0013 (filter) Drop the lineupDetailTypes filter on livescores/latest polling: Sportmonks v3 enforces a 50-integer cap on filter lists; dropping the filter avoids silent truncation. 2026-06-02 feat/drop-livescores-filter (#25)
ADR-0012 Retire POST /api/trade; CFD margin trading (POST /api/positions/open) is now the sole trade-execution mechanism. Legacy buy-and-hold endpoint removed from routes. 2026-06-01 feat/retire-legacy-trade (#23)
ADR-0011 FT freeze must span both legacy auto-sell and CFD close-out steps: the freeze flag is set before both liquidation passes and released only after both complete, preventing a race where a new open sneaks in between. 2026-06-01 feat/ft-freeze-spans-both-liquidation-steps (#21)

Known issues (Sportmonks upstream, not in scope)

These are upstream data gaps in the Sportmonks plan — they are not application bugs and have no code fix:

  • Goal / card event feed empty for some fixtures. Sportmonks does not supply goals and cards for every fixture on the current plan. The events array may be absent or empty for affected matches.
  • Per-player long-ball / aerial / tackle stats absent for U18 competitions. These stat types are not included in the Sportmonks plan for under-18 fixtures. aggregateTeamStats omits these keys for U18 matches — expected behaviour.
  • Kazakhstan U18 squad has 0 players. The squad is absent from the Sportmonks plan. HydrateRedis will find 0 instruments for this team; the Stadium screen will be blank for these players.

Why this file exists

The change-management system (Living Spec + ADR + per-commit walkthrough) is excellent at capturing the history of what was decided and the current truth of what runs. It was less good at answering the question: "what's been designed but not yet built?" A contributor browsing architecture/decisions/ could see ADRs with status: accepted but couldn't tell from the status alone whether the code reflecting them had landed yet.

PENDING.md is the answer. One place to look. The frontmatter field implementation-status: pending on each ADR is the source of truth; this file is the index.