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(orin-progress) lives here until its code ships. - A spec with
status: proposedlives here until it's authored asactiveagainst 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 theirstatus: superseded+superseded-byset). 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_price → server_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.
aggregateTeamStatsomits these keys for U18 matches — expected behaviour. - Kazakhstan U18 squad has 0 players. The squad is absent from the Sportmonks plan.
HydrateRediswill 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.