Repository navigation
Description
The Electric SDK snapshot-delivery oracle can fail because its random campaign does not generate one declared reach state. The reach guard is correctly rejecting missing coverage; the campaign needs a deterministic witness.
This blocked Test (collections) on #2346 at head e02e09c70ada77d5bbc52b51ebcdd4ee801fe028. CI tested merge commit 0d7e08d22b6d3d29a53e621ea0bd4bdcab458285 against main 1443dc92e5417394acbdc98b782caa9802848ce6. The failing test and retry grammar already exist on that main commit; #2346 changes the shared observer and has no Electric changes.
Failure
tests/electric-sdk-delivery-oracle.property.test.ts
applies installed-SDK snapshot deliveries against an independent overlapping source (random)
property: electric.sdk-snapshot-delivery
seed: -387674631
Error: electric.sdk-snapshot-delivery: generated histories reached these states fewer than 1 times,
so their laws were not enforced there: live-outage-crossed-by-throw (0)
The failure comes from snapshotReach.assertReached() after the 40-history campaign. No row or health refinement assertion failed in this recorded case.
Reproduce
Run against main at the commit above. Use the seed without a shrink path: path replay intentionally disables aggregate reach checks.
TANSTACK_DB_ORACLE_PROPERTY=electric.sdk-snapshot-delivery \
TANSTACK_DB_ORACLE_SEED=-387674631 \
pnpm --dir packages/electric-db-collection exec vitest run \
tests/electric-sdk-delivery-oracle.property.test.ts \
-t 'applies installed-SDK snapshot deliveries.*random' \
--coverage.enabled=false --maxWorkers=2An independent replay of the same fast-check input grammar confirms the missing case without invoking production:
import fc from 'fast-check'
const histories = []
fc.assert(
fc.property(
fc.integer({ min: 2, max: 4 }),
fc.string({ maxLength: 10 }),
fc.record({
failures: fc.array(fc.nat(7), { maxLength: 6 }),
extraLoads: fc.nat(3),
live: fc.array(fc.constantFrom('http', 'throw'), { maxLength: 7 }),
}),
(_width, _name, retries) => { histories.push(retries.live) },
),
{ numRuns: 40, seed: -387674631 },
)
console.log({
histories: histories.length,
fiveOrMoreAttempts: histories.filter((live) => live.length >= 5).length,
fifthAttemptThrows: histories.filter((live) => live[4] === 'throw').length,
})
// { histories: 40, fiveOrMoreAttempts: 6, fifthAttemptThrows: 0 }The driver declares live-outage-crossed-by-throw when the fifth observed attempt throws. This seed supplies no plan with a throw in that position. The input generator can therefore explain the missing reach independently of the observer implementation. This test uses a direct Collection and ShapeStream; it does not instantiate the shared observer.
Relevant source:
Suggested repair and acceptance criteria
- Add shared histories that deterministically reach each required retry boundary, including a throw on the fifth attempt. Use the existing model, SDK production driver, and comparison in both fixed and random campaigns.
- Require fixed-example reach so a future seed cannot remove these witnesses. Check actual SDK attempts at the existing observation cut, as the current driver does.
- Preserve the reach requirements and the 40 generated histories per campaign. Do not address this by lowering the minimum, removing a state, or repeatedly reseeding until green.
- Show the reported seed passes after the grammar repair, and retain calibration that rejects a wrong outage/health result at the intended checkpoint.
This report establishes a sampling-dependent coverage failure. It does not establish a production behavior defect or that retrying CI repairs the oracle.
Activity