From 1617a105ee48c3f25141f11da0661d9961903b67 Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Fri, 7 Aug 2026 21:13:44 -0400 Subject: [PATCH 1/3] docs(config): correct the "unvalidated skip set" claim on the live allowlist `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) --- config.live-sandbox.yaml | 24 ++- ...08-07-unvalidated-skip-set-reassessment.md | 147 ++++++++++++++++++ 2 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md diff --git a/config.live-sandbox.yaml b/config.live-sandbox.yaml index b843ad31..eb5d7514 100644 --- a/config.live-sandbox.yaml +++ b/config.live-sandbox.yaml @@ -5,12 +5,28 @@ # PREVIEWED and requires a typed `y`. Caps are deliberately tiny so a bad fill can lose only a # few dollars. # -# Authored in the dev repo (gitignored). DEPLOYED to ~/keel at arm-time alongside its -# OWN database keel-live.db. There it runs as: +# Authored in the dev repo and TRACKED there since 183dcdb. DEPLOYED to ~/keel at arm-time +# alongside its OWN database keel-live.db. There it runs as: # .venv/bin/keel --config config.live-sandbox.yaml --db keel-live.db agent (interactive) +# The repo copy is the backup of record: edit both, or they drift. -# 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. +# The 5 assets this sandbox trades. This is NOT a validated cohort, and an earlier version of +# this comment claiming it matched "the walk-forward/PBO analysis" was wrong on every count -- +# see docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md. In short: +# - No walk-forward/PBO run has ever covered ADA or XLM. Every such run in docs/experiments/ +# stopped at BTC/ETH/PAXG. The walk-forward that exists tuned a PARAMETER (entry_lookback +# 20 -> 40), it did not validate a set of assets. +# - keel-live.db rules 1-5 were seeded straight to `live` (promoted_at IS NULL), i.e. through +# the documented `rules seed --status live` bypass, not through the promotion gate. +# - Nothing has traded: trade_outcomes and signals are empty for every product, so with +# min_trades=100 no asset here could have earned promotion on evidence. +# +# SOL/LTC/LINK are excluded because their turtle rules are still `candidate` and have never been +# backtested -- NOT on compliance grounds, and NOT because anything about them failed. All three +# were attested 2026-07-23 in the same batch as ADA/XLM (same attestor, same source) and ADMIT +# `keel assets screen` against keel.db today, carrying MORE daily history (1827 bars) than PAXG +# (456 native-USD bars, on the allowlist only via a documented screen_exceptions waiver). +# Revisit this list once `keel rules backtest 21/23/25` has actually been run. allowlist: - BTC - ETH diff --git a/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md b/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md new file mode 100644 index 00000000..339dfcc9 --- /dev/null +++ b/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md @@ -0,0 +1,147 @@ +# Re-assessing "SOL/LTC/LINK are the unvalidated skip set" + +**Date:** 2026-08-07 +**Status:** documentation correction only. **No allowlist changed, no asset attested, no rule +promoted, no database written.** +**Trigger:** a standing re-assessment of whether that claim — carried in a live-money config — +is always valid. + +## The claim under test + +`config.live-sandbox.yaml`, directly above the `allowlist:` that governs the real-money sandbox: + +```yaml +# 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. +allowlist: [BTC, ETH, PAXG, ADA, XLM] +``` + +**Verdict: not valid, and not valid at any point since it was written.** The exclusion is +*conservative in direction* — fewer live assets is the safe error — but every stated reason for +it is false, and the label misdescribes both which assets were validated and what mechanism does +the excluding. A comment sitting above a live allowlist is read as the reason for that +allowlist; this one would mislead anyone who trusted it. + +## Provenance: there is no decision to find + +The phrase "unvalidated skip set" appears **nowhere else in the repository**. The file entered +git fully formed on 2026-08-03 in `183dcdb` ("chore: track the deployment's operator configs"), +a *backup* commit — before that it lived only in `~/keel` on one laptop. No commit, PR, design +doc, or experiment note ever introduced or justified the exclusion. It is an inherited +assertion, not a recorded ruling. + +## Four gates, and the comment names the wrong one + +keel enforces four independent gates. Three are asset-level, one is rule-level: + +| # | Gate | Object | Enforced by | +|---|---|---|---| +| 1 | Compliance / attestation | asset | `screen.py::screen_asset` — `attestation=None` fails closed | +| 2 | Mechanical screen | asset | same fn — history ≥1460 bars, liquidity, settlement, spot-only | +| 3 | Allowlist | asset | `guards.py` rail 1, every intent — **consults neither gate 1 nor 2** | +| 4 | Statistical evidence | **rule** | `agent.py` filters on `rules.status`; `promotion.py::can_promote` | + +The comment attaches a **gate-4 (rule-level)** reason to a **gate-3 (asset-level)** control. +Rail 1 is a flat membership test against whatever list the loaded config contains; it does not +and cannot know whether anything was validated. What actually makes SOL/LTC/LINK inert is the +absence of a `live`-status `rules` row — a `keel rules seed --status` choice, not the allowlist. + +## Gates 1 and 2: SOL/LTC/LINK passed, and have since 2026-07-23 + +`asset_attestations` in `keel.db` holds all eight assets. SOL, XLM, LTC and ADA were attested at +the **same second** (2026-07-23 12:15:12), same attestor, same source (Mufti Faraz Adam, "Is +Crypto Halal?"), all `pays_yield=0`, "bare unstaked spot only". LINK followed 2.5 minutes later. +No `screen_exceptions` row exists for any of the five. + +Screening copies of the databases, all three ADMIT: 1827 daily bars each, median volumes +$108M / $15.1M / $21.2M against a $1M floor. + +There is **no negative result anywhere** for SOL, LTC or LINK. They were not tested and rejected. + +The comparison that settles it: + +| asset | daily bars | attested | screen verdict | in live allowlist | +|---|---:|:---:|:---:|:---:| +| ADA / XLM | 1833 | 2026-07-23 | ADMIT | yes | +| SOL / LTC / LINK | 1827 | 2026-07-23 | ADMIT | **no** | +| PAXG | **456** | 2026-07-23 | admit **only via waiver** | yes | + +The excluded assets carry *more* history than an included one. PAXG is on the list solely +through a documented `screen_exceptions` history waiver. + +## The parenthetical is false: no walk-forward/PBO ever covered ADA or XLM + +Every walk-forward, PBO/CSCV and ablation run recorded in `docs/experiments/` — the first PBO +run, exit-lookback, ADX ablation, horizon independence, Yang-Zhang, and all four +`trials-ledger.jsonl` sessions — stops at **BTC/ETH/PAXG**. Nothing dated after 2026-07-20 runs +any such analysis, and the 8-asset expansion landed 2026-07-23. + +So ADA and XLM have been through that machinery exactly as much as SOL, LTC and LINK have: +**not at all.** The walk-forward that does exist tuned a *parameter* — `turtle_breakout.py` +still annotates `entry_lookback: int = 40 # walk-forward OOS default (was 20)` — it never +validated a set of assets. + +## Gate 4: the live set didn't pass it either + +`keel-live.db` rules 1–5 (BTC/ETH/PAXG/ADA/XLM) were all created in the same second on +2026-07-24 13:42:24 at `status = live` with **`promoted_at IS NULL`** — seeded directly through +the bypass `rules seed` warns about in its own output: + +> ⚠️ seeded at LIVE status, bypassing the promotion gate. This is for the supervised live-order +> test only … **Do not leave live-seeded rules in place afterwards.** + +They have been in place 14 days. + +In `keel.db`, XLM (22) and ADA (24) do carry a `promoted_at`, while SOL (21), LTC (23) and LINK +(25) remain `candidate`. But `trade_outcomes` and `signals` are **empty for every product** and +`min_trades` is 100 — so that promotion cannot have been earned on evidence either. It is the +same documented `--force` bypass. `rules seed` performs no backtest at all: `--status` is an +operator-supplied string written straight through by `insert_rule`. + +**The live 5-set is not the validated set. It is the gate-bypassed set.** SOL/LTC/LINK are the +three that were *not* fast-tracked. + +> **Note on the empty `backtests` table.** It proves nothing either way. The table is declared +> at `keel/data/db.py:140` and indexed, but there is no `INSERT INTO backtests` anywhere in the +> repo — `rules backtest` / `rules promote` compute in memory and never persist. An empty table +> is the expected state even where backtests *have* run. This corrected an earlier reading in +> this same investigation. + +## What survives + +Exactly one narrow reading is true: **SOL/LTC/LINK's turtle rules have never been backtested.** +That is a real and sufficient reason to keep them off a live allowlist. It is also true of the +five assets that *are* on it, which is what makes "the unvalidated skip set" the wrong name for +them. + +## When does the claim stop holding? + +It already has, partially — the compliance half expired on 2026-07-23 when all eight were +attested. The remaining half expires the moment `keel rules backtest 21 / 23 / 25` is run. Since +nothing in the codebase re-checks this comment, it will stay wrong until edited by hand. + +## Action taken + +The comment in `config.live-sandbox.yaml` was rewritten to state the accurate reason. **The +allowlist itself is unchanged** — correcting a false rationale is not grounds to act on the +decision it described, and admission is the operator's call through the deterministic gate. + +## Open items for the operator + +1. **Deployment drift.** Only the repo copy was edited. `~/keel/config.live-sandbox.yaml` still + carries the old comment; sync it. +2. **`keel-live.db` carries almost no compliance state.** Screening the live allowlist against + it, **0 of 5 admit** — BTC/ETH/ADA/XLM reject on missing attestation, PAXG on attestation + *and* history, because the attestations and the PAXG waiver exist only in `keel.db`. + Ironically **SOL is the only asset that DB admits**, having been attested there 2026-08-07 + 20:29:43. Operationally harmless (rail 1 reads `config.allowlist`, not the DB), but anyone + running `keel assets screen` against the live DB would conclude the opposite of the comment. +3. **Live-seeded rules left in place** 14 days, against `rules seed`'s own instruction. +4. **Stale candles.** `keel fetch` follows the allowlist, so SOL/LTC/LINK daily bars in + `keel.db` end 2026-07-31 vs 2026-08-06 for the allowlisted set. A backtest run today would + be six days stale — fetch first. +5. **Two open attestation questions** surfaced this run and not yet answered: LINK's staking + floor is funded from emissions rather than user fees, and LTC has carried **MWEB**, an + opt-in confidential-transaction layer, since May 2022 — a narrower form of the ZEC privacy + question. Neither is a defect; both are questions a human should settle before treating the + 2026-07-23 attestations as closed. From 0aa58e05db6b4dd5e4bf7c087d83e42a8a868f28 Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Fri, 7 Aug 2026 21:28:22 -0400 Subject: [PATCH 2/3] docs(config): fix review findings -- run the backtest, drop the false 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) --- config.live-sandbox.yaml | 47 +++-- ...08-07-unvalidated-skip-set-reassessment.md | 198 +++++++++++------- 2 files changed, 148 insertions(+), 97 deletions(-) diff --git a/config.live-sandbox.yaml b/config.live-sandbox.yaml index eb5d7514..0548507d 100644 --- a/config.live-sandbox.yaml +++ b/config.live-sandbox.yaml @@ -10,23 +10,38 @@ # .venv/bin/keel --config config.live-sandbox.yaml --db keel-live.db agent (interactive) # The repo copy is the backup of record: edit both, or they drift. -# The 5 assets this sandbox trades. This is NOT a validated cohort, and an earlier version of -# this comment claiming it matched "the walk-forward/PBO analysis" was wrong on every count -- -# see docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md. In short: -# - No walk-forward/PBO run has ever covered ADA or XLM. Every such run in docs/experiments/ -# stopped at BTC/ETH/PAXG. The walk-forward that exists tuned a PARAMETER (entry_lookback -# 20 -> 40), it did not validate a set of assets. -# - keel-live.db rules 1-5 were seeded straight to `live` (promoted_at IS NULL), i.e. through -# the documented `rules seed --status live` bypass, not through the promotion gate. -# - Nothing has traded: trade_outcomes and signals are empty for every product, so with -# min_trades=100 no asset here could have earned promotion on evidence. +# The 5 assets this sandbox trades. Keeping SOL/LTC/LINK off this list is the RIGHT call -- but +# an earlier version of this comment gave reasons that were not true, so the reasons are restated +# here. Full working: docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md. # -# SOL/LTC/LINK are excluded because their turtle rules are still `candidate` and have never been -# backtested -- NOT on compliance grounds, and NOT because anything about them failed. All three -# were attested 2026-07-23 in the same batch as ADA/XLM (same attestor, same source) and ADMIT -# `keel assets screen` against keel.db today, carrying MORE daily history (1827 bars) than PAXG -# (456 native-USD bars, on the allowlist only via a documented screen_exceptions waiver). -# Revisit this list once `keel rules backtest 21/23/25` has actually been run. +# What that comment got RIGHT: these 5 are exactly the `paper`-status rules in keel.db +# (10/11/12 BTC/ETH/PAXG + 22 XLM + 24 ADA), so "same as the paper-forward" was accurate. +# +# What it got WRONG: it also credited "the walk-forward/PBO analysis". No walk-forward or PBO run +# has ever covered ADA or XLM -- every such run in docs/experiments/ stopped at BTC/ETH/PAXG, and +# the walk-forward that exists tuned a PARAMETER (turtle_breakout.py:113, entry_lookback 20 -> 40), +# it never validated a set of assets. And these 5 did not clear the promotion gate: keel-live.db +# rules 1-5 carry promoted_at IS NULL, seeded straight to `live` through the bypass `rules seed` +# warns about. (Rule 6, the BTC dca, IS promoted -- and has a filled live order and an open +# position, so this deployment is NOT inert.) +# +# The real reason SOL/LTC/LINK stay off, measured 2026-08-07 by running the backtest nobody had +# run -- `keel rules backtest` on a COPY of keel.db, candles 6 days stale, in-sample, one window: +# 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 5. That is a real adverse +# result, NOT a compliance one -- all three were attested 2026-07-23 alongside ADA/XLM under the +# same governing source (KB source-86; LINK's is more carefully qualified, as a utility token), +# all three ADMIT `keel assets screen`, and all three carry MORE daily history (1827 bars) than +# PAXG (456 native-USD bars, on this list only via a documented screen_exceptions waiver). +# +# Read those numbers with the sample sizes in view: n=5..15 against min_trades=100. NONE of the +# five -- included or excluded -- can clear the promotion gate on this evidence. The split is +# directionally supported, not validated. Do not treat a positive expectancy here as a licence to +# add an asset, and do not add SOL/LTC/LINK on the strength of their screen/attestation status. allowlist: - BTC - ETH diff --git a/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md b/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md index 339dfcc9..43f51745 100644 --- a/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md +++ b/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md @@ -1,8 +1,8 @@ # Re-assessing "SOL/LTC/LINK are the unvalidated skip set" **Date:** 2026-08-07 -**Status:** documentation correction only. **No allowlist changed, no asset attested, no rule -promoted, no database written.** +**Status:** documentation correction + one measurement. **No allowlist changed, no asset +attested, no rule promoted, no production database written** (backtests ran against a copy). **Trigger:** a standing re-assessment of whether that claim — carried in a live-money config — is always valid. @@ -16,19 +16,21 @@ is always valid. allowlist: [BTC, ETH, PAXG, ADA, XLM] ``` -**Verdict: not valid, and not valid at any point since it was written.** The exclusion is -*conservative in direction* — fewer live assets is the safe error — but every stated reason for -it is false, and the label misdescribes both which assets were validated and what mechanism does -the excluding. A comment sitting above a live allowlist is read as the reason for that -allowlist; this one would mislead anyone who trusted it. +**Verdict: the decision is right; the stated reasons were mostly wrong; and "always valid" is +the wrong frame for it.** One half of the parenthetical is accurate, the other half describes +analysis that does not exist, the "unvalidated" label misdescribes which assets were validated, +and the whole thing named a gate that does not do the excluding. Then — on a check nobody had +run until this re-assessment — the *conclusion* turned out to be supported by evidence the +comment never cited. -## Provenance: there is no decision to find +## Provenance: no decision record exists The phrase "unvalidated skip set" appears **nowhere else in the repository**. The file entered git fully formed on 2026-08-03 in `183dcdb` ("chore: track the deployment's operator configs"), -a *backup* commit — before that it lived only in `~/keel` on one laptop. No commit, PR, design -doc, or experiment note ever introduced or justified the exclusion. It is an inherited -assertion, not a recorded ruling. +a *backup* commit; `36c931a` had gitignored it on 2026-07-24. No commit, PR, or design doc ever +introduced or justified the exclusion. + +That said, a coherent origin story does exist and the comment half-names it — see below. ## Four gates, and the comment names the wrong one @@ -38,27 +40,23 @@ keel enforces four independent gates. Three are asset-level, one is rule-level: |---|---|---|---| | 1 | Compliance / attestation | asset | `screen.py::screen_asset` — `attestation=None` fails closed | | 2 | Mechanical screen | asset | same fn — history ≥1460 bars, liquidity, settlement, spot-only | -| 3 | Allowlist | asset | `guards.py` rail 1, every intent — **consults neither gate 1 nor 2** | +| 3 | Allowlist | asset | `guards.py:369` rail 1 — **consults neither gate 1 nor 2** | | 4 | Statistical evidence | **rule** | `agent.py` filters on `rules.status`; `promotion.py::can_promote` | The comment attaches a **gate-4 (rule-level)** reason to a **gate-3 (asset-level)** control. -Rail 1 is a flat membership test against whatever list the loaded config contains; it does not -and cannot know whether anything was validated. What actually makes SOL/LTC/LINK inert is the -absence of a `live`-status `rules` row — a `keel rules seed --status` choice, not the allowlist. +Rail 1 is a flat membership test against whatever list the loaded config contains. What actually +makes SOL/LTC/LINK inert is the absence of a `live`-status `rules` row. ## Gates 1 and 2: SOL/LTC/LINK passed, and have since 2026-07-23 -`asset_attestations` in `keel.db` holds all eight assets. SOL, XLM, LTC and ADA were attested at -the **same second** (2026-07-23 12:15:12), same attestor, same source (Mufti Faraz Adam, "Is -Crypto Halal?"), all `pays_yield=0`, "bare unstaked spot only". LINK followed 2.5 minutes later. -No `screen_exceptions` row exists for any of the five. - -Screening copies of the databases, all three ADMIT: 1827 daily bars each, median volumes -$108M / $15.1M / $21.2M against a $1M floor. - -There is **no negative result anywhere** for SOL, LTC or LINK. They were not tested and rejected. +SOL, XLM, LTC and ADA were attested at the **same second** (2026-07-23 12:15:12, `attested_at` +1784823312), same attestor, `pays_yield=0`, "bare unstaked spot only". LINK followed 160s later +under the same governing source (KB source-86) — though LINK's attestation text is materially +more qualified, classifying it as a **utility token** (ERC-20, `native` chosen only because the +backing enum lacks a `utility` slot). That nuance is worth preserving; "same source" flattens it. -The comparison that settles it: +Screening a copy of `keel.db`, all three ADMIT — 1827 daily bars each, median notionals +$108,273,790 / $15,129,648 / $21,156,873 against a $1M floor. | asset | daily bars | attested | screen verdict | in live allowlist | |---|---:|:---:|:---:|:---:| @@ -66,82 +64,120 @@ The comparison that settles it: | SOL / LTC / LINK | 1827 | 2026-07-23 | ADMIT | **no** | | PAXG | **456** | 2026-07-23 | admit **only via waiver** | yes | -The excluded assets carry *more* history than an included one. PAXG is on the list solely -through a documented `screen_exceptions` history waiver. +The excluded assets carry *more* history than an included one. PAXG is on the list solely via +the single `screen_exceptions` row in the table. -## The parenthetical is false: no walk-forward/PBO ever covered ADA or XLM +**There is no compliance asymmetry.** Whatever separates these two groups, it is not gates 1–2. -Every walk-forward, PBO/CSCV and ablation run recorded in `docs/experiments/` — the first PBO -run, exit-lookback, ADX ablation, horizon independence, Yang-Zhang, and all four -`trials-ledger.jsonl` sessions — stops at **BTC/ETH/PAXG**. Nothing dated after 2026-07-20 runs -any such analysis, and the 8-asset expansion landed 2026-07-23. +## The parenthetical: half true, half false -So ADA and XLM have been through that machinery exactly as much as SOL, LTC and LINK have: -**not at all.** The walk-forward that does exist tuned a *parameter* — `turtle_breakout.py` -still annotates `entry_lookback: int = 40 # walk-forward OOS default (was 20)` — it never -validated a set of assets. +**True half — "same as the paper-forward."** The `paper`-status rules in `keel.db` are exactly +10 (BTC), 11 (ETH), 12 (PAXG), 22 (XLM), 24 (ADA) — precisely the live 5. `paper.py:15` loads +`repo.get_rules("paper")`. So at the *rule* level this is an accurate description, and it is a +perfectly coherent origin story for the exclusion: the sandbox mirrored the paper-forward's +promoted rule set. (Note `config.paperforward.yaml`'s *allowlist* is all eight assets — the +match is between rule sets, not config files.) + +**False half — "the walk-forward/PBO analysis."** Every walk-forward, PBO/CSCV and ablation run +in `docs/experiments/` stops at **BTC/ETH/PAXG**. The `trials-ledger.jsonl` symbol census across +69 rows and 4 sessions: BTC 32, ETH 33, PAXG 32, and **0** for each of ADA, XLM, SOL, LTC, LINK. +ADA and XLM have been through that machinery exactly as much as SOL/LTC/LINK have: not at all. +The walk-forward that does exist tuned a *parameter* — `turtle_breakout.py:113`: + +```python +entry_lookback: int = 40, # Donchian-high entry (days); walk-forward OOS default (was 20) +``` ## Gate 4: the live set didn't pass it either -`keel-live.db` rules 1–5 (BTC/ETH/PAXG/ADA/XLM) were all created in the same second on -2026-07-24 13:42:24 at `status = live` with **`promoted_at IS NULL`** — seeded directly through -the bypass `rules seed` warns about in its own output: +`keel-live.db` rules 1–5 (BTC/ETH/PAXG/ADA/XLM) were created in the same second on 2026-07-24 +13:42:24 at `status = live` with **`promoted_at IS NULL`** — seeded through the bypass +`rules seed` warns about in its own output: > ⚠️ seeded at LIVE status, bypassing the promotion gate. This is for the supervised live-order > test only … **Do not leave live-seeded rules in place afterwards.** -They have been in place 14 days. - -In `keel.db`, XLM (22) and ADA (24) do carry a `promoted_at`, while SOL (21), LTC (23) and LINK -(25) remain `candidate`. But `trade_outcomes` and `signals` are **empty for every product** and -`min_trades` is 100 — so that promotion cannot have been earned on evidence either. It is the -same documented `--force` bypass. `rules seed` performs no backtest at all: `--status` is an -operator-supplied string written straight through by `insert_rule`. - -**The live 5-set is not the validated set. It is the gate-bypassed set.** SOL/LTC/LINK are the -three that were *not* fast-tracked. - -> **Note on the empty `backtests` table.** It proves nothing either way. The table is declared -> at `keel/data/db.py:140` and indexed, but there is no `INSERT INTO backtests` anywhere in the -> repo — `rules backtest` / `rules promote` compute in memory and never persist. An empty table -> is the expected state even where backtests *have* run. This corrected an earlier reading in -> this same investigation. +They have been in place 14 days. `rules seed` performs no backtest: `--status` is an +operator-supplied string written straight through by `insert_rule` (`commands/rules.py:351`). + +In `keel.db`, XLM (22) and ADA (24) *do* carry a `promoted_at`, while SOL (21), LTC (23) and +LINK (25) remain `candidate`. That promotion cannot have been earned: `rules promote` gates on a +candle-driven backtest (`commands/rules.py:180`), and XLM/ADA return **n_trades = 8 and 6** +against `min_trades = 100`. It is inference, not record, that `--force` was used — the `journal` +table is empty and `log_event` writes to logs, not the DB — but the gate demonstrably could not +have passed. + +> **Two corrections this investigation made to itself.** +> **(a)** The empty `backtests` table proves nothing. It is declared at `keel/data/db.py:140` +> and indexed, but there is no `INSERT INTO backtests` anywhere — `rules backtest` / `rules +> promote` compute in memory and never persist. An empty table is expected even where backtests +> *have* run. Consequently "SOL/LTC/LINK have never been backtested" is **unprovable** and is no +> longer claimed. +> **(b)** "Nothing has traded" was **false**. `trade_outcomes` is empty in both DBs, 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. This deployment is not inert and does carry exposure. + +## The measurement nobody had run + +The original comment guessed. Running `keel rules backtest` — against a **copy** of `keel.db`, +never the original — settles the direction in three commands: + +| rule | asset | n_trades | win rate | expectancy | profit factor | max DD | +|---|---|---:|---:|---:|---:|---:| +| 21 | SOL | 13 | 23.08% | **−12.41** | 0.259 | 161.3 | +| 23 | LTC | 5 | 0.00% | **−13.09** | 0.000 | 65.5 | +| 25 | LINK | 15 | 20.00% | **−0.665** | 0.630 | 19.4 | +| 22 | XLM | 8 | 37.50% | +0.056 | 11.44 | 0.04 | +| 24 | ADA | 6 | 50.00% | +0.121 | 5.52 | 0.10 | + +All three excluded assets are negative-expectancy; LTC won none of five trades. So the earlier +draft of this document was wrong to say "there is no negative result anywhere for SOL, LTC or +LINK" — there is one, and it was ten seconds away in data already sitting in `keel.db`. + +**Read it with the sample sizes in view.** n = 5–15 against `min_trades = 100`, in-sample, one +window, no walk-forward, and on candles six days stale for the excluded three. By this project's +own standards (`2026-07-20-first-pbo-run.md` on why high PBO with a flat slope is the *good* +shape; §79.13 on 47 of 55 assets failing `t = 1.65`) this is a cheap directional check, not +validation. It cannot promote anything and should not. **None of the five clears the gate.** + +What it does do is remove the symmetry argument: the two groups are not indistinguishable on +evidence, and the difference runs the way the original comment assumed. ## What survives -Exactly one narrow reading is true: **SOL/LTC/LINK's turtle rules have never been backtested.** -That is a real and sufficient reason to keep them off a live allowlist. It is also true of the -five assets that *are* on it, which is what makes "the unvalidated skip set" the wrong name for -them. +- The exclusion of SOL/LTC/LINK is **correct**, and now for a stated, reproducible reason. +- The label "unvalidated skip set" is still **wrong**, because it implies the other five were + validated. None of the five was. All five sit far below the promotion floor. +- "Same as the paper-forward" was **right**; "the walk-forward/PBO analysis" was **invented**. +- The exclusion is not, and never was, a compliance judgment. ## When does the claim stop holding? -It already has, partially — the compliance half expired on 2026-07-23 when all eight were -attested. The remaining half expires the moment `keel rules backtest 21 / 23 / 25` is run. Since -nothing in the codebase re-checks this comment, it will stay wrong until edited by hand. +The compliance half expired on 2026-07-23 when all eight assets were attested. The "unvalidated" +half was never accurate as a *distinguishing* claim. What now stands in for it — adverse +backtest expectancy — is itself provisional: it rests on 5–15 trades and would want re-running +after a `keel fetch`, and properly a walk-forward before anyone treats it as settled. ## Action taken -The comment in `config.live-sandbox.yaml` was rewritten to state the accurate reason. **The -allowlist itself is unchanged** — correcting a false rationale is not grounds to act on the -decision it described, and admission is the operator's call through the deterministic gate. +The comment in `config.live-sandbox.yaml` was rewritten to state the accurate reasons and to +carry the measured numbers. **The allowlist itself is unchanged** — the measurement supports the +status quo, and admission is the operator's call through the deterministic gate regardless. ## Open items for the operator -1. **Deployment drift.** Only the repo copy was edited. `~/keel/config.live-sandbox.yaml` still - carries the old comment; sync it. -2. **`keel-live.db` carries almost no compliance state.** Screening the live allowlist against - it, **0 of 5 admit** — BTC/ETH/ADA/XLM reject on missing attestation, PAXG on attestation +1. **Deployment drift.** Only the repo copy was edited; `~/keel/config.live-sandbox.yaml` is + still byte-identical to the old version. Sync it. +2. **`keel-live.db` carries almost no compliance state.** Screening the live allowlist against a + copy, **0 of 5 admit** — BTC/ETH/ADA/XLM reject on missing attestation, PAXG on attestation *and* history, because the attestations and the PAXG waiver exist only in `keel.db`. - Ironically **SOL is the only asset that DB admits**, having been attested there 2026-08-07 - 20:29:43. Operationally harmless (rail 1 reads `config.allowlist`, not the DB), but anyone - running `keel assets screen` against the live DB would conclude the opposite of the comment. -3. **Live-seeded rules left in place** 14 days, against `rules seed`'s own instruction. -4. **Stale candles.** `keel fetch` follows the allowlist, so SOL/LTC/LINK daily bars in - `keel.db` end 2026-07-31 vs 2026-08-06 for the allowlisted set. A backtest run today would - be six days stale — fetch first. -5. **Two open attestation questions** surfaced this run and not yet answered: LINK's staking - floor is funded from emissions rather than user fees, and LTC has carried **MWEB**, an - opt-in confidential-transaction layer, since May 2022 — a narrower form of the ZEC privacy - question. Neither is a defect; both are questions a human should settle before treating the - 2026-07-23 attestations as closed. + Ironically **SOL is the only asset that DB admits** (attested there 2026-08-07 20:29:43). + Operationally harmless — rail 1 reads `config.allowlist`, not the DB — but anyone running + `keel assets screen` against the live DB gets the opposite of the comment's picture. +3. **Live-seeded rules left in place 14 days**, against `rules seed`'s own instruction. +4. **Stale candles.** `keel fetch` follows the allowlist, so SOL/LTC/LINK daily bars in `keel.db` + end 2026-07-31 vs 2026-08-06. Re-run the backtests above after a fetch before relying on them. +5. **Two open attestation questions**, neither a defect: LINK's staking floor is funded from + emissions rather than user fees, and LTC has carried **MWEB** — opt-in confidential + transactions — since May 2022, a narrower form of the ZEC privacy question. From 59f4c740e6d81a6885600bfc73d80dd6aeb4ac5b Mon Sep 17 00:00:00 2001 From: Elmehdi Aitbrahim Date: Fri, 7 Aug 2026 21:39:27 -0400 Subject: [PATCH 3/3] docs(config): compare on profit factor, and flag the live-DB SOL attestation 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) --- config.live-sandbox.yaml | 39 +++++---- ...08-07-unvalidated-skip-set-reassessment.md | 85 +++++++++++++------ 2 files changed, 84 insertions(+), 40 deletions(-) diff --git a/config.live-sandbox.yaml b/config.live-sandbox.yaml index 0548507d..5b69871b 100644 --- a/config.live-sandbox.yaml +++ b/config.live-sandbox.yaml @@ -25,22 +25,31 @@ # warns about. (Rule 6, the BTC dca, IS promoted -- and has a filled live order and an open # position, so this deployment is NOT inert.) # -# The real reason SOL/LTC/LINK stay off, measured 2026-08-07 by running the backtest nobody had -# run -- `keel rules backtest` on a COPY of keel.db, candles 6 days stale, in-sample, one window: -# 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 5. That is a real adverse -# result, NOT a compliance one -- all three were attested 2026-07-23 alongside ADA/XLM under the -# same governing source (KB source-86; LINK's is more carefully qualified, as a utility token), -# all three ADMIT `keel assets screen`, and all three carry MORE daily history (1827 bars) than -# PAXG (456 native-USD bars, on this list only via a documented screen_exceptions waiver). +# The reason that DOES hold up -- established 2026-08-07 by running the backtest nobody had run, +# so it is a post-hoc vindication of the 2026-07-24 exclusion, not the reason it was made. +# `keel rules backtest` on a COPY of keel.db, in-sample, one window (SOL/LTC/LINK candles 6 days +# stale; the allowlisted rows are current): +# 21 SOL n=13 win 23.1% expectancy -12.41 pf 0.26 <- excluded +# 23 LTC n= 5 win 0.0% expectancy -13.09 pf 0.00 <- excluded +# 25 LINK n=15 win 20.0% expectancy -0.66 pf 0.63 <- excluded +# 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 +# 10 BTC n=13 win 46.2% expectancy +1353.99 pf 1.61 +# 11 ETH n=13 win 30.8% expectancy +45.72 pf 1.21 +# 12 PAXG n= 4 win 50.0% expectancy +212.15 pf 3.25 +# COMPARE ON pf, NOT expectancy: expectancy is quote-currency per trade, so it tracks the asset's +# price (BTC ~64k vs XLM ~0.30) and is meaningless across rows. On the scale-free metric the split +# is clean -- every excluded asset is pf < 1 (losing), every included one is pf > 1. # -# Read those numbers with the sample sizes in view: n=5..15 against min_trades=100. NONE of the -# five -- included or excluded -- can clear the promotion gate on this evidence. The split is -# directionally supported, not validated. Do not treat a positive expectancy here as a licence to +# That is a real adverse result for SOL/LTC/LINK, and NOT a compliance one: all three were attested +# 2026-07-23 alongside ADA/XLM under the same governing source (KB source-86; LINK's is more +# carefully qualified, as a utility token), all three ADMIT `keel assets screen`, and all three +# carry MORE daily history (1827 bars) than PAXG (456 native-USD bars, on this list only via a +# documented screen_exceptions waiver). +# +# Read the numbers with the sample sizes in view: n=4..15 against min_trades=100. NOT ONE of the +# eight rules above can clear the promotion gate on this evidence -- the live five included. The +# split is directionally supported, not validated. Do not treat a positive pf here as a licence to # add an asset, and do not add SOL/LTC/LINK on the strength of their screen/attestation status. allowlist: - BTC diff --git a/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md b/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md index 43f51745..a6f11975 100644 --- a/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md +++ b/docs/experiments/2026-08-07-unvalidated-skip-set-reassessment.md @@ -49,9 +49,10 @@ makes SOL/LTC/LINK inert is the absence of a `live`-status `rules` row. ## Gates 1 and 2: SOL/LTC/LINK passed, and have since 2026-07-23 -SOL, XLM, LTC and ADA were attested at the **same second** (2026-07-23 12:15:12, `attested_at` -1784823312), same attestor, `pays_yield=0`, "bare unstaked spot only". LINK followed 160s later -under the same governing source (KB source-86) — though LINK's attestation text is materially +SOL, XLM, LTC and ADA were attested at the **same second** (`attested_at` 1784823312 = +2026-07-23 16:15:12 UTC / 12:15:12 EDT), same attestor, `pays_yield=0`, "bare unstaked spot +only". LINK followed 160s later under the same governing source (KB source-86) — though its +attestation text is materially more qualified, classifying it as a **utility token** (ERC-20, `native` chosen only because the backing enum lacks a `utility` slot). That nuance is worth preserving; "same source" flattens it. @@ -90,8 +91,9 @@ entry_lookback: int = 40, # Donchian-high entry (days); walk-forward OOS defaul ## Gate 4: the live set didn't pass it either -`keel-live.db` rules 1–5 (BTC/ETH/PAXG/ADA/XLM) were created in the same second on 2026-07-24 -13:42:24 at `status = live` with **`promoted_at IS NULL`** — seeded through the bypass +`keel-live.db` rules 1–5 (BTC/ETH/PAXG/ADA/XLM) were created in the same second +(`created_at` 1784914944 = 2026-07-24 17:42:24 UTC / 13:42:24 EDT) at `status = live` with +**`promoted_at IS NULL`** — seeded through the bypass `rules seed` warns about in its own output: > ⚠️ seeded at LIVE status, bypassing the promotion gate. This is for the supervised live-order @@ -121,25 +123,41 @@ have passed. ## The measurement nobody had run The original comment guessed. Running `keel rules backtest` — against a **copy** of `keel.db`, -never the original — settles the direction in three commands: - -| rule | asset | n_trades | win rate | expectancy | profit factor | max DD | -|---|---|---:|---:|---:|---:|---:| -| 21 | SOL | 13 | 23.08% | **−12.41** | 0.259 | 161.3 | -| 23 | LTC | 5 | 0.00% | **−13.09** | 0.000 | 65.5 | -| 25 | LINK | 15 | 20.00% | **−0.665** | 0.630 | 19.4 | -| 22 | XLM | 8 | 37.50% | +0.056 | 11.44 | 0.04 | -| 24 | ADA | 6 | 50.00% | +0.121 | 5.52 | 0.10 | - -All three excluded assets are negative-expectancy; LTC won none of five trades. So the earlier -draft of this document was wrong to say "there is no negative result anywhere for SOL, LTC or -LINK" — there is one, and it was ten seconds away in data already sitting in `keel.db`. - -**Read it with the sample sizes in view.** n = 5–15 against `min_trades = 100`, in-sample, one +never the original — settles the direction. The three excluded rules first, then the five the +sandbox actually trades, for contrast: + +| rule | asset | n_trades | win rate | expectancy | profit factor | max DD | | +|---|---|---:|---:|---:|---:|---:|---| +| 21 | SOL | 13 | 23.08% | −12.41 | **0.259** | 161.3 | excluded | +| 23 | LTC | 5 | 0.00% | −13.09 | **0.000** | 65.5 | excluded | +| 25 | LINK | 15 | 20.00% | −0.665 | **0.630** | 19.4 | excluded | +| 22 | XLM | 8 | 37.50% | +0.056 | 11.44 | 0.04 | | +| 24 | ADA | 6 | 50.00% | +0.121 | 5.52 | 0.10 | | +| 10 | BTC | 13 | 46.15% | +1353.99 | 1.61 | 12177.6 | | +| 11 | ETH | 13 | 30.77% | +45.72 | 1.21 | 1285.0 | | +| 12 | PAXG | 4 | 50.00% | +212.15 | 3.25 | 377.1 | | + +**Compare on profit factor, not expectancy.** Expectancy is quote-currency per trade, so it +tracks the asset's price — BTC's +1354 and XLM's +0.056 are not commensurable, and reading the +column 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: **every excluded asset is +pf < 1 (losing), every included asset is pf > 1.** LTC won none of five trades. + +So the earlier draft of this document was wrong to say "there is no negative result anywhere for +SOL, LTC or LINK" — there is one, and it was ten seconds away in data already sitting in +`keel.db`. + +**Read it with the sample sizes in view.** n = 4–15 against `min_trades = 100`, in-sample, one window, no walk-forward, and on candles six days stale for the excluded three. By this project's own standards (`2026-07-20-first-pbo-run.md` on why high PBO with a flat slope is the *good* shape; §79.13 on 47 of 55 assets failing `t = 1.65`) this is a cheap directional check, not -validation. It cannot promote anything and should not. **None of the five clears the gate.** +validation. It cannot promote anything and should not. **Not one of the eight rules above clears +the gate** — the live five included, and ETH's 30.77% win rate also sits under the canonical +`min_win_rate` of 0.55. + +Note the ordering of events: this measurement is dated 2026-08-07, roughly two weeks after the +2026-07-24 exclusion. It is a **post-hoc vindication** of that decision, not the reason it was +made. The reason it was made remains unrecorded. What it does do is remove the symmetry argument: the two groups are not indistinguishable on evidence, and the difference runs the way the original comment assumed. @@ -172,12 +190,29 @@ status quo, and admission is the operator's call through the deterministic gate 2. **`keel-live.db` carries almost no compliance state.** Screening the live allowlist against a copy, **0 of 5 admit** — BTC/ETH/ADA/XLM reject on missing attestation, PAXG on attestation *and* history, because the attestations and the PAXG waiver exist only in `keel.db`. - Ironically **SOL is the only asset that DB admits** (attested there 2026-08-07 20:29:43). Operationally harmless — rail 1 reads `config.allowlist`, not the DB — but anyone running `keel assets screen` against the live DB gets the opposite of the comment's picture. -3. **Live-seeded rules left in place 14 days**, against `rules seed`'s own instruction. -4. **Stale candles.** `keel fetch` follows the allowlist, so SOL/LTC/LINK daily bars in `keel.db` +3. **The one attestation `keel-live.db` does hold deserves a look, and it is not SOL's + `keel.db` one.** The row is: + + ``` + asset=SOL sector='layer-1 smart-contract blockchain infrastructure' backing=native + pays_yield=0 source='https://www.solana.com/staking' + attested_by='Elmehdi Aitbrahim' attested_at=1786148983 + (2026-08-08 00:29:43 UTC / 2026-08-07 20:29:43 EDT) + ``` + + Two things worth the operator's attention. **(a)** It is same-evening, written ~44 minutes + before this investigation's first commit — not historical state. It was not written by this + work (which touched only scratchpad copies; `~/keel/keel.db`'s mtime is unchanged and every + query here ran `mode=ro`), and `keel-live.db` is the live agent's own DB, so it is written + continuously. But its provenance should be confirmed rather than assumed. **(b)** Its + `source` is a **staking page**, which sits awkwardly against `pays_yield=0` and against every + `keel.db` attestation's "Attests bare unstaked spot only" framing — including SOL's own. That + is a compliance question independent of this document, and it is the operator's to settle. +4. **Live-seeded rules left in place 14 days**, against `rules seed`'s own instruction. +5. **Stale candles.** `keel fetch` follows the allowlist, so SOL/LTC/LINK daily bars in `keel.db` end 2026-07-31 vs 2026-08-06. Re-run the backtests above after a fetch before relying on them. -5. **Two open attestation questions**, neither a defect: LINK's staking floor is funded from +6. **Two open attestation questions**, neither a defect: LINK's staking floor is funded from emissions rather than user fees, and LTC has carried **MWEB** — opt-in confidential transactions — since May 2022, a narrower form of the ZEC privacy question.