STATE.md: CURRENT STATUS + OPEN ITEMS orientation block

Top-of-file ground-truth block for orienting a fresh session.

Records what shipped tonight (probability layer revived 32/32, value
engine arc 1, grade-range work, backup durable on-box at 643/643,
model_snapshots retention live with 100 rows incl 36 refusals, ESPN
parser fix) WITH two honest qualifiers rather than a clean win: A still
does not emit in production so the A-RATED marketing hold stands, and EV
is overconfident (+62%/+61%/+56.9% captured, p_win clamps at 0.95) while
hero v2 already ranks on it.

OFF-BOX BACKUP recorded as NOT WORKING and deferred — never succeeded
once, every dump lives only on the Hetzner volume. Documents the two real
blockers fixed (missing base64 decode; container had rsync but no ssh
binary) and the remaining one: the Storage Box offers an EMPTY auth-method
list, which is an account refusing all auth rather than a wrong key.
Explicitly marks as UNVERIFIED that no Chrome/UI diagnostic was run — no
data on the SSH-support toggle, external reachability, project-vs-box key
scope, or any Hetzner outage — and lists those as untested hypotheses in
likelihood order rather than implying they were checked. The full
scratch-Postgres restore proof is recorded as still OWED.

Open items with status: settlement zero-pushes bug, ~28 props/day
unsettled, permanent model-version contamination (with the hard-cutoff
rule), A-grade unreachable, EV overconfidence, edge_pct broken scale, C4
CLV, consistency CV stopgap. Plus the three live credentials to rotate:
Storage Box password, VYNDR_INTERNAL_KEY (pasted in a transcript), and the
GitHub PAT still in .git/config.

Next queued: backtest harness (needs ~2wk history, currently holds one
night), settlement audit, opponent-strength sourcing (MLB solved via
statsapi pitching splits; NBA/WNBA open) behind the source-adapter
pattern, then the metrics engine gated on the harness.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SmNjJAwEnqHPtXbvSZR8kA
This commit is contained in:
Kev
2026-07-20 00:10:02 -04:00
parent 971f641d12
commit 7ea0af2081
+114
View File
@@ -1,6 +1,120 @@
# VYNDR — STATE OF THE WORLD
### As of `cc8e478` (main, DEPLOYED + fingerprinted live), 2026-07-20. This file opens every future session. Update it when a train ships.
---
# 🧭 CURRENT STATUS + OPEN ITEMS — orientation block (2026-07-20, ~03:20 UTC)
*Written to orient a fresh session. Ground truth, not optimism. Everything below
was verified live unless explicitly marked UNVERIFIED.*
## What shipped tonight (all deployed + fingerprinted)
| # | Shipped | Proof |
|---|---|---|
| 1 | **Probability layer revived** — it was DEAD in prod | `p_win`/`ev_pct`/`model_odds`/`value` on **32/32** live grades (was 0/8) |
| 2 | **Value engine Arc 1** — de-vig, EV, value triplet, hero v2 | live: book 140 · fair 125 · model 109, `value:false` correctly |
| 3 | **Grade-range work** — L20 symmetry, `refreshTeamStats` wired, consistency CV guard, `confidence_basis`, dead `mlbGrader.js` removed | suite 279/3325; D emitted on real WNBA data locally |
| 4 | **Backup durable ON-BOX** | dump read back: **643 rows in dump == 643 live**, 18 MB |
| 5 | **`model_snapshots` retention LIVE** (migration 025) | **100 rows** captured over 2 cycles, incl. **36 refusals** |
| 6 | ESPN team-stats parser fixed (`buckets is not iterable`, 0/15 → 15/15) | live refresh |
### ⚠️ Two honest qualifiers on the above
- **A STILL DOES NOT EMIT IN PRODUCTION.** The 11-step grade is now *stored*
(`grade_11`) and A/D are *arithmetically* reachable + locked by tests, but the
±1.0 opponent factor is still dead because `opp_rank_stat` is underivable from
ESPN (see open item 6). Live boards remain **B/C only**.
**→ The "A-RATED" marketing hold STANDS** (`AccuracyBadge` correctly falls
through to "MODEL · X% HIT"; `TopSignals` self-hides). Do not promote A-rated.
- **EV IS OVERCONFIDENT AND UNVALIDATED.** First captured values include
**+62.1% / +61% / +56.9%** — real markets don't offer that. Cause: `p_win`
clamps at `PROB_CEIL` 0.95 off ~10 games. **Hero v2 ranks on `ev_pct`, so it
picks the MOST overconfident read.** Do not surface EV as truth until
calibration runs on the harness.
## 🔴 OFF-BOX BACKUP — NOT WORKING. Deferred. (real state)
**On-box is durable and proven. Off-box has never succeeded once.**
Every dump currently lives only on the Hetzner persistent volume — **a single
box-side loss takes the backups with it.**
Fixed tonight (both real blockers, both now gone):
1. `BACKUP_SSH_KEY` was not base64-decoded → now auto-detects base64 vs raw PEM.
2. Container had `rsync` but **no `ssh` binary**`openssh-client` added to the
Dockerfile. (`Failed to exec ssh` is gone.)
**Remaining blocker — SSH auth is rejected at the Storage Box.** rsync exits 255.
Verified from the dev box with the private key directly:
```
debug1: Offering public key: ... SHA256:ZO3j7en9J7wN7EKcbYHfpyNcxTPw266hJxECUWXoMTo
debug1: Authentications that can continue: <-- EMPTY
Permission denied ().
```
**The server offers NO auth methods at all.** That is not a wrong-key signature —
it is the account refusing all authentication. Port 23 answers with an OpenSSH
banner regardless, which is why SSH can look enabled when it isn't.
**UNVERIFIED — I did NOT run a Chrome/UI diagnostic and have no data on:** the
Hetzner "SSH support" toggle state, an "External Reachability" setting, whether
the key was added at project level vs the box itself, or any Hetzner incident.
Those are the untested hypotheses, listed in likelihood order:
1. SSH support disabled on the Storage Box (separate checkbox from adding a key).
2. Key added to the wrong scope (project/sub-account vs this box).
3. External reachability disabled for the box.
4. Hetzner-side outage — no evidence either way; not checked.
**To close:** confirm the panel shows fingerprint
`SHA256:ZO3j7en9J7wN7EKcbYHfpyNcxTPw266hJxECUWXoMTo`, enable SSH, then
`POST /api/internal/backup/run` and look for `off-box push OK`. **The full
scratch-Postgres restore proof is still OWED and is blocked on this** (needs the
dump off the container; docker is available locally to do it immediately after).
## Open items — with status
| Item | Status | Note |
|---|---|---|
| **Settlement: 0 pushes / 470 settled** | 🔴 OPEN, unstarted | Implausible — hits/TB land on the number regularly. Exact-number push almost certainly mis-scored as hit or miss. Corrupts every accuracy/ROI number. |
| **~28 props/day never settle** | 🔴 OPEN, unstarted | Jul 17 MLB 86 graded/57 settled; Jul 18 103/75. Cause undiagnosed. |
| **Model-version contamination** | 🟠 PERMANENT, mitigate | `ledger_entries` mixes pre/post-2026-07-19-fix grades with no marker; eras cannot be separated retroactively. **Any backtest/accuracy claim off existing ledger history MUST treat the fix boundary as a hard cutoff.** `model_snapshots` stamps `model_version`+`code_sha` so it can't recur. |
| **A-grade unreachable in prod** | 🔴 OPEN | `opp_rank_stat` null; ESPN team endpoint has no defensive metric at all. Marketing hold stands. |
| **EV overconfident** | 🟠 OPEN | Needs calibration before it drives any surface. Hero v2 already ranks on it. |
| **`edge_pct` broken scale (U-deg pt 2)** | 🔴 OPEN | 51.5% of ledger rows exceed the sane cap; worst 620. 13 frontend surfaces render it; **nothing renders `ev_pct`**; it's the free-tier hook; it's written to the append-only `edge` column every cron. |
| **CLV broken (C4)** | 🔴 OPEN | `closing_line == locked_line` on ~95% of rows. BEAT CLOSE suppressed. **CLV ledger stays PRIVATE until backtest-proven.** |
| **Consistency CV floor** | 🟠 STOPGAP | `CONSISTENCY_MIN_MEAN=4` leaves a ±1.0 dead for MLB low-count stats. Real fix = index-of-dispersion classifier; needs a backtest first. |
### 🔑 THREE KEYS TO ROTATE (all currently valid)
1. **Storage Box password** — Kev plans a fresh reset; do it before/with the SSH fix.
2. **`VYNDR_INTERNAL_KEY`** — was pasted in plaintext into a chat transcript
(2026-07-19) and is in the local `.env`. It gates snapshot triggers, backup
runs, settle passes and the newsletter send. **Rotate: Coolify env + local
`.env` together.**
3. **GitHub PAT in the `origin` remote** — plaintext in `.git/config`, leaked
since ~Session 31. Deploys run off `gitea` so it's inert, but it is a live
credential. Revoke on GitHub; the remote can simply be deleted.
## Next queued work (in order)
1. **Backtest harness** — reads `model_snapshots`. **Needs ~2 weeks of history**;
as of now it holds ONE night. Its honest first output is *"cannot validate
yet"* and that is the expected, correct result. Build the instrument now, let
data accumulate.
2. **Settlement-correctness audit** — the two bugs above. Highest-value
correctness work: everything downstream trusts hit/miss.
3. **A-grade / opponent-strength sourcing** — MLB is **solved and verified**:
`statsapi` `teams/stats?group=pitching` returns all 30 teams free with
`era/whip/avg/slg/ops/HR9`, and it's *stat-specific*, which beats what we were
fetching. NBA/WNBA need `stats.nba.com` or derived allowed-points. Implement
behind the **source-adapter pattern** (health check that PAGES on empty —
tonight's ESPN crash was invisible for exactly that reason).
4. **Metrics engine** — archetype-baselined proprietary metrics
(`specs/model-train.md` §2C). **Gated on the harness**: every metric family
ships only if it backtests better than without it.
**Governing docs:** `specs/model-train.md` (value engine + phases + north star) ·
`specs/snapshot-retention.md` (Phase 2 report + schema) ·
`specs/audit-data/grade-collapse.md` · `specs/audit-data/gate-simulation.md`.
---
## 🟢 RETENTION LIVE — model_snapshots capturing (2026-07-20, migration 025 applied)
Phase 2 priority zero. **History now compounds from tonight.** Spec:
`specs/snapshot-retention.md`.