feat(engine): the wiring wave — stamps ride every flush, provider generations, waitForIndexed, adopt-backfill, match-all serves
Some checks failed
CI / Node 22 (push) Has been cancelled
CI / Node 24 (push) Has been cancelled
CI / Bun (latest) (push) Has been cancelled

- Watermark stamping fans out at flush: all three projections stamped
  with the committed generation before their flushes persist.
- waitForIndexed(path?, {generation, timeoutMs}) — the one honest read
  barrier for write-then-recall consumers; typed timeout error carries
  the pending count and names the gauge; getIndexStatus() gains
  per-projection gauges. awaitPendingEmbeds() unchanged underneath.
- adoptLogAuthority() self-backfills curable divergences (pre-log
  records, witness drift) by identity re-commit before flipping — a
  fresh brain flips clean; log-ahead divergences still refuse loudly.
- The verification oracle gains VERB legs (all four divergence classes;
  unwired = honest verbsChecked: 0, never a scope claim).
- find({where: {}}) match-all serves (was silent-empty, warm AND cold;
  same fix in count/streaming/subgraph seeding); removeMany({where:{}})
  refuses typed — a match-all bulk delete must be explicit.
- Aggregation native envelope stamped via noteSourceGeneration before
  serializeState; the native-blob restore gates through the same
  adoption verdict as caller-side state (the unconditional adopt dies).
- LC8 pinned: a wholesale directory move opens and serves identically
  across all three intelligences, with history traveling.

Gates: unit 2031/2031 (156 files) · integration 812 (91 files) ·
conformance 27/27.
This commit is contained in:
David Snelling 2026-08-10 10:55:11 -07:00
parent b35d87a7ab
commit b53e6e8987
10 changed files with 1234 additions and 30 deletions

View file

@ -570,15 +570,35 @@ export class AggregationIndex {
}
}
// Restore native provider state from persistence
// Restore native provider state from persistence — GATED by the same
// adoption verdict as caller-side state (the unconditional adopt was an
// asymmetry: a stale native blob restored over a moved store silently
// over/under-counted). 'adopt' restores; 'catchup' restores too (the
// incremental reconciliation drives the provider through
// incrementalUpdate over the exact missing window); 'rescan' SKIPS the
// blob — the flagged rebuild repopulates the provider from source.
// Legacy unstamped envelopes verdict as rescan, loudly, never silently.
if (this.nativeProvider?.restoreState) {
const nativeState = await this.storage.getMetadata('__aggregation_native_state__')
if (nativeState && typeof nativeState === 'string') {
this.nativeProvider.restoreState(nativeState)
} else if (nativeState && typeof nativeState === 'object' && nativeState.data) {
// flush() persists `{ data: serializeState() }`, so `data` is the
// provider's serialized state string.
this.nativeProvider.restoreState(nativeState.data as string)
const blob =
nativeState && typeof nativeState === 'string'
? nativeState
: nativeState && typeof nativeState === 'object' && nativeState.data
? (nativeState.data as string)
: null
if (blob !== null) {
const verdict = this.stateAdoptionVerdict(
'__native__',
nativeState && typeof nativeState === 'object' ? (nativeState as Record<string, unknown>) : {}
)
if (verdict === 'adopt' || verdict === 'catchup') {
this.nativeProvider.restoreState(blob)
} else {
prodLog.warn(
`[Aggregation] native provider state not adopted (verdict: ${verdict}) — ` +
`the flagged rescan repopulates the provider from source`
)
}
}
}
}
@ -614,12 +634,17 @@ export class AggregationIndex {
}
}
// Persist native provider state
// Persist native provider state — stamped. noteSourceGeneration lets the
// provider bake the committed watermark into its OWN envelope before
// serializing (so a native-side reopen can verify honesty without our
// wrapper); the wrapper carries the same stamp for OUR adoption verdict.
if (this.nativeProvider?.serializeState) {
const nativeGen = this.storage.committedGeneration?.() ?? null
if (nativeGen !== null) this.nativeProvider.noteSourceGeneration?.(nativeGen)
const nativeState = this.nativeProvider.serializeState()
await this.storage.saveMetadata(
'__aggregation_native_state__',
{ data: nativeState }
nativeGen === null ? { data: nativeState } : { data: nativeState, sourceGeneration: nativeGen }
)
}