Files
vyndr/scripts/teeth-lineage-productization.js
builtbykev 930d526b01 Lineage productization: a live graph, an observer that doesn't trust it, and a surface that owns only what it knows
The authority review found there was nothing to switch: lineage is a
write-only graph with no living permanent writer and no product consumer.
Authority theater would have been a switch on a consumer that does not exist,
reading a store that is not being written. So: make the graph live, measure it
from outside, and expose the one category it alone owns.

WRITE-PATH FAILURE SEMANTICS, TRACED FIRST. persist(:857) -> the authoritative
cacheSet snapshot:latest(:1404) -> the lineage gate(:1426) -> ledger(:1473).
Lineage failure cannot fail base retention (earlier, separate upsert), cannot
fail publication (the product write precedes the gate), cannot fail the Ledger
(lineageIndex defaults null; the ledger has its own guard), and cannot create a
new partial row (blankLineage() first, atomicity sweep after the catch). The
isolation this tranche needed already existed; only a mode was missing.

THREE MODES, ONE EVALUATOR. `lineageWriteMode` distinguishes OFF /
CANARY_LEASED / PERSISTENT_SHADOW, and the write gate and the status surface
both read it, so they cannot disagree. The canary is CONSULTED, never
converted: its <=4h absolute expiry, its dynamic evaluation and its
fail-closed parse are untouched.

AN AMBIGUOUS CONFIGURATION FAILS CLOSED. If a sport is named by both persistent
mode and an active lease, the two instructions disagree about WHEN WRITING
STOPS — the lease says 22:45, persistent says never. The dangerous reading is
the quiet one: an operator sets a bounded lease believing writing will stop
while persistent keeps it going. We cannot know which they meant, so that sport
writes nothing until the configuration says one thing. The sport allowlist is
the canary's own, so persistent mode can never widen past it.

THE OBSERVER MAY NOT ASK THE WRITER HOW IT DID. settleLedger returned
{settled:0,pending:0} — byte-identical to a healthy "nothing to settle" — while
1,444 rows sat unprocessed, and the watchdog believed it. So `lineageCoverage`
reads durable retained state only, and THE DENOMINATOR MAY NOT CONSULT
lineage_action: eligibility is "the row was published AND a natural key is
derivable from its own identity columns", neither of which the lineage path
writes. If expectation were derived from whether lineage exists, coverage would
be 100% by construction and the metric would be decoration. Zero-expected and
zero-written are kept as different answers.

THE LEGACY BOUNDARY IS OBSERVED, NOT DECLARED. `publication_id` is stamped only
by commitPublication, so the row itself says whether lineage ran. Verified on
production: 5,353 rows carry it — 4,234 complete actions plus exactly the 1,119
historical partial rows — and zero actions exist without one. No epoch constant
is invented; a date would have been a guess about when the writer was on.
publication_id NULL -> LEGACY_UNVERIFIED. Stamped but incomplete ->
LINEAGE_UNAVAILABLE, which is the honest answer for the 1,119 and is never
quietly rewritten as legacy.

THE GRADE-SHIFT BADGE IS UNTOUCHED. revised_from_grade answers "did the letter
change"; lineage answers "which published claim superseded which". Different
questions, and a test now fails if either route learns the word lineage.

Suite 397/5,496/0 · tsc 0 · 15/15 teeth.

TWO OF MY OWN TESTS WERE VACUOUS AND A TOOTH FOUND IT. Tooth 2 came back green
because the isolation tests asserted the slate was published — true whether or
not the exception propagated — while never reaching the lineage gate at all:
the fake grader never fired `onGraded`, so the collector stayed empty and
persistedRows stayed null. Fixed by firing the hook and counting the commit.
A green teeth run means the test is missing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQJeAG8vcDoL5zkiaJyVb8
2026-08-30 22:10:14 -04:00

108 lines
6.2 KiB
JavaScript

#!/usr/bin/env node
/* TEETH — inject, prove the suite CATCHES it, restore byte-identically.
A green teeth run means the injection missed, not that the risk is absent,
so every tooth asserts its own injection landed before the suite is run. */
const fs = require('fs'); const path = require('path'); const cp = require('child_process');
const F = (p) => path.join(__dirname, p);
const P = 'tests/unit/lineageProductization.test.js';
const TEETH = [
{ n: 1, name: 'persistent mode quietly reuses the canary lease',
file: 'src/services/lineageWriteMode.js',
from: " return Object.prototype.hasOwnProperty.call(evaluate(now).modes, sp);",
to: " return canary.isEnabled(sp, now);",
suite: P },
{ n: 2, name: 'a lineage exception is allowed to abort the snapshot',
file: 'src/services/snapshotService.js',
from: " console.warn(`[publication] commit failed for ${sp} (product unaffected):`, e.message);",
to: " throw e;",
suite: P },
{ n: 3, name: 'partial lineage fields survive a failure (no atomicity sweep)',
file: 'src/services/retentionService.js',
from: " if (isValidLineageAction(r)) continue;\n if (LINEAGE_KEYS.some((k) => r[k] !== null && r[k] !== undefined)) cleared += 1;\n Object.assign(r, blankLineage());",
to: " if (isValidLineageAction(r)) continue;",
suite: P },
{ n: 4, name: 'the coverage denominator consults lineage_action',
file: 'src/services/lineageCoverage.js',
from: " if (!r || r.published !== true) continue;",
to: " if (!r || r.published !== true || r.lineage_action == null) continue;",
suite: P },
{ n: 5, name: 'zero durable coverage reported as healthy',
file: 'src/services/lineageCoverage.js',
from: " if (summary.covered_keys === 0) return HEALTH.MISSING_COVERAGE;",
to: " if (summary.covered_keys === 0) return HEALTH.HEALTHY;",
suite: P },
{ n: 6, name: 'zero-expected collapsed into zero-written',
file: 'src/services/lineageCoverage.js',
from: " if (summary.expected_keys === 0) return HEALTH.NO_ELIGIBLE_CLAIMS;",
to: " if (summary.expected_keys === 0) return HEALTH.MISSING_COVERAGE;",
suite: P },
{ n: 7, name: 'the revision badge is switched to lineage',
file: 'src/routes/ledger.js',
from: "const ROW_COLUMNS = 'id, player_key",
to: "const LINEAGE_READ_ID = 'read_id';\nconst ROW_COLUMNS = 'id, player_key",
suite: P },
{ n: 8, name: 'a legacy partial row is elected as an ancestry head',
file: 'src/services/read/readAncestry.js',
from: "const isValidAction = (r) => !!r && VALID_ACTION_FIELDS.every((f) => r[f] !== null && r[f] !== undefined);",
to: "const isValidAction = (r) => !!r && r.read_id !== null && r.read_id !== undefined;",
suite: P },
{ n: 9, name: 'a current missing-lineage claim silently answers LEGACY',
file: 'src/services/read/readAncestry.js',
from: " state: ANCESTRY_STATE.LINEAGE_UNAVAILABLE,\n reason: 'lineage was attempted for this Read and did not complete',",
to: " state: ANCESTRY_STATE.LEGACY_UNVERIFIED,\n reason: 'lineage was attempted for this Read and did not complete',",
suite: P },
{ n: 10, name: 'the observer gains a write verb (history is mutable)',
file: 'src/services/lineageCoverage.js',
from: "async function auditLatestCohort(sport, deps = {}) {",
to: "async function auditLatestCohort(sport, deps = {}) {\n if (deps.__never) await deps.getClient().from('model_snapshots').delete();",
suite: P },
{ n: 11, name: 'participant identity convergence reverted',
file: 'src/services/model/participantIdentity.js',
from: " const canonical = p.mlb_person_id != null ? p.canonical_player_name : null;",
to: " const canonical = null;",
suite: `${P} tests/unit/participantIdentityConvergence.test.js` },
{ n: 12, name: 'the canary lease bound is widened',
file: 'src/services/lineageCanaryConfig.js',
from: "const MAX_LEASE_MS = 4 * 60 * 60 * 1000;",
to: "const MAX_LEASE_MS = 24 * 60 * 60 * 1000;",
suite: 'tests/unit/lineageCanaryLease.test.js' },
{ n: 13, name: 'the retention collision gate is weakened',
file: 'src/services/retentionService.js',
from: " if (seen.has(id)) collisions += 1;",
to: " if (false) collisions += 1;",
suite: `${P} tests/unit/canonicalParticipant.test.js` },
{ n: 14, name: 'model belief moved',
file: 'src/services/intelligence/probabilityEstimator.js',
from: "function estimate", to: "function estimate_TEETH_BROKEN",
suite: 'tests/unit/probabilityEstimator.test.js' },
{ n: 15, name: 'publication eligibility widened (unserved captures become Reads)',
file: 'src/services/retentionService.js',
from: " const served = Array.isArray(s.rows) ? s.rows.filter((r) => r && r.published === true) : [];",
to: " const served = Array.isArray(s.rows) ? s.rows.filter((r) => !!r) : [];",
suite: 'tests/unit/publicationLineage.test.js tests/unit/eventPublication.test.js' },
];
let caught = 0; const missed = [];
for (const t of TEETH) {
const p = F(t.file);
const orig = fs.readFileSync(p, 'utf8');
if (!orig.includes(t.from)) { missed.push(`${t.n} ANCHOR NOT FOUND: ${t.name}`); continue; }
const broken = orig.replace(t.from, t.to);
if (broken === orig) { missed.push(`${t.n} INJECTION NO-OP: ${t.name}`); continue; }
fs.writeFileSync(p, broken);
const present = fs.readFileSync(p, 'utf8').includes(t.to);
let failed = false;
try {
cp.execSync(`npx jest ${t.suite} --testPathIgnorePatterns "/node_modules/" --silent --forceExit`,
{ cwd: __dirname, stdio: 'pipe' });
} catch { failed = true; }
fs.writeFileSync(p, orig);
if (fs.readFileSync(p, 'utf8') !== orig) { console.error('RESTORE FAILED', t.file); process.exit(2); }
if (!present) { missed.push(`${t.n} INJECTION NOT PRESENT: ${t.name}`); continue; }
if (failed) { caught += 1; console.log(` tooth ${String(t.n).padStart(2)} CAUGHT ${t.name}`); }
else { missed.push(`${t.n} NOT CAUGHT: ${t.name}`); console.log(` tooth ${String(t.n).padStart(2)} MISSED ${t.name}`); }
}
console.log(`\n ${caught}/${TEETH.length} teeth landed`);
if (missed.length) { console.log(' PROBLEMS:'); missed.forEach((m) => console.log(' ', m)); process.exit(1); }