Files
jianf f3ee2d1cb0 test(memory): pin that the WRITE path marks stale, not the test (C4 follow-up)
C4j asserted that a stale-marked centroid falls back to uncorrected vectors — but it
called `store.markCentroidStale(fp)` **itself** to set up the state. That proves the
recall side honours the flag; it says nothing about whether production ever sets it.

Measured: deleting the one line in `#ensureCentroid` that persists the verdict

    if (status?.stale === true) this.store.markCentroidStale(fingerprint)

left **all 306 criteria green**. The wiring had no guard at all.

This is the fifth instance of one shape in this branch:

    W8   saveSpaceCentroid defined, zero production callers
    C4d  centroid built by the test's own rebuildCentroid call
    P1   vectorScores hand-built in the fixture
    D2   counters computed, never printed
    C4j  stale flag set by the criterion, not by the write path

A hand-fed input cannot prove a production path. So C4k drives only the production
entry points — `apply()` + `commit()` — and marks nothing itself:

    after a settled rebuild   stats.stale === undefined
    after 3 more commits      stats.stale === 1     (drift 3/8 = 37.5% > 20%)

Mutation — deleting that line in `#ensureCentroid`:

    not ok 12 - C4k: the write path itself marks a drifted centroid stale
    error: C4k: the WRITE path must persist the stale verdict ... undefined !== 1

## Why the drift is generated rather than forced

3 commits on top of a settled 8 puts the delta at 37.5%, past the 20% ratio — the
same path an ordinary growing space takes. Forcing `markCentroidStale` directly is
exactly what C4j does and exactly what this criterion exists to complement.

Gates: npm test 307/307 (0 skipped), npm run check 12/12, frozen faces untouched.
2026-11-05 12:39:06 +08:00
..