Repository navigation
fix(scripts): engine-double-contract vetoes a native Mongo Collection fake by its own members - #30499
Conversation
…ths again Claude-Session: https://claude.ai/code/session_01Utp6CXoPqLaG33jM98mL1R Co-authored-by: Claude <noreply@anthropic.com>
… fake by its own members A fake of MongoDB's native Collection (insertOne/insertMany/updateOne/ findOne/find) held two engine siblings and a two-parameter findOne, so the gate read it as an engine findOne double. NATIVE_COLLECTION_ONLY_MEMBERS is positive evidence of that shape, consulted under the same object-name guard as the scoped-repository veto: an engine double whose findOne takes the object name first stays in scope, and insertMany stays engine evidence. Claude-Session: https://claude.ai/code/session_01Utp6CXoPqLaG33jM98mL1R Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. 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): |
|
domain:server#6 · os-bill · session_01Utp6CXCS98uhsFQYk64epE 席位核对 · ACCEPT · 2026-11-05T13:39Z · head
|
|
domain:server#6 · os-bill · session_01Utp6CXCS98uhsFQYk64epE 席位记录 · 2026-11-05T13:49Z · Head-sha
|
|
domain:server#6 · os-bill · session_01Utp6CXCS98uhsFQYk64epE 席位核对第 3、6 条补读 · 2026-11-05T13:58Z · head |
Requested by Bill · project thread
domain:server#6 · os-bill · session_01Utp6CXCS98uhsFQYk64epE
维护者速读
check:engine-double-contract)新增一条否决:测试里伪造的 MongoDB 原生Collection(带insertOne/updateOne这类只有原生驱动才有的方法)不再被当成 ObjectQL 引擎替身;driver-mongodb 那个为了过门禁被拆成两半的假对象恢复成原本的一个整体。find、insertMany、findOne,门禁按方法名把它误判成引擎替身,逼着写测试的人把假对象拆开来绕门禁;它的findOne(filter, options)根本不收对象名,不是引擎。findOne第一个参数不是对象名时生效,真正的引擎替身照样被抓(自检有对照);全仓前后读数一致(1230 已钉 / 120 欠账 / 3 豁免),否决只移走这一处、0 个已钉。回滚即撤本 PR,只动门禁脚本和一个测试文件。scripts/check-engine-double-contract.mjs的NATIVE_COLLECTION_ONLY_MEMBERS和isEngineVerbShape里新增的否决分支;同文件自检里的 NATIVE COLLECTION 一组;packages/drivers/driver-mongodb/src/mongodb-declared-column-null-on-write.test.ts。node scripts/check-engine-double-contract.mjs --census,预期末尾一行NATIVE_COLLECTION_ONLY_MEMBERS veto moves 1 construct(s); 0 of them pinned,点名的正是那个 Mongo 测试文件。Fixes #29859
Clause-②: no
Metadata-protocol: none
Skills-docs: none — gate script only
What changes
The false red.
scripts/check-engine-double-contract.mjsattributed an object literal to the ObjectQL engine contract by its member names. A fake of MongoDB's nativeCollectiondeclaringinsertOne/insertMany/updateOne/findOne/findheld two engine siblings (find,insertMany) besidefindOne, so it was discovered as afindOneengine double.isEngineVerbShapethen admitted it on either arity path: a two-parameterfindOne(filter, options)has a second parameter that is neither an id nor a string, and a short-arityfindOne(filter)readsinsertManyasENGINE_ONLY_MEMBERSevidence.Which evidence was wrong. Measured, not assumed:
insertManyis a real member of the engine class (ObjectQL.insertMany(object, rows, options),packages/objectql/src/engine.ts), so removing it fromENGINE_ONLY_MEMBERSwould weaken the engine-side evidence, and it would not have fixed the two-parameter case anyway. What was missing is positive evidence of the OTHER shape. So this adds a fourth arm to the existing evidence architecture:NATIVE_COLLECTION_ONLY_MEMBERS=insertOne,updateOne,deleteOne,replaceOne,bulkWrite,countDocuments,estimatedDocumentCount,findOneAndUpdate,findOneAndDelete,findOneAndReplace. Verified name by name: none is declared inpackages/objectql/src/engine.ts, nor onIDataEngine,IDataDriverorIScopedObjectRepository(packages/spec/src/contracts/); the same grep's control leg hitsinsertManyin engine.ts andfindOnein the contracts.updateMany/deleteManyare left out becauseDRIVER_ONLY_MEMBERSalready vetoes them;distinct/createIndex/watchare left out as too generic to mean "Mongo".isEngineVerbShaperuns right after the scoped-repository veto and under the same object-name guard (takesObjectNameFirst): the member is the evidence, and a verb that takes the object name first keeps the literal in scope however many Mongo-named helpers hang off it. So a real engine double cannot leave scan scope by declaringinsertOne.--censusnow ablates this veto on its own, beside the repository veto, so its reach is re-derivable: on this tree it moves exactly 1 construct, 0 of them pinned.The bent test, restored.
packages/drivers/driver-mongodb/src/mongodb-declared-column-null-on-write.test.tshad been split intosingleRowDb()/batchDb()only so the gate would not seeinsertMany+findbesidefindOne. It is onefakeDb()again, the natural shape the driver sees ((driver as any).db = { collection: () => collection }); the three tests are unchanged.Changeset: none,
skip-changeset: the diff publishes nothing.scripts/**is repo-root tooling, and the driver-mongodb file is a test (files: ["dist", "README.md", "CHANGELOG.md"], tsup entrysrc/index.ts).Tests
main's gate (f273c9f) with the restored test:node scripts/check-engine-double-contract.mjsexit 1,x PINNED [findOne]: packages/drivers/driver-mongodb/src/mongodb-declared-column-null-on-write.test.ts declares 1 engine double(s) whose findOne() does not route through assertEngineFindOnePredicate (line 65).OK — 1230 pinned, 120 in the DEBT ledger, 3 exempt.The NATIVE COLLECTION, the fourth shape (#29859).(7 cases, floor pinned at 7, roster floor 34 → 35), as A/B pairs: the five-member native fake is out of scope for thefindOneslice and the same literal withoutinsertOne/updateOneis discovered; the same pair at one-parameterfindOne(filter); the control the card names, an engine double holdingfind/insertManyplus engine members, is still an unpinnedfindOnedouble; an engine double that also declaresinsertOnestays in scope; a mixed fixture reports exactly the engine double.Acceptance notes
insertManystays in bothENGINE_SIBLINGSandENGINE_ONLY_MEMBERS, deliberately (engine member, measured above).insertMany+find+findOne) is still discovered. That is the A/B control, and the restored test needsinsertOne/updateOneanyway; widening further is a--censusmeasurement, not part of this card.Verification
All readings on head
f443d8b1(branch merged withorigin/mainat f506b79, a merge with no overlap with this diff) unless noted.Gate script: red on main's bytes, green here, one ablation
main's gate (f273c9f) over the restored test,node scripts/check-engine-double-contract.mjsexit 1, one problem:x PINNED [findOne]: …mongodb-declared-column-null-on-write.test.ts declares 1 engine double(s) whose findOne() does not route through assertEngineFindOnePredicate (line 65).OK — 1230 pinned, 120 in the DEBT ledger, 3 exempt.;--self-testexit 0;--censusexit 0,NATIVE_COLLECTION_ONLY_MEMBERS veto moves 1 construct(s); 0 of them pinned, naming onlymongodb-declared-column-null-on-write.test.ts:65.1230 / 120 / 3,1133retained rows,7122/4386/1252/1133provenance on both.scripts/ablation-replace.mjs, anchor 1 → 0, blob 6bad367f → de0d3adc): the veto'sifprefixed withfalse &&.--self-test: 3 failures,a five-member native Mongo Collection fake is out of scope for the findOne slice,a one-parameter native findOne beside insertMany is out of scope,a mixed fixture reports EXACTLY the engine double, not the native Collection; the full run exit 1 naming the Mongo test file. Restored: blob == HEAD 6bad367f,git diff HEADempty.Package suites
os-verify-lock.sh(VERDICT command-exit 0):pnpm --filter '@objectstack/driver-mongodb...' build, thenpnpm --filter @objectstack/driver-mongodb test(Test Files 35 passed, 6 skipped; Tests 728 passed, 194 skipped), thenpnpm --filter @objectstack/driver-mongodb typecheck(tsc +check:test-typecheckOK, 0 debt). The restored file alone: 3/3.Derived gates and lint
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 68 commands, each run with its exit recorded before any pipe; all 68 exit 0.--ranreconciliation:68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN.pnpm lintexit 0;check-nul-bytesexit 0.!, no narrowing arm) and thetest:repoproject.Generated by Claude Code