Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .agents/skills/oracle-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ Read [the oracle guide](../../../docs/contributing/oracle-rubric.md),
and limits in [the coverage map](../../../docs/contributing/oracle-coverage.md).
Follow the subsystem reading requirements in AGENTS.md.

Keep unit tests and standalone concrete type assertions out of oracle files
(ORC-016). Fixed regressions are inputs to the same model, driver, and
comparison as the broader campaign, without their own expected answers.
Compile-time oracles generate legal TypeScript inputs and compare public
types with a reusable independent law; a matrix of fixed assertions does not
satisfy this requirement. Supplemental examples belong in ordinary test files.

Use the [instrument library](../../../docs/contributing/instruments/index.md)
when there is a material uncertainty. Select cards within the authorized task;
there is no required sequence or instrument quota.
Expand Down
7 changes: 7 additions & 0 deletions .changeset/bright-cups-infer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@tanstack/db-sqlite-persistence-core': patch
---

Fix type inference for schema-free collection options wrapped with persistedCollectionOptions and passed to createCollection.

Reject caller utilities that use the reserved local persistence names acceptMutations, getLeadershipState, or forceReloadSubset, instead of silently replacing them.
22 changes: 22 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ is not ready:
the owner and the maintainer decision.
- **Pinned-only coverage:** a named example where the law needs a generator
dimension.
- **Unit tests inside oracles:** ordinary examples or concrete type assertions
placed in an oracle file. A fixed regression must replay the shared model,
production driver, and comparison without its own expected answer.
- **"Pre-existing" as a dismissal:** a reachable counterexample that an agent
labels as older than the change, but does not fix, record in the coverage
map with its trace, or bring to the maintainer for a decision.
Expand Down Expand Up @@ -694,6 +697,25 @@ explain why extending its owner, creating a new independent oracle, or adding a
receiving witness is not practical. Bug fixes cannot use this focused-test-only
exception. They must provide evidence that closes the entire declared bug class.

### Keep Unit Tests Out of Oracles

Oracle files contain reusable laws, independent models, input or history
grammars, shared comparisons, and their execution. Do not put ordinary unit
tests or concrete type assertions in an oracle file. A filename, coverage-map
entry, contract comment, or table of fixtures does not turn examples into an
oracle.

Keep a fixed regression as input to the same model, production driver, and
comparison that the generated campaign uses. It must not carry a separate
expected answer or its own assertions. Checker calibration may supply a wrong
observation to that same comparison. Put supplemental unit tests in ordinary
test files; they do not discharge an oracle-owned coverage obligation.

For compile-time contracts, generate legal TypeScript inputs and check their
public types against a reusable independent type law. A list of
`expectTypeOf` calls or `@ts-expect-error` examples is not an oracle. Negative
checks derived by the shared law from generated inputs are permitted.

### Name Oracle Files for Discovery

Include `oracle` in filenames that own an independent reference computation,
Expand Down
66 changes: 63 additions & 3 deletions docs/contributing/oracle-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,69 @@ of all four public virtual fields directly after implicit, expression, and
functional root publication. Its fixed controlled-Collection cases do not
establish every nested projection shape or framework receiving boundary.

Three type-only owners check compile-time boundaries:
`packages/db-sqlite-persistence-core/tests/persisted-options-type-oracle.test-d.ts`
checks local and synced persisted option input/output and key types;
The generated persistence option type/admission owner is
`packages/db-sqlite-persistence-core/tests/persisted-options-type-oracle.ts`.
It generates row shapes (1–4 scalar, nullable, array, or nested fields), six
key domains, field optionality/readonly modifiers, utility signatures, numeric schema versions,
and network deadlines. Each shape retains 30 construction forms across
local/synced, schema-free/transforming schema, typed-spread/inline arguments,
and inferred/partial/full type arguments, including contextual schema callbacks.
Twelve configured forms cross eager/on-demand/network-first options with schema
and sync modes; network-first remains eager. Two schema-free forms supply a
phantom schema generic without a schema value and still preserve row input.
Eight modifier neighbors cross mutable/readonly first fields with schema and
persistence modes, bringing each shape to 52 core or 53 browser constructions.
Transforming schemas accept their output as input, as required by the schema
guide: their distinguished field narrows string | number to number, and output
optional fields remain optional on input. Exact input equality distinguishes
the two domains; inserting an output row is a legal neighboring observation.

Independent type laws compare insert input, complete published row types,
exact keys, user utilities, added local persistence capabilities (including
optional leadership/reload signatures), option types, and contextual getKey /
markReady callbacks. The browser driver uses real Query Collection options.
Declared schema-compatible-input, readonly-input, readonly-output and
mutable-fields reaches occur structurally in every generated history.
Its independent closed capability model checks direct-write signatures,
observer state, refetch parameters and a non-any Promise-array envelope. A
supplemental before/after relation preserves the full Query utility types;
QueryObserverResult's internal payload has no independent model here.
Fresh-object sync rejection uses an exact unsuppressed overload diagnostic and
a legal neighbor that changes only sync, so a collateral option error cannot
substitute for the promised rejection.

Core and browser `persisted-options.test.ts` runners share the grammar/model
and use their respective receiver tsconfig. Package and root `test:oracles`
commands select them. Both run 12 histories with seed 2259 and 12 with a fresh
seed, measure per-path reach, and accept the shared seed/path/property replay
interface (`persisted-options.types.core` / `.browser`). A shared semantic
builder retains source and declaration diagnostics while caching dependencies;
timeouts scale with the campaign multiplier, and histories yield for worker RPC.
This owner does not execute runtime parsing, adapter I/O, sync, or publication,
and does not check built declarations, npm resolution, other host packages,
every TS version, arbitrary extra-property structural assignment, or the
internal semantics of trusted PendingMutation/LoadSubsetOptions carriers.
The [type-preservation audit](oracle-reviews/pr-2259-persisted-option-types.md)
and `scripts/calibrate-persisted-option-types.mjs` preserve parent RED, GREEN,
legacy-suite survival, hostile-mutant evidence, and runnable overlay recipes.
The readonly-row overlay strips user-property readonly modifiers from get's
return while retaining readonly virtual fields. The prior grammar accepted it;
the modifier histories reject it at the shared exact published-row comparison.

The maintainer chose rejection for local caller utility collisions. The same
owner's runtime admission grammar checks the three reserved names
acceptMutations, getLeadershipState and forceReloadSubset, individually and in
combinations, against both public core/browser wrappers. It crosses local/synced
options, schema presence, function/undefined values, and enumerable/non-enumerable/inherited
properties. Rejection must be an InvalidPersistedCollectionConfigError before
persistence resolution; ordinary local utilities and synced adapter utilities
remain available. Each fixed/fresh campaign measures all ten admission states
under `persisted-options.utilities.core` / `.browser`. No Collection is created,
and no sync, SQLite I/O, native-host or publication claim follows from this path.
The versioned audit records the user decision, original overwrite RED, GREEN,
and guards that check only own/truthy properties or omit a reserved name.

Other existing fixed type checks cover adjacent compile-time boundaries:
`packages/db/tests/mutation-handler-type-oracle.test-d.ts` checks sibling
Collection/key/utilities in mutation handlers; and
`packages/db/tests/query/virtual-row-fields-oracle.test-d.ts` checks all four
Expand Down
Loading
Loading