Skip to content

chore(tests,tooling): rule the second driver-memory consumer and gate the census (#6664) - #6693

Merged
qq9340100 merged 1 commit into
mainfrom
claude/issue-6664-driver-memory-census
Aug 8, 2026
Merged

chore(tests,tooling): rule the second driver-memory consumer and gate the census (#6664)#6693
qq9340100 merged 1 commit into
mainfrom
claude/issue-6664-driver-memory-census

Conversation

@qq9340100

Copy link
Copy Markdown
Collaborator

Fixes #6664

Maintainer ruling (2026-08-08, on the issue): Option A + Option C in one PR; Option B rejected. This PR is exactly that, and nothing else.

Premise re-verified on current origin/main (d6d1a50)

The issue's grep evidence was taken at e6025e9. Re-run before implementing — still true, with the file drifting one line:

$ git grep -n "from '@objectstack/driver-memory'" origin/main -- '*.ts' | grep -v node_modules
examples/embed-objectql/src/index.ts:17
packages/runtime/src/autonumber-seed-cross-side-parity.integration.test.ts:35
packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts:119

PM assumption 1 also confirmed: PR #6665 already rewrote the ruled file's census sentence to point here, so this PR builds on the post-#6665 wording and does not restore the old "only here" claim.

A — the second consumer is ruled, not migrated

packages/runtime/src/autonumber-seed-cross-side-parity.integration.test.ts gets its own ruling block in the same style as the driver-split file's, stating why its arm is structural rather than a convenience:

  • InMemoryDriver declares supports = {}, so the driver has no autonumber of its own and the engine's fallback seeding owns the counter;
  • SqlDriver advertises the capability, so its own sequence bootstrap answers instead — that is the other arm of the same toBe(), four functions down.

Point the schemaless arm at sqlite :memory: and both arms become the same implementation: the assertion then passes because nothing distinguishes them, not because the two seeders agree. That is the always-green shape this family has already paid for once (#5830 held auth-contains-filter.test.ts back on exactly that measurement, and #5893 migrated it only after #5702 gave its SQL arm a real verdict again).

The freeze half is quoted from the ruling rather than paraphrased — #5704, maintainer 2026-08-06: 「#5499 冻结令冻的是缺陷修复投入,不禁止作参照物使用」.

The driver-split file's census is restated as two ruled consumers, and one inherited inaccuracy is corrected while I was in the block: #5704's consequence reads 「runtime 的 driver-memory devDep 长期保留(仅此一个消费点)」, but the declaration is in packages/runtime's dependencies, not devDependencies (beside driver-sql / driver-sqlite-wasm, which this package declares for the same reason — the datasource factory resolves them by dynamic import), and it now serves two ruled consumers rather than one. The ruling is quoted verbatim; the ledger records what is actually there.

C — the census becomes a ledger with a gate reading it

scripts/check-driver-memory-census.mjs + scripts/driver-memory-census.ledger.json, wired as pnpm check:driver-memory-census and run in lint.yml's ESLint job (static AST, no build needed).

Five invariants, each named in the failure text:

DISCOVERED the scan found at least one binding. Zero is a broken scan, not a retired driver — every other invariant iterates this set.
LEDGERED every module binding and every package.json declaration has a ledger entry whose kind / field matches. An unledgered arrival is the #6664 defect itself.
LIVE every ledger entry still resolves to something the scan found, so a migrated consumer must lose its entry in the same PR.
RULED each ruledConsumers entry is a static import whose file still contains its rulingMarkers.
CENSUS each ruled file states the ruled count verbatim, in a marker derived from the ledger.

CENSUS is the one aimed straight at this card: the old census was prose with no second party, so it expired the first time the hand-edit step was skipped. Now changing the ruled set makes both files' sentences fail until they are rewritten.

Two shape decisions worth flagging, both inside the "your call on the cleanest mechanical shape" the ruling delegates:

  1. The scan is wider than from '...'. It classifies every module-binding position — static import, export ... from, await import(), import() in type position, require(), vi.mock(). The dominant form for this package in this repo is the dynamic import (three shipped consumers use it), so a static-only scan would have had its hole exactly where the next arrival lands. vi.mock is included rather than silently skipped, because an unstated exclusion is the thing this gate replaces — and vi.mock('X', async (importOriginal) => ...) does reach the real module.
  2. AST, not regex. The distinction the census has always drawn is declarations vs mentions. packages/runtime/tsup.config.ts carries the specifier as a bare string in a bundler externals array; the ruled file's own block names the package five times. Positions decide this, so a comment and an externals entry are reported as mentions under --list and never as arrivals.

The ledger holds 16 entries: 11 TS bindings (2 ruled + 9 others) and 5 manifest declarations. The 14 non-ruled ones are not exemptions: each carries a closed-vocabulary axis and a why the gate refuses to accept empty. product-consumer entries are the ones #5704 carved out of the migration surface by name (「⛔ 明确不在本单范围」) — their fate belongs to the package-retirement decision (#5499: A — 维持冻结、暂不退役), not to the test-backend programme.

No --fix / --update flag, for the reason engine-double-contract.baseline.json states for itself: a generator would let a new arrival be admitted by "just run the update command".

Verification

Reverse verification, direction predicted before running — red, twice, in the two places that matter:

The self-test drives both sides of every decision the scanner and the reconciler make, including the direction that matters most here — growing the ruled set to 3 must invalidate every sentence still carrying "2".

$ pnpm check:driver-memory-census
OK  self-test: classifies every module-binding form ... and proves discovery reaches both ruled consumers in the real tree.

@objectstack/driver-memory census: 11 module binding(s) in 11 file(s), 5 manifest declaration(s) — 2 ruled test consumer(s) (#6664 census: 2 ruled consumers).
  ruled    packages/runtime/src/sandbox/undeclared-field-write-driver-split.integration.test.ts  (#5704 Q2 = B, maintainer 2026-08-06)
  ruled    packages/runtime/src/autonumber-seed-cross-side-parity.integration.test.ts  (#6664 A, maintainer 2026-08-08 — inherits #5704 Q2 = B)

check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states "#6664 census: 2 ruled consumers".

Everything else run locally, gates enumerated from .github/workflows/lint.yml one by one rather than from memory:

  • ESLint job: pnpm lint clean, and all 32 check:* steps pass individually (including the new one).
  • Type-check job, the steps that run without the full workspace build: check:type-check-coverage, check:driver-conformance, check:stall-guard, check:skill-frame-sync, check:skill-compatibility — all pass. check:generated --reconcile-only passes unchanged: a root check: script needs no entry in packages/spec's ledger, which reads that package's own package.json.
  • PM assumption 3 verified: pnpm --filter @objectstack/spec build && check:generated reports all 10 generated artifacts up to date — the comment edits cause no artifact churn.
  • packages/runtime: pnpm typecheck clean; full suite 114 passed (114) files / 1696 passed (1696) tests.
  • check:nul-bytes clean, plus the wider self-scan the byte rule asks for when a change touches control-character territory. It earned its keep: a raw NUL had materialized in four template literals of the new script (${e.file} NUL ${e.kind}), invisible to the gate because the file was still untracked at that point. Replaced with real spaces; re-scanned clean.

No changeset

This releases nothing: two test-file comment blocks, an agent-tooling gate script, its ledger, a root package.json script entry and a workflow step. No package's published behaviour changes, so .changeset/ gets nothing and the PR carries skip-changeset.


Generated by Claude Code

… the census (#6664)

Fixes #6664

Maintainer ruling 2026-08-08: Option A + Option C in one PR, Option B rejected.

A — `packages/runtime/src/autonumber-seed-cross-side-parity.integration.test.ts`
gets its own ruling block, inheriting #5704's Q2 = B: its schemaless arm is
structural (InMemoryDriver declares `supports = {}`, so the engine's fallback
seeding owns the counter; SqlDriver advertises the capability and answers from
its own sequence bootstrap, which is the other arm of the same `toBe()`).
The driver-split file's census is restated as two ruled consumers.

C — `scripts/check-driver-memory-census.mjs` + `scripts/driver-memory-census.ledger.json`
replace the prose census with a ledger and a gate: every module binding of
`@objectstack/driver-memory` in a tracked TS file and every package.json
dependency declaration must be ledgered, every ledger entry must still be live,
each ruled file must still carry its ruling markers, and each must state the
ruled COUNT verbatim — so the sentence and the set can no longer drift apart.

The gate polices the retirement programme's bookkeeping only; nothing here
invests in the driver (#5499 freeze).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K94yzy5CVgC2JtrqYAuDk2
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 8, 2026 12:54pm

Request Review

@github-actions github-actions Bot added the size/l label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@github-actions github-actions Bot added ci/cd dependencies Pull requests that update a dependency file tests labels Aug 8, 2026
@qq9340100 qq9340100 added skip-changeset PR has no user-facing published change; bypasses the changeset gate and removed ci/cd dependencies Pull requests that update a dependency file tests labels Aug 8, 2026 — with Claude
@qq9340100
qq9340100 marked this pull request as ready for review August 8, 2026 13:05
@qq9340100
qq9340100 added this pull request to the merge queue Aug 8, 2026
Merged via the queue into main with commit 179f0ae Aug 8, 2026
38 checks passed
@qq9340100
qq9340100 deleted the claude/issue-6664-driver-memory-census branch August 8, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants