test(plugin-auth): migrate the contains witness to sqlite, now that $regex is refused (#5893) - #6665
Merged
Conversation
… `$regex` is refused (#5893) `auth-contains-filter.test.ts` pins #5710's `contains` -> `$contains` flip. Its behavioural face ran on `InMemoryDriver` because, when #5830 measured it, driver-sql routed `$regex` through the same `applyContainsLike` as `$contains` — a SQL witness answered the defect and the fix identically, so migrating would have produced pins that pass because nothing distinguishes them. #5702 (PR #6549) deleted that fallthrough and retired the spelling: driver-sql now refuses `$regex` by name in the ADR-0112 envelope (INVALID_FILTER / 400). The expiry condition #5830 wrote for this card is met, so the file moves onto the PR #5880 harness (SqlDriver + better-sqlite3 `:memory:` + real DDL via initObjects) and witnesses its defect through the refusal. - migrate the behavioural face; measured identical answers value-for-value - add a discrimination face: the backend refuses `$regex` (code AND status, naming `$icontains`) while still answering `$contains` — the property that lets the behavioural pins fail at all, so this cannot silently rot back into an always-green pin - strengthen the `^` case with a control read, since "no rows" is the one answer a broken query and a correct one can both produce - drop plugin-auth's `@objectstack/driver-memory` devDep (now zero consumers) + lockfile ripple - revise the census comments in the runtime driver-split pin and the sibling coverage test, which still said this file must not be migrated Reverse-verified: restoring the defect turns 5 of 9 cases red — the contract face plus all four behavioural pins, every one of them via the refusal path rather than a row difference. The runtime pin's "only permanent test consumer in the repository" census had also expired independently of this change (#6468 added a second importer in the same package); it now claims a ruling about itself rather than a repo-wide count, and the second file's disposition is filed as #6664. Fixes #5893 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BM1tNf5U3nEbHKR4fo5qVQ
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Contributor
📓 Docs Drift CheckThis PR changes 1 package(s): 10 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
os-zhuang
marked this pull request as ready for review
August 8, 2026 09:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #5893
Discharges the deferral #5830 recorded as ruling C:
auth-contains-filter.test.ts's witness backend moves fromdriver-memoryto sqlite, on the expiry condition that card wrote for itself rather than on a second opinion.Premise verification (before implementing)
Verified against
origin/main@e6025e9, not against the issue text:drivers:
$regex响亮拒收 +$icontains各后端实现(#4706 裁决 B 案 · 驱动半边) #5702 landed.driver-sql's emitter refuses$regexby name —sql-driver.ts'sdefault:arm callsretiredFilterOperatorErrorbefore the generic unsupported-operator message, and the family's own suites assertcode: 'INVALID_FILTER'+status: 400on it (sql-driver-null-operators.test.ts,sql-driver-icontains-and-retired-operators.test.ts).The PM's mechanism assumption holds, and it was measured rather than assumed — the dispatch explicitly invited falsification. Driving the PR test(plugin-auth): where-operator 覆盖测试迁到 sqlite
:memory:见证;contains pin 实测不可迁,留证上报 (#5830) #5880 harness path (SqlDriver + better-sqlite3:memory:) directly:The four
$containsanswers are value-for-value what the memory backend answered, so the migration costs the fixture nothing; the refusal is reachable through the harness, so the defect is witnessable again.Consumer census. On
origin/main, plugin-auth's only realdriver-memoryconsumers were this test file's import and thepackage.jsondevDep. The other grep hits are prose comments and stay — retirement verification greps declarations, not mentions.What changed
SqlDriver+ better-sqlite3:memory:+ real DDL throughinitObjects, copied from the siblingauth-where-operator-coverage.test.ts(PR test(plugin-auth): where-operator 覆盖测试迁到 sqlite:memory:见证;contains pin 实测不可迁,留证上报 (#5830) #5880). Seed declares only the two columns assertions actually read; the three camelCase keys the old fixture carried (emailVerified/createdAt/updatedAt) are dropped rather than declared, since nothing looked at them and only a schemaless store accepted them (test(rest,plugin-approvals,trigger-record-change): 7 个 integration 测试真迁 driver-sql sqlite :memory:(#5704 批次 3) #5806's "resolve by declaring, not by relaxing").$containsand$regexapart. That property is now pinned in the file — the refusal envelope (codeandstatus, naming$icontains) paired with$containsstill answering on the same fixture. Without it, the daydriver-sqlre-aliases$regexthe behavioural pins would quietly become the always-green asset [finding] #5704 收口后仓内新增一个 driver-memory 测试消费者:plugin-auth/auth-contains-filter.test.ts(#5710 pin 测试,与 #5704 程序不变量的张力,请分诊裁处置) #5830 refused to create, and nothing would say so.^case.expect(rows).toEqual([])is the one assertion an empty seed, a missing table or a dropped predicate all satisfy. It now sits next to acontains('a')read over the same fixture, so the case says the store is live and the predicate really selects.@objectstack/driver-memoryout ofplugin-auth/package.json(zero consumers left) plus the lockfile ripple.pnpm install --frozen-lockfilepasses.[#5830]paragraph, and the sibling coverage test's now-stale "do not finish the job by copying this harness onto it".Reverse verification
Mandatory here, and the direction was predicted before running it: red via the refusal path, not via row differences. Defect restored by flipping the adapter's
containsbranch back to a bare$regex(taken out afterwards withgit checkout --, nevergit stash).Contract face plus all four behavioural pins, every behavioural one through
retiredFilterOperatorError. Fix restored: 9 passed.Reported honestly rather than to the template's shape: the third face stays green under this mutation, and that is correct — it asserts a property of the backend, not of the adapter, and it is precisely what makes the other four go red. A face-3 that moved when the adapter changed would be testing the wrong thing. Stating it here because "every new assertion went red" would have been the tidier sentence and the false one.
Tests and gates
pnpm --filter @objectstack/plugin-auth test— 39 files, 974 passedpnpm --filter @objectstack/plugin-auth typecheck— cleanpnpm --filter @objectstack/runtime exec vitest run src/sandbox/undeclared-field-write-driver-split.integration.test.ts— 6 passed.github/workflows/lint.ymland run one by one, not picked from memory. ESLint job: all 31 steps PASS (pnpm lint,check:slot-lookup,check:query-options-erasure,check:verify-stand-in,check:nul-bytes,check:doc-authoring,check:docs-audit-scope,check:role-word,check:quick-reference-counts,check:adr-anchors,check:org-identifier,check:authz-resolver,check:service-providers,check:route-envelope,check:error-code-casing,check:wildcard-fallthrough,check:meta-type-normalized,check:init-service-contract,check:durability-log-level,check:startup-registry-verdict,check:objectui-changeset,check:release-notes,check:release-body,check:node-version,check:workflow-status-functions,check:shard-attestation,check:published-files,check:engine-double-contract,check:resume-authority-declared,check:merge-driver,check:spec-parsed-alias). TypeScript job: all PASS, including the full workspace build,turbo typecheck(120 tasks),check:driver-conformance,check:type-check-coverage,check:type-check-debt, the spec check family, examples + downstream-contract typecheck, andcheck:i18n/check:i18n-coverage. Also ran the gates other workflows own:check:override-consistency(validate-deps),check:console-sha(ci), and the fourspec-liveness-checkgates.check:driver-conformanceandpnpm install --frozen-lockfilecalled out specifically because of the devDep removal — both green.grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]') — no hits.Changeset
None, deliberately. This PR is tests + comments + the removal of a devDependency. devDeps are not installed by consumers of
@objectstack/plugin-auth, so nothing about the published package changes and there is no user-visible behaviour to describe in release notes.skip-changesetapplied.Out-of-scope finding, filed not fixed
The runtime pin's anchor comment claimed to be "the only PERMANENT test consumer of
driver-memoryin the repository", and that census had already expired independently of this PR: #6468 (PR #6553) addedpackages/runtime/src/autonumber-seed-cross-side-parity.integration.test.ts, in the same package, importing the driver for a reason that reads as permanent as the ruled file's — and outside #5704's ruling.That matters because the census is the enforcement: no gate counts driver-memory consumers, so the comment is the only thing telling the next agent what a grep hit means. Filed as #6664 (
finding, nopm:queue) with the three dispositions and a recommendation. This PR does not fix it — it only stops the comment asserting something known to be false: the sentence now claims a ruling about this file instead of a repo-wide count, and points at #6664.Scope note
The dispatch's file surface was
packages/plugins/plugin-auth/**+pnpm-lock.yaml, while the issue's step 3 and the dispatch's own deliverable list both require the comment revision inundeclared-field-write-driver-split.integration.test.ts— which lives inpackages/runtime, not plugin-auth (the claim comment records the path as plugin-auth's; that is where it actually is). The edit there is comments only, no code, and it is the named deliverable, so it is included and flagged here rather than silently taken or silently skipped. No driver package and nopackages/specfile is touched.🤖 Generated with Claude Code
https://claude.ai/code/session_01BM1tNf5U3nEbHKR4fo5qVQ
Generated by Claude Code