Skip to content
9 changes: 5 additions & 4 deletions docs/contributing/oracle-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ does not award oracle credit for a filename alone.
| [#1833](https://github.com/TanStack/db/pull/1833) | Explicit oracle | `packages/db/tests/query/pagination-oracle.property.test.ts` owns inherited collection collation, actual `item2`/`item10` order, exact request options, hostile lexical/numeric controls, and both scan and auto-index paths. It runs in `@tanstack/db`'s `test:oracles` campaign. |
| [#1834](https://github.com/TanStack/db/pull/1834) | Explicit oracle | `packages/db/tests/query/cold-join-reconciliation-oracle.test.ts` owns join/predicate equality equivalence across the established value domains, binary/string and nullish controls, replacement histories, raw lazy demand, and scan/auto-index paths. It runs in `@tanstack/db`'s `test:oracles` campaign. |
| [#1835](https://github.com/TanStack/db/pull/1835) | Explicit oracle | The existing `packages/db/tests/collection-state-retention-oracle.property.test.ts` and `packages/db/tests/optimistic-transaction-oracle.property.test.ts` owners cover separate collection-state and transaction-history laws. Both were already registered in `@tanstack/db`'s `test:oracles` campaign; focused storage/local-only tests remain collateral. |
| [#1837](https://github.com/TanStack/db/pull/1837) | Explicit oracle | The offline scheduler, leadership replay, and serializer owners cover selective replay retirement, durable per-ID settlement, stale-read fencing, lifecycle recovery, native scalar encoding, and prior wire compatibility. They run in the package test campaign; generated owners expose `OFFLINE_ORACLE_{SEED,PATH,RUNS}` or the scheduler's `TANSTACK_DB_OFFLINE_ORACLE_*` replay interface. |
| [#1837](https://github.com/TanStack/db/pull/1837) | Explicit oracle | The offline scheduler, leadership replay, and serializer owners cover selective replay retirement, durable per-ID settlement, stale-read fencing, lifecycle recovery, native scalar encoding, and prior wire compatibility. They run in the package test campaign; generated owners expose `OFFLINE_ORACLE_{SEED,PATH,RUNS}`, and the scheduler and interruption-settlement owners use the shared `TANSTACK_DB_ORACLE_{SEED,PATH,PROPERTY}` replay interface. |
| [#1842](https://github.com/TanStack/db/pull/1842) | No shipped-law case | The PR changed only focused observer tests and introduced no production behavior. `packages/db/tests/live-query-observer.test.ts` remains the correct evidence; no synthetic oracle or campaign claim is added. |

[PR #1816](https://github.com/TanStack/db/pull/1816) preserves existing witnesses,
Expand Down Expand Up @@ -2296,11 +2296,12 @@ properties have separate environment variables; inspect their test headers.
Do not assume the core multiplier reaches them.

The Node expression-index oracle runs matching fixed-seed and seedless-random
campaigns by default. Supplying both replay values selects only the requested
seed and shrink path:
campaigns by default. A path replay of its property selects only the
requested seed and shrink path:

```sh
TANSTACK_DB_WS5A_SEED=1659005 TANSTACK_DB_WS5A_PATH=0 \
TANSTACK_DB_ORACLE_SEED=1659005 TANSTACK_DB_ORACLE_PATH=0 \
TANSTACK_DB_ORACLE_PROPERTY=sqlite-persistence.expression-index \
pnpm --filter @tanstack/node-db-sqlite-persistence test:oracles
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Revised means changed in executable revision 7e4266bb; retained means the assign
| packages/db/tests/live-query-observer-history.property.test.ts | revised |
| packages/db/tests/mutation-handler-type-oracle.test-d.ts | revised |
| packages/db/tests/optimistic-transaction-oracle.property.test.ts | revised |
| packages/db/tests/oracle-replay.fixture.test.ts | retained |
| packages/db/tests/replay-guard-calibration.fixture.test.ts | retained |
| packages/db/tests/oracle-replay.test.ts | revised |
| packages/db/tests/paced-mutations-oracle.test.ts | retained |
| packages/db/tests/query/cold-join-reconciliation-oracle.test.ts | revised |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import { fc } from '@fast-check/vitest'
import { hash } from '../src/hashing/hash'
import { oracleRuns } from '../../db/tests/oracle-config.js'

/**
* A failed structural traversal must publish no reusable hash state.
Expand Down Expand Up @@ -136,7 +137,7 @@ describe(`getter failure does not publish partial structural hashes`, () => {
expectRetryHistory(history),
),
{
numRuns: 100,
numRuns: oracleRuns(100),
...(seed === undefined ? {} : { seed }),
...(path === undefined ? {} : { path }),
},
Expand Down
3 changes: 2 additions & 1 deletion packages/db-ivm/tests/hash-graph-oracle.property.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import { fc } from '@fast-check/vitest'
import { hash } from '../src/hashing/hash'
import { oracleRuns } from '../../db/tests/oracle-config.js'

/**
* Structural hash follows the reachable value graph, not object identity.
Expand Down Expand Up @@ -182,7 +183,7 @@ describe(`structural hash graph boundary`, () => {
expectGraphHash(edges)
}),
{
numRuns: 300,
numRuns: oracleRuns(300),
...(campaign.seed === undefined ? {} : { seed: campaign.seed }),
...(campaign.path === undefined ? {} : { path: campaign.path }),
},
Expand Down
3 changes: 2 additions & 1 deletion packages/db-ivm/tests/hash-identity-oracle.property.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
hash,
registerOpaqueHash,
} from '../src/hashing/hash.js'
import { oracleRuns } from '../../db/tests/oracle-config.js'
import { captureHashSession } from './hash-session'

/**
Expand Down Expand Up @@ -816,7 +817,7 @@ function runOptions(seed: number | undefined) {
)
throw new Error(`TANSTACK_DB_IVM_HASH_IDENTITY_SEED must be an integer`)
return {
numRuns: 300,
numRuns: oracleRuns(300),
...(seed === undefined ? {} : { seed }),
...(replayPath === undefined ? {} : { path: replayPath }),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import { fc } from '@fast-check/vitest'
import { hash } from '../src/hashing/hash'
import { oracleRuns } from '../../db/tests/oracle-config.js'

/**
* Mixed-carrier graphs extend the established structural-hash graph law across
Expand Down Expand Up @@ -271,7 +272,7 @@ describe(`mixed-carrier structural graph laws`, () => {
const hashValue = replayFault === `accept-cycles` ? () => 0 : hash
const property = mixedGraphProperty(hashValue, () => checked++)
fc.assert(property, {
numRuns: 150,
numRuns: oracleRuns(150),
...(campaign.seed === undefined ? {} : { seed: campaign.seed }),
...(campaign.path === undefined ? {} : { path: campaign.path }),
})
Expand Down
3 changes: 2 additions & 1 deletion packages/db-ivm/tests/hash-oracle.property.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import { fc } from '@fast-check/vitest'
import { hash } from '../src/hashing/hash'
import { oracleRuns } from '../../db/tests/oracle-config.js'
import type { Arbitrary } from 'fast-check'

/**
Expand Down Expand Up @@ -113,7 +114,7 @@ function hashProp<Ts extends [unknown, ...Array<unknown>]>(arbitraries: {
)
throw new Error(`TANSTACK_DB_IVM_HASH_SEED must be a 32-bit integer`)
fc.assert(property, {
numRuns: 100,
numRuns: oracleRuns(100),
...(seed === undefined ? {} : { seed }),
...(valueReplayPath === undefined ? {} : { path: valueReplayPath }),
})
Expand Down
72 changes: 32 additions & 40 deletions packages/db-ivm/tests/index-refinement-oracle.property.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@
import { fc } from '@fast-check/vitest'
import { describe, expect, it } from 'vitest'
import { Index } from '../src/indexes.js'
import {
oraclePropertyOptions,
oracleReplayTest,
oracleRuns,
} from '../../db/tests/oracle-config.js'

type Prefix = number | string | bigint
type Value = [Prefix, number | string] | number | string
Expand Down Expand Up @@ -228,58 +233,45 @@ function expectRefinement(

// ---------------------------------------------------------------------------
// Campaigns. The fixed and random campaigns run the same property, grammar,
// check, and budget. `TANSTACK_DB_IVM_INDEX_SEED` and
// `TANSTACK_DB_IVM_INDEX_PATH` select a direct replay.
// check, and budget. A seed alone reseeds the random campaign. A path replay
// of INDEX_REFINEMENT_PROPERTY runs its recorded history, and every other
// test in this file stands aside.

const replaySeed = process.env.TANSTACK_DB_IVM_INDEX_SEED
const replayPath = process.env.TANSTACK_DB_IVM_INDEX_PATH
const campaigns =
replaySeed === undefined && replayPath === undefined
? [
{ name: `20260930`, seed: 20260930 as number | undefined },
{ name: `random`, seed: undefined },
]
: [
{
name: `replay`,
seed: replaySeed === undefined ? undefined : Number(replaySeed),
},
]
const INDEX_REFINEMENT_PROPERTY = `ivm.index-refinement`

describe(`Index refinement oracle`, () => {
if (replaySeed === undefined && replayPath === undefined) {
for (const { name, additions } of pinnedHistories) {
it(`matches the multiset model when ${name}`, () => {
expectRefinement(additions)
expectRefinement(additions, `prefixIdentity`)
})
}
for (const { name, additions } of pinnedHistories) {
oracleReplayTest(it)(`matches the multiset model when ${name}`, () => {
expectRefinement(additions)
expectRefinement(additions, `prefixIdentity`)
})
}

for (const { name, seed } of campaigns) {
it(`matches the multiset model across generated additions (${name})`, () => {
if (replayPath !== undefined && replaySeed === undefined)
throw new Error(`TANSTACK_DB_IVM_INDEX_PATH requires a seed`)
if (
replaySeed !== undefined &&
(replaySeed.trim() === `` ||
typeof seed !== `number` ||
!Number.isSafeInteger(seed))
oracleReplayTest(it)(
`matches the multiset model across generated additions (20260930)`,
() => {
fc.assert(
fc.property(historyArbitrary, (additions) => {
expectRefinement(additions)
expectRefinement(additions, `prefixIdentity`)
}),
{ numRuns: oracleRuns(300), seed: 20260930 },
)
throw new Error(`TANSTACK_DB_IVM_INDEX_SEED must be an integer`)
},
)

oracleReplayTest(it, INDEX_REFINEMENT_PROPERTY)(
`matches the multiset model across generated additions (random or replayed)`,
() => {
fc.assert(
fc.property(historyArbitrary, (additions) => {
expectRefinement(additions)
expectRefinement(additions, `prefixIdentity`)
}),
{
numRuns: 300,
...(seed === undefined ? {} : { seed }),
...(replayPath === undefined ? {} : { path: replayPath }),
},
oraclePropertyOptions(300, INDEX_REFINEMENT_PROPERTY),
)
})
}
},
)

// Positive execution witness: generated histories reach a NaN prefix that
// cancels after another value joined its key.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest'
import { fc } from '@fast-check/vitest'
import { MultiSet } from '../src/multiset.js'
import { oracleRuns } from '../../db/tests/oracle-config.js'
import type { MultiSetArray } from '../src/multiset.js'

/**
Expand Down Expand Up @@ -556,7 +557,7 @@ describe(`MultiSet consolidation oracle`, () => {
fc.assert(
fc.property(historyArb, (history) => expectConsolidation(history)),
{
numRuns: 300,
numRuns: oracleRuns(300),
...(seed === undefined ? {} : { seed }),
...(replayPath === undefined ? {} : { path: replayPath }),
},
Expand Down
3 changes: 2 additions & 1 deletion packages/db-ivm/tests/murmur-stream-oracle.property.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest'
import { fc } from '@fast-check/vitest'
import { oracleRuns } from '../../db/tests/oracle-config.js'

/**
* # Does the murmur stream hash the bytes it is given?
Expand Down Expand Up @@ -86,7 +87,7 @@ describe(`MurmurHashStream`, () => {
fc.property(fc.array(chunk, { minLength: 1, maxLength: 8 }), (chunks) => {
expect(digests(Current, chunks)).toEqual(digests(Reference, chunks))
}),
{ numRuns: 2000 },
{ numRuns: oracleRuns(2000) },
)
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { D2 } from '../../src/d2.js'
import { MultiSet } from '../../src/multiset.js'
import { reduce } from '../../src/operators/reduce.js'
import { output } from '../../src/operators/output.js'
import { oracleRuns } from '../../../db/tests/oracle-config.js'

/**
* # Does the reduce fast path emit what the general path emits?
Expand Down Expand Up @@ -137,7 +138,7 @@ describe(`reduce fast path`, () => {
expect(emitted(runs, false)).toEqual(emitted(runs, true))
},
),
{ numRuns: 1000 },
{ numRuns: oracleRuns(1000) },
)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
assertOnlyKeysAffected,
compareFractionalIndex,
} from '../test-utils.js'
import { oracleRuns } from '../../../db/tests/oracle-config.js'
import { TopKMessageTracker, TopKRelation } from './topk-relation-oracle.js'

// Helper function to check if indices are in lexicographic order
Expand Down Expand Up @@ -163,7 +164,7 @@ describe.each([
),
{
seed,
numRuns: 30,
numRuns: oracleRuns(30),
examples: [
[
false,
Expand Down Expand Up @@ -243,7 +244,7 @@ describe.each([
),
{
seed,
numRuns: 100,
numRuns: oracleRuns(100),
examples: [
[
1,
Expand Down Expand Up @@ -361,7 +362,7 @@ describe.each([
),
{
seed,
numRuns: 100,
numRuns: oracleRuns(100),
examples: [
[
{
Expand Down
Loading
Loading