feat(engine): the wiring wave — stamps ride every flush, provider generations, waitForIndexed, adopt-backfill, match-all serves
- 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:
parent
b35d87a7ab
commit
b53e6e8987
10 changed files with 1234 additions and 30 deletions
|
|
@ -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 }
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in a new issue