feat: committedGeneration capability + pinned durability/stability contracts
- storage.committedGeneration(): the committed watermark exposed on the fact-scan capability, so a provider compares its stamp's sourceGeneration against the store's truth without parsing the private manifest format (the capability source now carries both the live fact log and the committed closure). - Pinned contract tests: fsync-before-ack (transact passes today; the single-op path is pinned via it.fails as the documented target — group commit must become LATENCY batching, ack waiting on the shared fsync, never durability skipping; the pin flips red when that lands so there is no cliff to discover) and scan-stability-under-rotation (a scan snapshot yields exactly its facts — no gaps, duplicates, or bleed-in — while segments rotate beneath it; the reclaim-during-scan variant lands with fact compaction, which does not exist yet). - FactLog accepts a rotateBytes option so tests exercise real rotation.
This commit is contained in:
parent
e4f37cd32b
commit
d1ecee10f0
6 changed files with 177 additions and 11 deletions
|
|
@ -851,11 +851,19 @@ export abstract class BaseStorage extends BaseStorageAdapter {
|
|||
// fact-log reader themselves — the log's open path is writer-side.
|
||||
// ==========================================================================
|
||||
|
||||
/** The host-wired fact-scan source (a closure over the live fact log). */
|
||||
private _factScanSource: (() => import('../db/factLog.js').FactLog | null) | null = null
|
||||
/** The host-wired fact-scan source (closures over the live generation state). */
|
||||
private _factScanSource: {
|
||||
factLog: () => import('../db/factLog.js').FactLog | null
|
||||
committedGeneration: () => number
|
||||
} | null = null
|
||||
|
||||
/** HOST-ONLY: wire (or clear) the fact-scan capability's source. */
|
||||
public setFactScanSource(source: (() => import('../db/factLog.js').FactLog | null) | null): void {
|
||||
public setFactScanSource(
|
||||
source: {
|
||||
factLog: () => import('../db/factLog.js').FactLog | null
|
||||
committedGeneration: () => number
|
||||
} | null
|
||||
): void {
|
||||
this._factScanSource = source
|
||||
}
|
||||
|
||||
|
|
@ -866,19 +874,29 @@ export abstract class BaseStorage extends BaseStorageAdapter {
|
|||
kinds?: Array<'noun' | 'verb'>
|
||||
batchSize?: number
|
||||
}): import('../db/factLog.js').FactScanHandle | null {
|
||||
const log = this._factScanSource?.()
|
||||
const log = this._factScanSource?.factLog()
|
||||
return log ? log.scanFacts(options) : null
|
||||
}
|
||||
|
||||
/** The fact log's head generation, or `null` when no fact log exists. */
|
||||
public factLogHeadGeneration(): number | null {
|
||||
const log = this._factScanSource?.()
|
||||
const log = this._factScanSource?.factLog()
|
||||
return log ? log.headGeneration() : null
|
||||
}
|
||||
|
||||
/**
|
||||
* The COMMITTED generation watermark (the manifest truth) — the value a
|
||||
* projection's `sourceGeneration` compares against. Exposed here so a
|
||||
* provider never parses the store's private manifest format. `null` when
|
||||
* the capability is unwired (no host, or a bare adapter).
|
||||
*/
|
||||
public committedGeneration(): number | null {
|
||||
return this._factScanSource ? this._factScanSource.committedGeneration() : null
|
||||
}
|
||||
|
||||
/** Sealed fact-segment paths (zero-copy handoff); empty when none. */
|
||||
public factSegmentPaths(options?: { fromGeneration?: number }): string[] {
|
||||
const log = this._factScanSource?.()
|
||||
const log = this._factScanSource?.factLog()
|
||||
return log ? log.segmentPaths(options) : []
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue