docs(config): correct the "unvalidated skip set" claim on the live allowlist - #185
Merged
Conversation
…lowlist
`config.live-sandbox.yaml` carried, directly above the real-money allowlist:
# The 5-trend Turtle set (same as the paper-forward + the walk-forward/PBO analysis).
# SOL/LTC/LINK are deliberately excluded -- they're the unvalidated skip set.
Every part of that is false, and it entered git as an inherited assertion: the file was
tracked in 183dcdb as a backup, and no commit, PR or design doc ever introduced or justified
the exclusion. The phrase appears nowhere else in the repo.
- No walk-forward/PBO run has ever covered ADA or XLM. Every such run in docs/experiments/
stops at BTC/ETH/PAXG. The walk-forward that exists tuned a PARAMETER (entry_lookback
20 -> 40); it never validated a set of assets.
- SOL/LTC/LINK are not excluded on compliance grounds and failed nothing. All three were
attested 2026-07-23 in the same batch as ADA/XLM -- same attestor, same source -- and
ADMIT `keel assets screen`, carrying MORE daily history (1827 bars) than PAXG (456, on
the allowlist only via a documented screen_exceptions waiver).
- The comment attaches a rule-level reason to an asset-level control. Rail 1 is a flat
membership test that consults neither attestations nor rule status; what actually makes
SOL/LTC/LINK inert is the absence of a live-status `rules` row.
- The live set didn't pass the promotion gate either: keel-live.db rules 1-5 have
promoted_at IS NULL, seeded straight to `live` through the bypass `rules seed` warns
about. trade_outcomes and signals are empty for every product against min_trades=100,
so ADA/XLM's paper promotion cannot have been earned on evidence either.
The one true reading -- SOL/LTC/LINK have never been backtested -- is equally true of the
five assets that are live, which is what makes "the unvalidated skip set" the wrong name.
The allowlist itself is UNCHANGED. Correcting a false rationale is not grounds to act on
the decision it described; admission stays the operator's call through the deterministic
gate. Comment-only: load_config yields an identical allowlist and caps.
Also fixes the header's stale "(gitignored)" -- the file has been tracked since 183dcdb.
Full re-assessment, including open operator items (deployment drift, keel-live.db carrying
almost no compliance state, live-seeded rules left in place 14 days, stale SOL/LTC/LINK
candles), in docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… claims Independent review of #185 found three false or unsupported claims, two of them in the live-money config comment, and one omission that changes the conclusion's basis. Corrections: - "Nothing has traded: trade_outcomes and signals are empty for every product" was FALSE. trade_outcomes is empty, but keel-live.db holds signals=1, a FILLED live order (BTC-USD BUY 0.000778 @ 64267.30, rule_id=6) and an OPEN position, both 2026-08-07 01:12:50, from the dca rule 6 -- which IS properly promoted. The deployment is not inert and carries exposure. Saying otherwise above a live allowlist is the worst defect here. - The min_trades argument used the wrong mechanism. `rules promote` gates on a candle-driven backtest (commands/rules.py:180), not trade_outcomes. Conclusion unchanged but now rests on the real numbers: XLM n_trades=8, ADA n_trades=6, against min_trades=100. - "Every stated reason is false" was OVERSTATED. The parenthetical's paper-forward half is TRUE: keel.db `paper`-status rules are exactly 10/11/12 BTC/ETH/PAXG + 22 XLM + 24 ADA, i.e. the live 5. That is a coherent origin story, and it is now credited rather than dismissed. Only the walk-forward/PBO half was invented. - "Have never been backtested" was UNPROVABLE and self-contradicted -- this same doc argues the backtests table is dead schema, so absence of a record proves nothing. Claim dropped. - "Same source" flattened LINK's attestation, which deliberately classifies it a UTILITY token (ERC-20; 'native' chosen only because the enum lacks a 'utility' slot). Softened. - entry_lookback annotation now quoted verbatim from turtle_breakout.py:113. And the omission that mattered: the previous comment said "revisit once `keel rules backtest 21/23/25` has been run" without running it. Run now, against a COPY of keel.db: 21 SOL n=13 win 23.1% expectancy -12.41 pf 0.26 23 LTC n= 5 win 0.0% expectancy -13.09 pf 0.00 25 LINK n=15 win 20.0% expectancy -0.66 pf 0.63 22 XLM n= 8 win 37.5% expectancy +0.06 pf 11.44 24 ADA n= 6 win 50.0% expectancy +0.12 pf 5.52 All three excluded assets are negative-expectancy; LTC won none of five. So "there is no negative result anywhere for SOL/LTC/LINK" was wrong -- there is one, and it was ten seconds away in data already in keel.db. The exclusion is the right call, now for a reproducible reason rather than an invented one. Stated with the sample sizes in view: n=5..15 against min_trades=100, in-sample, one window, candles 6 days stale for the excluded three. A directional check, not validation. NONE of the five clears the gate, which is why the allowlist is still unchanged and why the comment now explicitly warns against reading a positive expectancy as licence to add an asset. No production database was written: backtests ran against a scratchpad copy; ~/keel/keel.db mtime is unchanged. Verification: load_config yields an identical allowlist/caps/weights; a comment-stripped diff against main shows no non-comment differences; 2078 tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…station Second review pass. All findings were non-blocking wording; two mattered enough to fix. - **Compare on profit factor, not expectancy.** Expectancy is quote-currency per trade, so it tracks the asset's price -- BTC's +1353.99 and XLM's +0.056 are not commensurable, and the column read as a ranking would put BTC four orders of magnitude "ahead" of ADA purely because a bitcoin costs more. On the scale-free metric the split is clean and states itself: every excluded asset is pf < 1, every included asset is pf > 1. Added BTC/ETH/PAXG rows (10/11/12: n=13/13/4, pf 1.61/1.21/3.25) so the included cohort is shown rather than asserted. - **"NONE of the five" was ambiguous** in a config whose own opening line says "The 5 assets this sandbox trades" -- the table's five were SOL/LTC/LINK/XLM/ADA. Now "not one of the eight rules above", with the live five explicitly included, and it is shown for all eight rather than left unshown. ETH's 30.77% win rate also sits under the canonical min_win_rate 0.55. - **"The real reason SOL/LTC/LINK stay off" overstated it.** The measurement is dated 2026-08-07, ~2 weeks after the 2026-07-24 exclusion, so it cannot have been the reason it was made. Reframed as a post-hoc vindication; the actual reason remains unrecorded. - Staleness qualifier now applies only to SOL/LTC/LINK (the allowlisted rows are current). - Epoch timestamps labelled UTC/EDT rather than bare local. New item the review surfaced, now open item 3 rather than an aside: keel-live.db's sole attestation is SOL, written 2026-08-08 00:29:43 UTC -- same-evening, ~44 min before this branch's first commit -- and its `source` is a STAKING page, which sits awkwardly against its own pays_yield=0 and against every keel.db attestation's "bare unstaked spot only" framing. Not written by this work (scratchpad copies only; ~/keel/keel.db mtime unchanged, all queries mode=ro), and keel-live.db is the live agent's own DB, so it is written continuously -- but provenance should be confirmed, not assumed, and the staking source is a compliance question for the operator independent of this document. Verification unchanged: load_config identical, comment-stripped diff against main empty, 2078 tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
eaitbrahim
added a commit
that referenced
this pull request
Aug 8, 2026
…ays_yield=0 (#186) Follow-up to #185, correcting a claim I made there. Open item 3 said the live-DB SOL attestation's `source` (solana.com/staking) "sits awkwardly against pays_yield=0". Fetching the page shows the opposite. It states: "In order to earn staking rewards ... the tokens in a stake account must be delegated to a validator," with no rebasing and no automatic distribution to holders. Bare holding earns nothing -- which is precisely what pays_yield=0 asserts. The citation is direct evidence FOR the field, not against it. The real gap is narrower and different: it is the wrong KIND of source. AssetAttestation.source is documented as "where this was established -- a URL, a standard, a scholar's ruling." A vendor product page establishes the mechanical fact but not the RULING that a native L1 coin is Mal Hukmi, lawful to own and trade. Every keel.db attestation carries both (KB source-86 + the three-layer screen reasoning + "Attests bare unstaked spot only"); this row carries only the mechanical half, implicitly. screen.py:249 cannot tell the difference -- it checks source.strip() is non-empty and nothing more. Provenance also resolved, and it was an open question worth closing rather than leaving as "should be confirmed": ~/.zsh_history records the exact command at epoch 1786148982, one second before the row's attested_at, preceded by a placeholder attempt and two `keel fetch --products SOL-USD` runs. Hand-typed at the terminal -- not an agent, not the daemon. Added: SOL now carries two attestations with different evidentiary bases, so which governs depends on which --db a command runs against; and the page's ~8% initial inflation decaying to 1.5% means a bare holder is diluted rather than paid, which is a scholarly question rather than one this file can answer. None of it is live-reachable -- SOL is not in the live allowlist and has no rule in keel-live.db, so rail 1 blocks any SOL intent regardless. Docs-only; no code, no config, no database touched. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Re-assessment of a judgment carried in a live-money config,
config.live-sandbox.yaml, directly above the real-money allowlist:Verdict: the decision is right; the stated reasons were mostly wrong. The comment is rewritten to say what's actually true, and the working is recorded in a new experiment doc. The allowlist is unchanged.
What the old comment got right
"Same as the paper-forward" is accurate at the rule level —
keel.db'spaper-status rules are exactly 10/11/12 (BTC/ETH/PAXG) + 22 (XLM) + 24 (ADA), i.e. the live 5. That's a coherent origin story for the exclusion and the PR now credits it.What it got wrong
docs/experiments/stops at BTC/ETH/PAXG.trials-ledger.jsonlsymbol census over 69 rows: BTC 32, ETH 33, PAXG 32, and 0 each for ADA, XLM, SOL, LTC, LINK. The walk-forward that exists tuned a parameter (turtle_breakout.py:113,entry_lookback20 → 40).keel-live.dbrules 1–5 carrypromoted_at IS NULL— seeded straight tolivethrough the bypassrules seedwarns about, and left in place 14 days.keel assets screenand carry more daily history (1827 bars) than PAXG (456, on the list only via a documented waiver).guards.py:369) is a flat membership test consulting neither attestations nor rule status.The measurement nobody had run
The old comment guessed. Running
keel rules backtestagainst a copy ofkeel.dbsettles the direction:All three excluded assets are negative-expectancy; LTC won none of five. The exclusion is correct — now for a reproducible reason instead of an invented one.
Stated honestly: n = 5–15 against
min_trades = 100, in-sample, one window, candles 6 days stale for the excluded three. A directional check, not validation. None of the five clears the gate — which is why the allowlist is unchanged, and why the new comment explicitly warns against reading a positive expectancy as licence to add an asset.What this PR does NOT do
The allowlist is unchanged. No asset attested, no rule promoted, no production database written — backtests ran against a scratchpad copy;
~/keel/keel.db's mtime is untouched.Verification
load_configyields an identical allowlist, caps and weights; a comment-stripped diff againstmainshows no non-comment differences.python -m pytest tests/ -q→ 2078 passed. (uv run pytestfails to importkeel_coreon a clean tree too — pre-existing, unrelated; this diff touches zero Python.)Review corrections (second commit)
An independent adversarial review caught three false/unsupported claims in the first commit, two of them in the live config:
keel-live.dbholdssignals=1, a filled live order (BTC-USD BUY 0.000778 @ 64267.30) and an open position from the properly-promoteddcarule 6. The deployment is not inert and carries exposure. Removed.min_tradesargument used the wrong mechanism —rules promotegates on a candle backtest (commands/rules.py:180), nottrade_outcomes. Conclusion unchanged, now resting on ADA n=6 / XLM n=8.backteststable is dead schema (db.py:140, zero writers). Dropped.Plus: credited the true paper-forward half, softened "same source" for LINK (its attestation deliberately classifies it a utility token), and made the
entry_lookbackquote verbatim.Open operator items
Recorded in the doc, not actioned here:
~/keel/config.live-sandbox.yamlstill has the old comment; sync it.keel-live.dbcarries almost no compliance state — screening the live allowlist against a copy, 0 of 5 admit; SOL is ironically the only asset it admits. Harmless (rail 1 reads config, not the DB) but inverts the comment's picture.rules seed's own instruction.keel fetchbefore relying on them.🤖 Generated with Claude Code