Build the conditioning registry, and a probe so "proven" stops drifting
The order opens with "two proven clusters live". They are not proven -- the
proven set is empty -- and this is the fourth consecutive order to start from
a stronger claim than the measurements support. Correcting that in prose four
times has not worked, so this session adds scripts/proven-status.js, which
recomputes the answer from the ledger: hits LOSES (-0.096, CI excluding zero),
total_bases INCONCLUSIVE (+0.004), strikeouts INCONCLUSIVE (+0.259 at n=57).
It deliberately reports sample readiness separately from recorded verdicts, so
"n>=500" can never again be read as "passed".
A counting error worth recording. The first read of the top-volume archetype
said BOMBER x hits was 641 rows -- gate-ready. It is 287. model_snapshots
holds one row per prop PER SNAPSHOT CYCLE, so joining it to ledger_entries
counts each ledger row once per cycle it appeared in. Deduping on the ledger
row id gives the true figure, and my own status script had the same bug until
it was fixed. That is the difference between running the gate and being short
by 213.
So no archetype x stat combination reaches the gate. BOMBER x hits at 287 is
the closest; pitcher archetypes are untestable at 58 settled strikeout rows
across all of them, so the pitcher half of this order could not be run.
The registry is built: recordConditioning keys archetype x underlying-skill x
interaction x status with measured lift, and the skill tag is MANDATORY and
enforced -- untagged entries are refused, and PROVEN without sufficient
evidence is refused. validatedSkills() returns the coherent profile as it
stands, which is {} for every archetype, by design.
BOMBER x hits conditioning was tested across the order's categories and every
result is underpowered: arsenal (barrel x breaking share) incremental +0.043,
batted-ball (launch x pitcher GB) +0.001, contact quality -0.020 and -0.015,
K x K -0.063. Within BOMBER the counter still leads on hits, 0.218 to 0.160,
consistent with the closed pooled negative.
One bug fixed mid-run: fromStatcastRow maps percentage and raw fields only and
does not carry pitch_mix, so the arsenal category first reported n=0 for every
row -- it was measuring nothing rather than failing. Without catching it,
"arsenal doesn't matter" would have been recorded from a column that was never
populated.
On defense: I looked for a derivable proxy before calling it unsourceable, and
there isn't one. We ingest no fielding data at all, and opposing pitchers'
hits-allowed conflates pitching with defense, so it would validate the wrong
skill. It needs Savant's fielding endpoint -- free, same host as the five
feeds already ingested -- and it is not sourced here, because sourcing it to
test at n=282 would answer nothing.
Nothing proved, so nothing was recalibrated and nothing shipped.
4,221 tests green (335 suites); web build exit 0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1sivYNqY2TS5ftykmHBU9
This commit is contained in:
@@ -1466,6 +1466,36 @@ phased plan in the Session-57 conversation / BUILD-STATE Next section).
|
||||
Four exceed the |r|>=0.15 effect bar (arm_angle −0.250, whiff +0.213, k_pct
|
||||
+0.206, chase +0.195) but exceeding one of three thresholds is not passing.
|
||||
|
||||
## Conditioning registry + the proven-status probe (Session 86 — non-obvious)
|
||||
- **RUN `node scripts/proven-status.js` BEFORE planning on a "proven" claim.**
|
||||
Four consecutive orders opened by calling null results proven. The script
|
||||
recomputes from the ledger: PROVEN_SET is **EMPTY** (hits LOSES −0.096 CI
|
||||
excluding zero; total_bases +0.004 inconclusive; strikeouts +0.259 inconclusive
|
||||
at n=57). It deliberately reports SAMPLE READINESS separately from RECORDED
|
||||
VERDICTS so "n>=500" is never mistaken for "passed".
|
||||
- **JOINING `model_snapshots` TO `ledger_entries` FANS OUT.** model_snapshots
|
||||
holds one row per prop PER SNAPSHOT CYCLE, so a naive join counts each ledger
|
||||
row once per cycle: BOMBER x hits read as **641** when the true distinct figure
|
||||
is **287**. Always dedupe on `ledger_entries.id`. This is the difference
|
||||
between "gate-ready" and "short by 213".
|
||||
- **NO archetype x stat reaches n>=500.** Best: BOMBER x hits 287, BOMBER x TB
|
||||
142, BOMBER x rbi 128, GHOST x hits 124. Pitcher archetypes are untestable
|
||||
(58 settled Ks across ALL archetypes).
|
||||
- **`featureRegistry.recordConditioning`** keys archetype x SKILL x interaction x
|
||||
status + lift. The skill tag is MANDATORY and enforced (untagged → refused;
|
||||
PROVEN without sufficient evidence → refused). `validatedSkills()` returns the
|
||||
coherent profile — currently `{}` for every archetype, by design.
|
||||
- **`fromStatcastRow` does NOT carry `pitch_mix`** (it maps PCT_FIELDS/RAW_FIELDS
|
||||
only). Attach it explicitly or arsenal features silently read n=0 — which
|
||||
would have recorded "arsenal doesn't matter" from a column that was never
|
||||
populated. pitch_mix shape is `[{type, usage_pct, velo, whiff_pct, ...}]`.
|
||||
- **DEFENSE IS GENUINELY NOT DERIVABLE from what we ingest.** No OAA/DRS/range
|
||||
anywhere; opposing pitchers' hits-allowed conflates pitching WITH defense so it
|
||||
would validate the wrong skill. It needs Savant's fielding endpoint (free, same
|
||||
host as the five feeds already ingested). Don't proxy it.
|
||||
- Within BOMBER, the counter still leads on hits (0.218 vs 0.160) — consistent
|
||||
with the closed pooled hits negative.
|
||||
|
||||
## Active Skills
|
||||
- vyndr-voice (all user-facing output)
|
||||
- prop-analysis (grading methodology)
|
||||
|
||||
Reference in New Issue
Block a user