keel Roadmap — read from the repo, refreshed hourly
This page is a read of the project's own working plan — the milestones on GitHub and the issues under them, exactly as the repo tracks them. Every item links to its issue, where discussion already happens; nothing here is voted on, and nothing here can be bought ahead of anything else.
An open milestone is an intention, not a commitment, and a date on one is a target, not a promise. Work ships when it is honest to say it shipped — the changelog records what actually landed.
The journey so far
Every closed milestone, oldest first — the project's history read straight from the repository, dated by GitHub on the day each phase actually finished. No narrative was written after the fact; this is the record.
July 2026
-
Safety hardening — USDC, allowance, bypass-arm
USDC-funding rail (no bank/ACH draw), monthly subscription-allowance rail, and bypass-arming hardening.
View this milestone on GitHub → -
Engine validation & trade simulation
5yr historical trade simulation of the deterministic engine: edge test + realistic $500/mo account, risk-adjusted vs DCA benchmark, GO-LIVE/TRAIN-MORE verdict + gap-analysis backlog.
View this milestone on GitHub → -
Account-model reconciliation + tier/fee analysis
20% taker <$1k vol) + subscription costs -> net-P&L matrix.
View this milestone on GitHub →
August 2026
-
Phase 1 — Offline foundation
DB + CSV import + P&L + analysis primitives + market feed.
View this milestone on GitHub → -
Phase 2 — Rules, CTS engine, backtest, paper gate
Rule library + CTS confluence scoring + backtest + paper-trade + promotion/demotion.
View this milestone on GitHub → -
Phase 3 — Execution, rails, agent loop (confirm)
Executor + 12 hard rails + scheduled agent loop in confirm mode.
View this milestone on GitHub → -
Phase 4 — Autonomy, money mgmt, insights
Bypass mode + smooth-ratio money management + insights + journaling.
-
Phase 6 — Open source: licence & discoverability
BLOCKING. The repo is public but legally all-rights-reserved: no LICENSE, no description, no topics.
View this milestone on GitHub → -
Phase 7 — Open source: contributor readiness
Make contributing possible for someone who is not the author.
View this milestone on GitHub → -
Phase 8 — Open source: scholarly grounding & launch
What converts 'someone's trading bot' into something a Muslim developer can trust: the fiqh basis written down, a scholarly review path, Arabic entry point, then announce — in that order, never before.
-
Phase 9 — Execution & backtest fidelity
Make the simulator and the live executor agree with reality.
View this milestone on GitHub → -
Phase 10 — Evidence pipeline: cadence, pooling & measurement
20 trades per asset-year, min_trades=100 takes 31–84 years — the promotion gate is arithmetically unreachable.
View this milestone on GitHub → -
Phase 13 — TUI: the operator console
py 3000→1434 lines, parity+isolation pins), C2 #388 (console shell, guarded profile switching, the session banner with the MarketSchedule port extension), C3 #389 (compliance menu, the scout-results admission handler,…
View this milestone on GitHub → -
Phase 14 — Self-update: the console keeps the deployment current
CLOSED 2026-08-19 — #415 delivered in PR #417: the in-console self-updater.
View this milestone on GitHub → -
Desktop distribution — keel for non-technical users
A first-time user downloads one file, installs, and reaches a working keel without typing a command.
View this milestone on GitHub → -
Strategy-API expressiveness (Jesse comparison)
Outcome of the 2026-08-23 comparison against the Jesse framework's strategy API.
View this milestone on GitHub → -
Web UI — a zero-dependency, view-source console
py's server-side HTML with a JSON API plus plain ES modules.
View this milestone on GitHub → -
Reach & surfacing (deferred)
Work whose value depends on having an audience: MCP surfacing, the site AI page, homepage claims.
View this milestone on GitHub → -
v0.11 — Ship the browser, the app, and WAL
0. 11+ plan: deepen the moat (auditability, the gauntlet, compliance) while attacking the real bottlenecks — statistical throughput and fee economics.
View this milestone on GitHub → -
Phase 11 — Evidence expansion & operational guardrails
Phase 11 — Evidence expansion & operational guardrails.
View this milestone on GitHub → -
Phase 13 — Binance (keel-broker-binance)
A fifth venue, and the first added for a REASON the repo already states rather than for reach.
View this milestone on GitHub → -
Competitive parity — validation & reach
7, ranked. Organising principle: every competitor's validation tooling is a diagnostic the user may ignore; keel's promotion gate refuses.
View this milestone on GitHub →
September 2026
-
The honest cockpit (dashboard)
The Alpaca-audit dashboard pass.
View this milestone on GitHub → -
v0.14.0 shakedown
0 on the deployment turned up: the MCP un-migrated guard (#751), two console bugs found testing it (#754, #755), and the launchd console daemons plus keel open (#756).
View this milestone on GitHub →
October 2026
-
Console — four engine views
Slim the local web console from 13 screens to Pulse, Holdings, Rules, Audit & Setup; drop venue-mirror data; add the browser Halt.
-
DCA sleeve — lifecycle design
In progress — open milestones
-
Phase 5 — Broker port & second venue
Wire the keel.brokers registry to the live path so a second venue is reachable. Covers the Robinhood adapter's remaining prerequisites, venue visibility/capability gating, and retiring the hardcoded CoinbaseClient in _build_broker.
- done Robinhood best_bid_ask is not a coherent book snapshot — the legs cross on the most liquid pairs #413
- open Robinhood: order-object shapes are still doc-only — one real order is needed to verify them #412
- done Robinhood transport: no backoff against a 100 req/min limit, and 429 propagates as a bare HTTPError #411
- done Robinhood: no pre-flight sizing check, so a sub-minimum or off-increment order finds out at the venue #410
- done Broker port: place_order has no idempotency key, so any retry places a second live order #409
- done Venue visibility must be capability-based, not key-presence-based — a read-only key looks identical to a working one #233
- done Robinhood STATE_TO_PORT_STATUS omits partially_filled — latent, not currently harmful #226
- done Validate the Robinhood adapter's invented fixture shapes against the live venue #215
- done Assess US equities as a tradeable asset class for keel (Coinbase or any other broker) #214
- done Robinhood: declare the quote-sized-entry gap rather than approximating it #207
- done Assess Trade Nation (tradenation.com) as a candidate broker for keel #204
- done Assess cTrader Open API (openapi.ctrader.com) as a candidate broker for keel #201
- done Prerequisites before wiring Robinhood to the live execution path #198
- done Robinhood: fees_usd is always 0, so subscription-lapse detection is inert against this venue #197
- done Robinhood adapter: close the independent review findings #196
-
Phase 12 — Stocks via Alpaca (keel-broker-alpaca)
US equities through the broker port: a keel-broker-alpaca adapter (Alpaca Trading API, paper first) that passes the port conformance suite with zero changes to the engine core, an equities paper profile accruing hash-chained evidence, and a cost-fidelity restatement (regulatory fees, spread, data tiers) benchmarked against DCA on the same tickers. PRD: docs/superpowers/specs/2026-08-18-keel-broker-alpaca-prd.md Lineage: Phase 5 — Broker port & second venue (milestone 8; #233 capability-based venue visibility and #198 Robinhood live-path prerequisites remain open there and interact with this work). Hard constraints carried from the PRD: long-only spot, cash accounts only (no margin — riba; also sidesteps PDT's margin threshold), per-(venue, instrument) attested screening with operator-supplied classifications, no live path in any phase.
- done Alpaca options: verify the venue reality before any commitment — agreement, cash-account support, multi-leg, assignment events #636
- open Route within fee-free allowances across venues — rail 14 is the boundary, never a budget to relax #478
- done keel update cannot update an Alpaca deployment — the equities profile is outside PRODUCTION_WHEEL_PREFIXES #425
- done Trademark & originality posture: venue disclaimers and contribution licensing rules #379
- done Cash-account posture: encode and document no-margin / PDT-adjacent constraints #372
- done keel-broker-alpaca Phase C: cost-fidelity restatement + DCA benchmark on equities #371
- done keel-broker-alpaca Phase B: equities paper profile, attestation semantics, runbook #370
- done keel-broker-alpaca Phase A: adapter package + port conformance suite green #369
-
Phase 14 — Analysis feed (Ibn Khaldun Analyzer)
Consume Ibn Khaldun Analyzer's assessments as candidate proposals a human attests. The Analyzer proposes; keel's existing deterministic gate decides. Nothing new touches admission, sizing, or order placement. PRD: docs/superpowers/specs/2026-08-27-analysis-feed-prd.md SRD: docs/superpowers/specs/2026-08-27-analysis-feed-srd.md GATED: the machine-readable fields keel needs (asset, sources[]) live in the Analyzer's `signal` block, which is the Desk tier boundary. Desk tier or the integration does not work. Everything after Phase A depends on that decision.
- open Analysis feed C3: the keep-paying decision — measure it, publish it either way #578
- open Analysis feed C2: the operator guide — including the sentence about attesting out of persuasion #577
- open Analysis feed C1: the safety pins — AST scans that outlive the unit tests #576
- open Analysis feed B4: entitlement visibility — a lapse must not read as market quiet #575
- open Analysis feed B3: `keel analysis fetch` — writes a shortlist the existing `assets propose` already reads #574
- open Analysis feed B2: the frame→Candidate adapter — pure, and narrower than the payload #573
- open Analysis feed B1: bounded SSE client on urllib — stdlib only, not a daemon #572
- open Analysis feed A2: `analysis_feed:` config and credential — not `subscription:`, which is rail 14 #571
- open Analysis feed A1: decide the tier — measure crypto relevance before buying Desk #570
-
Deferred — awaiting a named trigger
Work deliberately NOT started, each with a written trigger that would reopen it. This milestone exists so deferred work stays tracked without being counted as in-flight — closing these issues would delete the trigger, which is the thing worth keeping. See each issue for its own condition.
- open Monetisation rail: self-hosted non-custodial BTCPay — crypto-only, USD-priced, prepaid-credit subscriptions #638
- done ADR 0005 — the options decision: amend the constitution (cash-secured, exception-gated) or hold the line at cash-spot #637
- done The MCP server is invisible: README mentions it zero times in 212 lines #600
- open Binance BNB fee discount: an allowlist admission, not a settings toggle #568
- open keel-broker-binance Phase C: cost-fidelity restatement — does 0.1% make the intersection non-empty? #567
- open keel-broker-binance Phase B: paper profile, rail-17 attestation semantics, runbook #566
- open keel-broker-binance Phase A: adapter package + port conformance suite green #565
- open Binance: decide which entity, and whether USDT becomes a settlement currency #564
- done Opt the promotion gate into per-product slippage — prerequisite-gated on a thin-asset candidate or a load-bearing restatement #335
- open Route a rule's conditional entry as a genuine resting order (limit/stop) — deferred until a price-conditional rule earns it #333
-
Anywhere access (Phase B)
The mobile wedge: keel link, remote-exposure security, the mobile-first PWA pass, ceremony card, Web Push. Nothing here is audience-gated — it is free-product value that later tiers sit on. Plan: docs/evolution-plan.md §5 Phase B.
-
DCA plan — proposal CLI and read-only card
keel dca plan: a proposed multi-asset DCA schedule from the allowlist, admission, target weights and rail 14's buy cap; [Y] writes candidate rules only. Read-only proposal card under /rules.
- done DCA card: a degraded rail 14 cap is shown without its reason #852
- done DCA card: awaiting-state command template omits the served deployment's --config/--db #851
- done PR feat(web): read-only DCA plan card on /rules #850
- done dca plan: a duplicated allowlist entry doubles that asset's weight and writes two DCA rules for it #849
- done dca plan: target_weights keys differing only in case collapse silently #848
- done dca plan: cap check uses an average month; rail 14 caps the calendar month, so 5-buy months veto #847
- done PR feat(dca): keel dca plan -- propose a DCA schedule within the venue plan's cap #846
- done test_rule_manifest still pins the DCA rule budget to config.dca.budget_usd after #840 #844
- done PR fix(executor): size each DCA buy from the rule's own amount (#840) #843
- done PR fix(rails): exempt DCA buys from the total-exposure rail; rail 14 bounds DCA (#841) #842
- done fix(rails): exempt DCA buys from the total-exposure rail; rail 14 bounds DCA #841
- done fix(executor): live DCA spends config dca.budget_usd ($50) instead of each rule's own amount #840
- open keel asset onboard: one guided flow for declare → attest → allowlist → fetch/screen, ending at a candidate rule #839
-
DCA sleeve — limits and ops
- done PR fix(dca): the passing-value suggestion clears rails 3 and 2 as well as 14 (#874) #876
- open With an unlimited rail-14 record, cash is DCA's only aggregate bound -- say so, and warn in dca plan #875
- done keel dca plan: the rail-14 suggestion can name a value rail 2 or rail 3 still blocks #874
- done DCA plan screen cache ignores allowlist edits for up to its TTL #873
- done dca plan: at $0 headroom the rail-14 suggestion names a budget/buffer where every per-buy rounds to $0.00 #872
- done dca plan: rail 5 warning says it 'may never veto', but multi-asset DCA plans are vetoed every cycle #871
- done PR feat(web): cache the DCA plan's admission screen for 5 minutes (#856) #870
- done PR fix(rails): exempt DCA buys from rail 6; dca plan checks rails 3 and 5 (#853) #869
- done PR feat(dca): a cap-blocked plan names the largest passing budget and buffer (#854) #867
- done PR chore(deploy): sync live-rules.json with the live rule set (#855) #858
- done Cache the admission screen behind /api/dca-plan (5-minute TTL) #856
- done Sync deploy/live-rules.json with the live rule set #855
- done keel dca plan: a cap-blocked plan names the largest budget and buffer that would pass #854
- done DCA concentration: exempt DCA buys from rail 6, and warn in keel dca plan on the rails that still bind #853
-
DCA sleeve — sell side build
- done [Phase 6] Declared close's phantom exposure returns on the product's next BUY (R33 zeroes only while flat) #943
- done [PR #939] The SKIPPED exit-watch line points to keel doctor, which crashes on the same non-mapping record #942
- done [PR #939] keel dca exit --preview crashes on an out-of-range observed_at in a sleeve_exit record #941
- done [PR #939] Two SleeveExit rules on one product: the proposal and the exit watch disagree about a breach #940
- done PR feat(rules): sleeve_exit, preview-only (#857) #939
- done [PR #937] Exit watch judges a cold-cache product (PAXG tranche 3) on one daily bar and reports clear #938
- done PR feat(execution): the sleeve exit monitor -- transition alerts, doctor, keel dca exit --preview (#857) #937
- done PR feat(rules): profit_take in preview, and --view gain as trim's default (#857) #936
- done PR feat(dca): keel dca trim --preview --view lots and --view bands (#857) #935
- done test(sleeve_report): cover render_replay's "the rule proposed nothing" line #934
- done test(rules): cover _sleeve_lookahead's cross-truncation divergence dedup #933
- done sleeve_sell lookahead: n_compared counts a truncation whose claim sits below warmup, which is never compared #932
- done Tests: sleeve_sell promotion refuses when the lookahead harness raises #931
- done Tests: run_proposal_replay's dca-rule selection, no-config branch and granularity refusal #930
- done sleeve_sell promotion: a lookahead check that compared nothing reads as clean #929
- done PR feat(promotion): the sleeve_sell gate, proposal replay, proposals review, --allow-concurrent-dca (#857) #928
- done PR fix(deps): pyjwt 2.13.0 -> 2.14.0 (CVE-2026-102274) #927
- done [PR #922] account sim crashes on a sell-all distribution: refusal holding re-sums qty above the lot #926
- done [PR #922] sim reports still say the DCA sleeve is never sold; HTML artefact omits distributions #925
- done [PR #922] account sim's min_hold_days reads only the averaged lot's first buy, booking sales live refuses #924
- done [PR #922] accumulation_table reuses lot ids after a full-lot sale, corrupting the FIFO row #923
- done PR feat(sim): the reverse path -- distributions in the account sim and the accumulation row (#857) #922
- done dca distribute --preview is one day behind the cycle: it misses the cadence day the pipeline proposes on (incl. the day-210 same_day_dca veto) #921
- done PR feat(dca): keel dca distribute --preview and the reverse_dca doctor findings (#857) #920
- done sleeve: R36 repeat check silences a later month's lost distribution (no recency bound) #919
- done PR feat(rules): reverse_dca, preview-only (#857) #918
- done A sleeve product a bar behind loses the day's proposal: no hourly retry happens (PR #914) #917
- done No cycle test reaches the min_hold_days / cooldown_days refusals in _handle_reductions (PR #914) #916
- done Sleeve cooldown self-renews on its own vetoes and never expires (PR #914) #915
- done PR feat(agent): _handle_reductions -- arbitration, one proposal per product per day, sleeve.proposal notifications (#857) #914
- and 39 more on GitHub →
Recently shipped
-
DCA sleeve — lifecycle design
- done Sell-side spec (#859): #831 D-arm fee drag quoted from the allowance-aware model, not the live-matching flat-taker run #868
- done Sell-side spec (#859): keel pnl reads imported transactions (FIFO), so --lots is not a small extension #866
- done Sell-side spec (#859): 'cycle did not run' is profile.cycled, not #811's position.unmanaged #865
- done Sell-side spec (#859): rotation and rebalance cost figures overstated vs #831's slippage table #864
- done Sell-side spec (#859): trial pre-registration is the driver docstring, not trials-ledger.jsonl #863
- done Sell-side spec (#859): cost_basis formula names a nonexistent positions.original_qty #862
- done Sell-side spec (#859): the ~$213 'DCA book' includes the PAXG turtle tranche; DCA at cost is $151.81 #861
- done Sell-side spec (#859): 'no live path can sell a DCA tranche' ignores last-writer position_rule ownership #860
- done PR docs(spec): DCA sleeve sell side -- trims, rebalancing, reverse DCA, protective exits, rotation (#857) #859
- done Design: the DCA sleeve's sell side -- trims, rebalancing, reverse DCA, protective exits, rotation #857
-
Console — four engine views
Slim the local web console from 13 screens to Pulse, Holdings, Rules, Audit & Setup; drop venue-mirror data; add the browser Halt.
- done PR Console: serve the static shell past the remote lifetime to its own session (#1006) #1008
- done PR sim report: word an empty-side Avg win/loss (R) by counting the R sample (#1004) #1007
- done Console: serve the static shell past the remote session lifetime so a first visit still gets HALT #1006
- done PR docs: remote-access names the two stop exceptions to the session lifetime (#1002) #1005
- done sim report: Avg win (R) / Avg loss (R) print a measured-looking 0.000 for an empty side #1004
- done PR sim report: word an empty-side R profit factor as insights does (#1000) #1003
- done docs/remote-access.md still says an expired session cannot be told apart from a wrong one (#985 follow-up) #1002
- done PR Console: a reloaded console keeps its HALT after the remote lifetime (#985) #1001
- done sim report edge table: profit factor (R) prints inf / 0.000 for an empty side #1000
- done PR fix(web): refuse HTTP/0.9 before dispatch with a framed 505 (#989) #999
- done PR rules backtest: word an empty-side profit factor as insights does (#988) #998
- done keel serve: an HTTP/0.9 request line raises AttributeError in _declared_body_length #989
- done rules backtest: profit_factor prints Infinity / 0 for an empty side, unlike insights summary since #986 #988
- done PR keel serve: socket timeout, GET drain, halt never creates a DB, halt outlives the remote lifetime; stale citations (#981 #982 #983) #987
- done PR insights+promotion: an empty sample side reads as empty, not as Infinity or zero (#979, #980) #986
- done Console: keep the HALT control on Pulse after the remote session lifetime expires (client half of #983) #985
- done Remote session lifetime (#648) refuses HALT too: a keel serve --external-host console can't halt after 12h until restarted #983
- done Stale backticked code references outside keel/web (engine._assemble_cts_context, backtest._closed_trade, simulate._slippage_for_products) #982
- done keel serve: request handler has no socket timeout; a refused POST that declares a body it never sends holds a thread forever #981
- done promotion: check_floors' blocking reasons print win_rate 0.0 / rr_r 0 where the sample has no trades or no wins #980
- done insights: an all-wins profit factor reads "—" (unknown) on Rules but "Infinity" in the CLI #979
- done PR Test log isolation, stale references, DCA stop distance, manifest name refusal (#964 #967 #973 #974) #978
- done PR Halt and keel serve hardening: drain every POST, HALT on a failed Pulse, serve keeps --external-host (#955, #958, #971) #977
- done Console reads 'keel isn't running' after another process closes the WAL database last (setup.inspect mode=ro) #976
- done PR insights: one track record per rule; empty side reads unknown (#962, #965) #975
- done scripts/rule_manifest.py apply stores a "name" param; a non-DCA rule named "dca" would read "no stop by design" #974
- done keel positions: attributed DCA tranches show a stop distance measured against the stop=0 sentinel #973
- done PR console: Holdings per rule row; DCA tranches read "no stop by design" (#960, #961) #972
- done keel serve drops --external-host after binding: remote Host refused, session lifetime and release locality check hollow #971
- done PR console: HALT gets its own token; the release token is served nowhere (#968, #969) #970
- and 18 more on GitHub →
-
v0.14.0 shakedown
What running v0.14.0 on the deployment turned up: the MCP un-migrated guard (#751), two console bugs found testing it (#754, #755), and the launchd console daemons plus keel open (#756). Closed issues only — this is a record of the shakedown, not a plan.
- done [ops] Serve every deployment from one command, surviving reboot and crash — and the origin problem behind a live/paper switcher #756
- done [web] The mode badge's db/config identity is a hover tooltip, so it is unreachable on touch — the mobile wedge's target device #755
- done [web] Navigating shows the previous view's figures under the new view's nav highlight — the loading signal is assistive-only #754
- done keel mcp's doctor tool raises on an un-migrated database, where the audit chain reports and continues #751
-
The honest cockpit (dashboard)
The Alpaca-audit dashboard pass. Sprint 1: equity series, orders, positions, balances. Sprint 2: activity timeline, session identity, journal. Sprint 3: cancel asymmetry, inverted plans page. Research Hub runs in parallel. Read-only unless noted — nothing here waits on #648; the ceremony card stays in Phase B.
- done [engine] Append-only SHA-256 hash chaining for orders, transactions and attestations #721
- done [engine] Persist the per-currency settled/available/total balance pair into the cycle snapshot #719
- done [engine] Record an attestation window: attest_due_ts on asset_attestations and instrument_attestations #718
- done [engine] Schema v20: persist quote_provenance and client_order_id on orders, at placement #715
- done [web] Research Hub /research: trials ledger, evidence matrix, gauntlet, slippage universe #708
- done [web+cli] keel orders cancel: the cancel asymmetry — entries one-click, exits typed #707
- done [web] Plans page, inverted: a manifesto of zero-cost permanence instead of a paywall matrix #706
- done [engine] Wire the discretionary journal: repo methods, CLI entry (human attestation), web read view #705
- done [web] Session identity: profile · mode · equity-state switcher chip and a no-CTA paper banner #704
- done [web] Activity: a unified timeline (cycles · fills · flows · attestations) with audit-grade CSV export #703
- done [web] Balances view: settled vs total cash, per-asset, as-of — never a buying-power CTA #702
- done [web] Positions view: per-tranche MTM, stop distance, bracket status, freshness and attestation chips #701
- done [web] Orders view: the per-order honesty record — expected vs actual fill, fee as paid, provenance #700
- done [engine] equity_points: a mode-partitioned mark-to-market equity time series (schema v16) #698
-
Competitive parity — validation & reach
Gaps against Freqtrade 2026.7, Hummingbot v2.16.0 and Jesse 3.0.7, ranked. Organising principle: every competitor's validation tooling is a diagnostic the user may ignore; keel's promotion gate refuses. Adopt their validation EVIDENCE as gate inputs rather than importing their features. Design boundaries (shorting, leverage, futures, market making, arbitrage, ML, market-data-driven pair selection, hyperopt) are recorded in the PRD as explicit non-goals. See docs/superpowers/specs/2026-08-20-competitive-gap-analysis-prd.md
- done Record the monetisation decision and its trigger — Jesse published theirs, keel should publish its 'not now' #603
- done `keel research`: thirteen evidence modules with no front door #601
- done A read-only MCP server for research assistants — the #453 capabilities check proves it cannot trade #477
- done Optuna parameter study, research-side only — candidates for the gauntlet, never auto-tuned lives #476
- done Rule significance testing — is a family's edge distinguishable from zero at the fee actually paid? #475
- done C7 — Rules are not pluggable, though brokers are #447
- done C6 — Partial fills are not tracked as a distinct state #446
- done C2 — A reusable walk-forward validator #445
- done C4 — Notifications beyond a CRITICAL-only webhook #444
- done C5 — keel doctor: one command that answers 'is this deployment actually working' #443
- done C3 — trail_stop_atr, roll_to_break_even and scale_out are implemented, tested, and never called #442
- done C1b — Monte Carlo and candle-bootstrap resampling: is the equity curve an outlier? #441
- done C1a — Lookahead and recursive bias detection #440
-
Phase 13 — Binance (keel-broker-binance)
A fifth venue, and the first added for a REASON the repo already states rather than for reach. README: "no shipped rule family is net-positive at the taker fee actually paid on this venue — cost is the binding constraint, and the viable parameter/fee intersection is empty under production-faithful execution." config.live.yaml carries taker_pct: 0.012 — 1.2%, Coinbase's published rate for a sub-$1k-30d-volume account. Binance spot is 0.100% at VIP 0 (verified against its published schedule). That is 12x, applied directly to the one constraint the project says is binding. Two gates come BEFORE any code, and neither is an adapter problem: which Binance (binance.com restricts US persons; Binance.US is a different entity, API and listing set), and whether USDT becomes a settlement currency (Binance is USDT-denominated; keel's screen deliberately excludes *-USDT today). The Phase A/B/C shape follows Phase 12's.
-
Phase 11 — Evidence expansion & operational guardrails
Phase 11 — Evidence expansion & operational guardrails. DONE: #349 (fetch honors config granularities, shipped in 0.9.1), #351 (universe 8→19 behind a measured 15-minute health screen; 19 hourly rules at paper; kill switch opened by the operator 2026-08-18; first cycle verified). REMAINING: #350 spread-gate rail (live-path half of the Tier-2 guardrail — ship before any live resumption), #352 pullback hourly-backtest perf regression, #353 n=100 forward-evidence review (accruing at ~940 signals/yr pooled; review scheduled 2026-09-30 — the milestone's due date). Progress board: https://github.com/orgs/CodeGateSoftware/projects/13
- done The 2026-09-30 n=100 pooled review is underpowered: n_eff is about 39, and it can only detect a 20-point edge #427
- done Analyze Dr. Lahlou's speculation-risk scholarship; cite as method support in fiqh-basis #376
- done Money-management and fiqh source review — findings and recommendations #365
- done n=100 forward-evidence review of paper-hourly (~2026-09-30) — the operator's degradation-metric milestone #353
- done PullbackContinuation hourly backtest is pathologically slow (38+ CPU-minutes, 5-year window) #352
- done Expand the paper-hourly universe 8→19 — gated on a measured 15-minute data-health screen #351
- done A routing-time maximum-spread gate — refuse entries when the live book is too wide #350
- done keel fetch ignores config.market_data.granularities — cache warm misses the FIFTEEN_MINUTE confirmation series #349
-
v0.11 — Ship the browser, the app, and WAL
Ship what main already holds: the browser surface, the macOS app, keychain secrets, background market data, browser attest/promote, and WAL — 25 commits past v0.10.0. First step of the v0.11+ plan: deepen the moat (auditability, the gauntlet, compliance) while attacking the real bottlenecks — statistical throughput and fee economics.
-
Reach & surfacing (deferred)
Work whose value depends on having an audience: MCP surfacing, the site AI page, homepage claims. Reopen when keel has real users — the same trigger ADR 0004 will record for monetisation: users, not revenue. Desktop-signing activation (the #438 Option D decision) shares this trigger: stay unsigned until a real user hits the wall.
-
Web UI — a zero-dependency, view-source console
Replace render.py's server-side HTML with a JSON API plus plain ES modules. No framework, no build step, no third-party JavaScript. Spec: docs/superpowers/specs/2026-08-23-web-ui-rewrite-design.md
- done The chart draws but cannot be read: cursor legend, trade hover, save as image #602
- done Delete the curses TUI — after parity, never before #541
- done Delete render.py's HTML generation and the HTML routes #540
- done Documentation deep links to keeltrading.com — and the empty glossary every install ships #539
- done PWA: manifest, icons, and a service worker that never caches /api/* #538
- done The remaining six views, SVG charts, and live updates over EventSource #537
- done Client shell: router, status view, responsive layout, accessibility baseline #536
- done Static asset serving and the full security header set #535
- done JSON API over the existing reports, with server-side sort and /api/config #534
- done The serialisation contract: money as strings, values presentation-ready #533
- done Palette: profit and loss are the same brightness, and inputs have no visible border #532
-
Strategy-API expressiveness (Jesse comparison)
Outcome of the 2026-08-23 comparison against the Jesse framework's strategy API. Scope is deliberately narrow: adopt the declared parameter space (which makes keel's own trials budget derivable rather than hand-recorded), document the fill-model hazard for externally-sourced strategies, and explicitly decline to port signal families — keel is cost-bound, not signal-bound. The comparison independently re-derived #333/#447/#502, which are corroborated rather than extended.
-
Desktop distribution — keel for non-technical users
A first-time user downloads one file, installs, and reaches a working keel without typing a command. Blocked on four architectural properties before any packaging step is meaningful: CWD-relative state, the un-overridable TTY gate, curses-on-Windows, and a first-run ceremony that includes decisions no installer can make. See the PRD: docs/superpowers/specs/2026-08-20-desktop-distribution-prd.md
- done A curl | bash installer that bootstraps the wheels — the no-warning path, auditable line by line #479
- done D6 — Decide the update path for a packaged install #439
- done D5 — Package and sign macOS/Windows artifacts in the release workflow #438
- done D4 — First-run wizard that presents the ceremony rather than skipping it #437
- done D3 — A GUI human gate, architecturally distinct from _is_interactive #436
- done D2 — Local web UI over the existing service layer #435
- done D1 — Resolve state to an OS app-data directory, keeping CWD as an explicit override #434
-
Phase 14 — Self-update: the console keeps the deployment current
CLOSED 2026-08-19 — #415 delivered in PR #417: the in-console self-updater. One service (keel/commands/update.py), two front-ends (keel update [--check] and the TUI Account menu). The release procedure in code: snapshot-consistent DB backups before download, the four production wheels by path, per-DB migrate, keel-versions verify before cleanup, superseded wheels removed only on verified success, backups never deleted, typed gate, verbatim-argv relaunch via execv. The adversarial review caught two blockers pre-merge (refusal false-positive on every real deployment; relaunch argv mangling the wrappers' flag order) plus torn-backup and lying-failure-text majors — all fixed red-first. Bootstrap note: the updater itself rides the next release cut; the FIRST update to any deployment is still the manual procedure.
-
Phase 13 — TUI: the operator console
CLOSED 2026-08-19 — all seven slices delivered and merged: C1 #387 (service extraction — the foundation; cli.py 3000→1434 lines, parity+isolation pins), C2 #388 (console shell, guarded profile switching, the session banner with the MarketSchedule port extension), C3 #389 (compliance menu, the scout-results admission handler, the Shariah-in-force browser with pinned honesty lines), C4 #390 (the strategy console — zero-backtest ledger, ARMED simulate, param help from PARAM_DOCS — and the research readers), C5 #391 (trading + data menus, every typed contract the CLI's own, curses-suspended prompting), C7 #394 (brokers service + CLI + Venues browser; the help & glossary system), C6 #392 (account menu, the thinness pin, the ceremony audit with coverage teeth, the runbook's console section). Independent final review: goal_met — O2-O11 verified at the code level; 3651 tests passing; no schema changes (deployments need only the next release cut). Every slice ran the full TDD → adversarial-review → fix → merge cycle; the reviews earned their keep (a console-freezing ledger blocker, three false glossary claims, a broken-adapter crash, and a blind-typed prompt were all caught and fixed pre-merge).
- done C7: venues/brokers visibility (service + CLI + TUI browser) and the newbie help & glossary system #394
- done C6: safety & polish pass — typed-confirmation adversarial review, keybinds, runbook TUI section #392
- done C5: trading + data menus — cycles, fetch surfaces, typed contracts intact #391
- done C4: rules menu + research readers (experiments, docs, trials ledger) #390
- done C3: compliance menu + the scout-results admission handler #389
- done C2: console shell — menu/sub-menu framework + profile switching (4 deployments) #388
- done C1: service-extraction audit — make every CLI operation callable as a service #387
-
Phase 10 — Evidence pipeline: cadence, pooling & measurement
Born from the 2026-08-15 status review's central complaint: at 1.19–3.20 trades per asset-year, min_trades=100 takes 31–84 years — the promotion gate is arithmetically unreachable. The fix is not more trades (the hourly corpus already measures more-trades and it is net-negative); it is making the evidence collectable and admissible: hourly-cadence paper, cross-sectional sample pooling with a diversity floor, the DCA ablation, and the re-measurement under Phase 9's honest cost model.
- done Rail-17 withdrawal attestation cadence — the 7-day TTL needs a visible refresh habit #340
- done Re-measure under the honest cost model: simulate re-run, DCA dip ablation, paper DCA re-enabled #339
- done Pool min_trades across same-parameter rules, with a cross-sectional diversity floor #338
- done An hourly-cadence paper profile — evidence at a collectable rate #337
-
Phase 9 — Execution & backtest fidelity
Make the simulator and the live executor agree with reality. Two defects here already voided every performance figure in the project once (#254 pending setups never expiring, #257 fills at a price live never waits for); the two open issues are the remaining known divergences between what a rule computes, what the backtest models, and what the venue actually does.
- done The live executor discards a rule's conditional entry price and routes a market order regardless #260
- done slippage is one global 5bp constant applied from BTC to TON #259
- done The simulator fills at a price live never waits for: entries are market orders in production, resting orders in backtest #257
- done backtest(): a pending setup never expires, silently freezing a strategy for the rest of the series #254
-
Phase 8 — Open source: scholarly grounding & launch
What converts 'someone's trading bot' into something a Muslim developer can trust: the fiqh basis written down, a scholarly review path, Arabic entry point, then announce — in that order, never before.
-
Phase 7 — Open source: contributor readiness
Make contributing possible for someone who is not the author. README written for a stranger, the documentation standard stated explicitly, the toolchain floor resolved, and a real on-ramp of shallow issues.
- done Enable Discussions with a Compliance & classification category #287
- done Create a real good-first-issue on-ramp (8-12 shallow issues) #286
- done Add issue and PR templates, including a compliance-question route #285
- done Add CODE_OF_CONDUCT.md with a stance on religious disagreement #284
- done Decide the Python floor: justify >=3.14.4 or relax it #283
- done Write CONTRIBUTING.md, including the documentation standard #282
- done Rewrite README for a newcomer, leading with the compliance engine #281
-
Phase 6 — Open source: licence & discoverability
BLOCKING. The repo is public but legally all-rights-reserved: no LICENSE, no description, no topics. Nobody can contribute, and nobody can find it. Until this closes, external PRs must not be accepted — a contributor has no rights to grant.
- done State the governance boundary: keel enforces rulings, it does not issue them #280
- done Add SECURITY.md and a private vulnerability reporting channel #279
- done Set the repo description and topics so the project is discoverable #278
- done Add a LICENSE — the repo is public but legally all-rights-reserved #277
-
Phase 4 — Autonomy, money mgmt, insights
Bypass mode + smooth-ratio money management + insights + journaling.
-
Phase 3 — Execution, rails, agent loop (confirm)
Executor + 12 hard rails + scheduled agent loop in confirm mode. First live-capable wave.
- done P3 Task 9: CLI #48
- done P3 Task 8: Agent loop (confirm mode) #47
- done P3 Task 7: Dangerous-action passphrase gate #46
- done P3 Task 6: Encrypted secrets vault #45
- done P3 Task 5: cb_client place_order (live) #44
- done P3 Task 4: Executor #43
- done P3 Task 3: Hard rails (guards) #42
- done P3 Task 2: Position sizing #41
- done P3 Task 1: Repository API + shared stats helper #40
-
Phase 2 — Rules, CTS engine, backtest, paper gate
Rule library + CTS confluence scoring + backtest + paper-trade + promotion/demotion. Nothing live.
- done P2 Task 9: Promotion / demotion lifecycle #30
- done P2 Task 8: Paper trader #29
- done P2 Task 7: Evaluation engine #28
- done P2 Task 6: Backtester (intrabar, no-overlap, MFE/MAE) #27
- done P2 Task 5: Rule — DCA / dip-buy backbone #26
- done P2 Task 4: Rule — RSI mean-reversion #25
- done P2 Task 3: Rule — pullback-continuation family #24
- done P2 Task 2: CTS confluence scorer #23
- done P2 Task 1: Strategy interfaces & shared types #22
-
Phase 1 — Offline foundation
DB + CSV import + P&L + analysis primitives + market feed. Fully offline, unit-tested, no live money.
- done Task 10: Market feed #10
- done Task 9: P&L (FIFO) #9
- done Task 8: CSV import #8
- done Task 7: Coinbase client wrapper #7
- done Task 6: Indicators (EMA/RSI/MACD/ATR/Fib/deceleration) #6
- done Task 5: Regime (condition & phase) #5
- done Task 4: Levels (support/resistance) #4
- done Task 3: Candlestick primitives #3
- done Task 2: SQLite schema & repository #2
- done Task 1: Project scaffolding, config & shared types #1
-
Account-model reconciliation + tier/fee analysis
Fix the sim account so it can trade (clamp sizing to real constraints, DCA sleeve, volume=buys+sells), then model Coinbase One tiers (Basic $500/Preferred $10k/Premium unlimited free volume) within-cap and over-cap with real fees (1.20% taker <$1k vol) + subscription costs -> net-P&L matrix. Live executor untouched (separate safety follow-up).
-
Engine validation & trade simulation
5yr historical trade simulation of the deterministic engine: edge test + realistic $500/mo account, risk-adjusted vs DCA benchmark, GO-LIVE/TRAIN-MORE verdict + gap-analysis backlog. Spec docs/superpowers/specs/2026-07-17-engine-validation-simulation-design.md
- done Sim Task 9: HTML/SVG simulation artifact (additive) #71
- done Sim Task 8: keel simulate CLI #70
- done Sim Task 7: report, verdict & gap analysis (sim/report.py) #69
- done Sim Task 6: portfolio simulator (sim/portfolio_sim.py) #68
- done Sim Task 5: DCA benchmarks (sim/benchmark.py) #67
- done Sim Task 4: raise promotion floors to canonical proving-gate values #66
- done Sim Task 3: hand-rolled Decimal financial metrics (sim/metrics.py) #65
- done Sim Task 2: simulation account ledger + guards parity (sim/account.py) #64
- done Sim Task 1: paginated 5yr candle history fetch (data/history.py) #63
-
Safety hardening — USDC, allowance, bypass-arm
USDC-funding rail (no bank/ACH draw), monthly subscription-allowance rail, and bypass-arming hardening. Safety-critical, before any live use.