Uh oh!
There was an error while loading. Please reload this page.
test(engine-doubles): add the findOne slice to check:engine-double-contract and adopt assertEngineFindOnePredicate across the re-measured 211-file remainder - #12560
Conversation
…iles / 245 findOne doubles The adoption half of #12068. Discovery was NOT re-derived by hand: the population is `check:engine-double-contract`'s own reported (file, line) answers with a findOne slice installed, so the batch cannot be narrower or wider than what the gate scores. `@objectstack/service-datasource` gains `@objectstack/metadata-core` as a devDependency — the one package in the remainder that depended on neither home of the predicate. Acyclic, measured rather than cited: `turbo run build --filter=@objectstack/service-datasource --dry` exits 0 with zero circular-dependency reports and metadata-core present in the graph. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6HFzyH98W1YaQXhJUJt6o
…ispatch NOT REVIEWED. The dispatch that wrote this stalled before committing or pushing; this commit exists only so the work survives the container, and the resuming dev is expected to inspect it, not to trust it. Contents as found on disk: the findOne slice added to check-engine-double-contract's SLICES table (assertEngineFindOnePredicate / resolveEngineFindOnePredicate, origin #4419), plus the regenerated baseline and pinned ledgers. No gate run, no test run, and no ablation was performed against it here.
…ndone-doubles-remainder
…p left, and alias metadata-core in service-datasource Supersedes the "NOT REVIEWED" disclaimer on 88784b7: the gate half and the 211-file adoption below it have now been run, ablated and re-measured. Three things this commit changes, all of them found by running what that commit never ran. 1. TS2345 in service-messaging. `delivery-headers-at-rest.integration.test.ts` passed the fake's `q: unknown` straight into the predicate, whose parameter is `EngineFindOneQueryInput | null | undefined`. vitest never type-checks, so the suite was green and `tsc --noEmit` was red — the one direction a test-only sweep can go wrong invisibly. Cast at the call, matching the sibling `assertEngineUpdateDispatch(d as any, q as any)` pin three lines below it. 2. service-datasource's engine double reached `@objectstack/metadata-core` through `dist/`. `check:test-source-alias` names the repair and refuses the alternative: alias the specifier in the package's own vitest config, never widen the shrink-only registry. A pin resolved through a build artifact is pinned to whatever was last built rather than to the predicate beside it, which is the single failure a contract pin exists to prevent. 3. Import order in that same test file is now load-bearing, and says so. Aliasing metadata-core to source pulls its import graph into the package's resolution domain, which switches on the clocked-window rule for the whole package — and that rule then misreported a file that has paid its `@objectstack/spec/kernel` load at module top since #10120. Cause is a detector defect filed as #12555: the gate's import regex swallows a bare side-effect import whenever an `import … from …` follows it later in the file. Not worked around in the gate — the fix there needs its own `--self-test` cases — so the statement is placed where the detector reads it correctly, with a comment naming the constraint and the card that removes it.
📓 Docs Drift Check
What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-warren
commented
Aug 26, 2026
PM review — accepted, flipped ready, auto-merge armed. All three open questions answered below.Measured independently, not read off the report: That last line is the one that decides question 1. This PR touches no production source at all — the claim "it publishes nothing" is true by measurement, not by argument. Q1 — |
Fixes#12068
The
findOneslice ofcheck:engine-double-contract, plus the adoption sweep that keeps it green. This is a resumed dispatch: two commits of unverified work were recovered from a stalled seat and pushed by the PM, who vouched for none of it. The provenance section below states exactly what survived that review and what did not.What the slice does, proved rather than declared
A slice appears in the
SLICEStable; being in the table is not the same as biting. Two ablations, each with its direction and counts written down before the mutation ran, and each restored under atrap … EXIT INT TERMwith an emptygit diffafterwards.A — the slice bites, at full population. Reverted all 211 adopted test files to
origin/maincontent, keeping the slice. Anchored on-disk proof first: predicate call sites inpackages/**went 277 → 32, a delta of exactly 245, the predicted number. The gate went red with 422 problems, naming 211 files underPINNED [findOne]and aRETAINED [findOne]coverage-loss line for each. Predicted direction and file count exact.Predicted 245 unguarded doubles, measured 248. The three-double gap is not noise and is worth stating:
protocol.batch-atomic,protocol.batch-not-attemptedandprotocol.upsert-existenceeach pin two doubles through one call site, via the "direct or one helper deep" acceptance the gate documents. 245 call sites + 3 helper-shared doubles = 248. Verified by comparing each file'spinnedcount in the ledger against its literal call-site count — exactly those three files disagree.B — the slice is what catches it. Positive control: un-pin one file (
service-storage/metadata-store.test.ts) → gate red,PINNED [findOne]: … declares 1 engine double(s) … (line 61), 2 hits. Then the same un-pinned file with thefindOneentry deleted fromSLICES→ zero lines mentioning that file underfindOne, and zeroPINNED [findOne]lines anywhere in the repo. The gate is still red, for the different reason predicted in writing: theDECLAREDinvariant fires because the ledgers name a verb no slice scans. A zero-hit only counts because the control fired on the same file a moment earlier.C — the one DEBT row, re-measured rather than inherited. The recovered baseline claimed the pin was tried on
runtime/src/sandbox/quickjs-runner.test.tsand measured red. A DEBT row weakens a shrink-only ratchet, so it was re-run instead of trusted: widening that facade'sfindOneto(object, query)and calling the predicate fails thereads inside the tx also reuse the handlecase withfindOne('[object Object]') selects no particular record— the query read as the object name, because the facade takes its object name from the closure and has no object-name position. The row records a misattribution, not deferred adoption, and it stands.The re-measured remainder
The card's "209 files / 250 doubles" was measured against an older
mainand is stale. Re-measured here againstorigin/main@f28f00fbd2, by ablation A above:main(#11957's objectql adoption and later)The ledger act is two rows, not the 63 the card budgeted for. Both are structural, neither is deferred adoption:
packages/spec/src/contracts/data-engine.test.tscannot import the predicate in principle — verified, both homes (metadata-core,objectql) declare@objectstack/specindependencies, so the import inverts that edge — and the quickjs facade has no object-name argument, per ablation C. The twofindOnecall sites that EXEMPT row calls out as shapes the real engine refuses are at lines 66 and 107 of that file, confirmed verbatim.Were any suites leaning on the permissive double?
That was the card's open question. No. Every affected package's full suite, not just the touched files: 960 test files, 15,488 tests, all green — metadata-protocol 143 (2 skipped), runtime 196, rest 148, plugin-security 83, plugin-auth 81, service-automation 91, service-messaging 29, service-storage 27, service-datasource 27, plugin-sharing 27, mcp 23, core 39, metadata 35, plugin-webhooks 11.
Provenance — what was kept, re-derived, discarded
Kept, after verifying it: the 211-file adoption in
ebae4b6e9e(the pin is the one mechanical line in front of a member each fake already declared), and theSLICESentry, baseline rows and ledgers in88784b7b70.88784b7b70is labelledwipand says "NOT REVIEWED"; that disclaimer is superseded by this PR, and the follow-up commit says so in its own message since history cannot be rewritten without a force-push.Re-derived, not inherited: the remainder count (ablation A); that the slice enforces (ablation B); the DEBT row's red (ablation C); the spec EXEMPT row's dependency-inversion claim and its two refused call sites; and that
engine-double-contract.pinned.json/.seams.jsonare what the tool produces —node scripts/check-engine-double-contract.mjs --writereports632 row(s), 0 added or grown, 0 lostand leaves an emptygit diff, so they are byte-identical to a regeneration, not hand-edited.engine-double-contract.baseline.jsonis the opposite ledger by design — hand-authored, shrink-only, MAINTAINER-ONLY — and its two new rows are the maintainer decision this PR carries.Discarded: nothing was reset. Two defects the recovered work carried were fixed instead (below); the approach itself held up.
Two defects the recovered work left, both found by running what was never run
tscwas red while the suite was green.service-messaging/delivery-headers-at-rest.integration.test.tshanded the fake'sq: unknownto a parameter typedEngineFindOneQueryInput | null | undefined— TS2345. vitest never type-checks, so this is the one direction a test-only sweep goes wrong invisibly. Cast at the call, matching theassertEngineUpdateDispatch(d as any, q as any)pin three lines below it.service-datasource's double reached the predicate through
dist/.check:test-source-aliaswas red with a NEW unaliased artifact import, and it refuses the alternative in its own text: alias in the package's vitest config, never widen the shrink-only registry. Done, anchored. A pin resolved through a build artifact is pinned to the last build rather than to the predicate beside it — the single failure a contract pin exists to prevent.Aliasing metadata-core to source then pulled its import graph into that package's resolution domain, which switches on the clocked-window rule for the whole package — and that rule misreported a file that has paid its
@objectstack/spec/kernelload at module top since #10120. Cause is a detector defect, filed as #12555 and not worked around here: the gate's import regex swallows a bare side-effect import whenever animport … from …follows it later in the file, so the verdict depends on import order. Reduced to three lines: bare import alone → seen; bare import then afromimport → lost; the same two reordered → seen. Fixing it needs its own--self-testcases, a different verification surface from this card, so the statement is placed where the detector reads it correctly with a comment naming the constraint and the card that removes it.Changeset grade — deliberately none,
skip-changesetinsteadThis PR publishes nothing: test files, a repo script under
scripts/, two ledger JSONs, one vitest config and one devDependency. The honest options are a real bump or the label, becausecheck-empty-changesetrejects the empty-frontmatter form outright — and a real bump would put a fabricated line in a customer-facing CHANGELOG ("added a devDependency to a test"). Precedent is the closest sibling: #8987, the adoption-only PR that retired the 29 baseline entries #8639 first-measured for this same gate, added@objectstack/metadata-coreas a devDependency of@objectstack/mcpin the same shape, and carried no changeset.check:published-filesis green.This deviates from the dispatch instruction, which asked for a changeset file; flagged rather than silently decided.
Verification, at
4262dda298The full gate union derived from the real changeset —
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, 216 paths, 33 gates — re-run on this exact head after the last commit, pluscheck:nul-bytes: 34/34 green, each exit code captured before any pipe.check-engine-double-contractprints its own verdict:OK — 689 pinned, 134 in the DEBT ledger, 3 exemptand632 (file, verb) row(s) held by the RETAINED ledger.turbo run typecheckover the nine affected packages that declare one: 38/38. The other five are in the frozen type-check DEBT ledger (#4311) and have notypecheckscript —check:type-check-coverageis green and unmoved. Repo-wideeslint . --no-inline-config: 5208 files, 0 errors, 0 warnings — run in full, so no narrowing is claimed.CI has not converged at the time of writing; per the dispatch contract this lands as a draft with the local reading stated, and the gate job conclusions are the PM's read.
Generated by Claude Code