Repository navigation
test(driver-sql): the three live-MySQL NULL-safe shadow suites model a pre-18 store - #25142
Conversation
…a pre-18 store Since 7b-0 a table initObjects creates holds organization_id NOT NULL, and since 7b-2 a unique: 'organization' declaration keys the plain tenant column. The 12998, 13015 and 15479 live cells pin the NULL-safe hash-shadow arm, so their fixtures now declare the index in its 18.0 form (an input carrying nullSafeColumns, honoured verbatim) and relax the tenant column with asPre18TenantColumn before writing NULL-organization rows. Claude-Session: https://claude.ai/code/session_018gewcgUaNUX9hMkxeP2HE2 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): |
Contract reviewServed-tier: Scope: the net diff against the merge base (3 files, +67/−8), all fixture setup in
Read with them:
① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对 ·
|
| Item | Reading |
|---|---|
| Shape | Draft PR → main. The body opens Refs #25131, with no closing keyword: the generated card closes on the next green hourly run. 3 files, +67/−8. Not governed: check-governed-merges matched 0 of 3 paths. |
| Scope | Seven live-MySQL tests stop failing in their setup. Five failed on 7b-0's NOT NULL tenant column. Two failed because 7b-2 no longer produces the NULL-safe shadow from unique: 'organization'. The fixtures now declare the org-scoped unique in its pre-18 NULL-safe form (nullSafeColumns: ['organization_id'], honoured verbatim) and call asPre18TenantColumn after initObjects. Every assertion stays. |
| Seat's own read | The nullSafeColumns input is #24893's own spelling for the retained path in the driver-turso suites, and four other driver-sql suites on main already declare it. A second initObjects was measured not to restore NOT NULL. No test, cell or assertion is skipped, narrowed or deleted. |
| Review | TIER_DEFAULT. Record 6328472119 is PASS on this head. |
| Declaration | No changeset (test files only; skip-changeset, Check Changeset passed). Clause-②: no (test fixtures only: …) and Metadata-protocol: none at line starts on the PR body. |
| Cross-lane | None. |
| Gates | Dev at e4c6eaf7c: 54 derived, 54 run, all exit 0 (two re-run after the full build). Live, in local containers with CI's recipe: before, 7 failed and 12 passed in the three files; after, 19/19, and the full live driver-sql suite passed 5688 with 2 skipped (242/242 files). The default run passed 3742 with 212 skipped, and the typecheck exited 0. |
| CI | At this read on e4c6eaf7c0: ci-failure GREEN, all 41 check-runs completed, none failed. Temporal Conformance does not run on a PR or in the merge queue, so the next hourly full run after the merge is the in-CI proof. git merge-tree against today's origin/main (abc25a3536) is clean. |
Disposition:
open_questions: one, answered A: model the pre-18 store, keep every assertion.deviations: all accepted:- the 18.0-form index declaration beyond the claim's route, under 按实测修;
- 7 failures, not 6;
- the base
abc25a35; - the AGENTS.md trailers and footer;
- the seat-held subscription.
out_of_scope_findings: the card's own count, noted in the PR, no card.
Landing: ordinary queue (pr_ready + automerge_enable through the relay). After the merge, the seat reads the next hourly full run. Green closes #25131. Red is this card's to root-cause again.
Generated by Claude Code
Refs #25131
Clause-②: no (test fixtures only: no response, status, error, outcome or export moves)
Metadata-protocol: none
main's hourly full run is red inTemporal Conformance (live PG + MySQL), in the step "Run driver-sql suite against both live servers". This PR changes only the fixture setup of the three live-MySQL suites that fail there. No production file moves, and no test or assertion is narrowed, skipped or deleted.What is red, measured on
60b42cd0b7and on today'sabc25a357 failures, not the 6 the card names. The card's count was read on
fccbd9d0d5, before #24893 (d5d8146012, 18.x step 7b-1 + 7b-2) landed. The hourly run's own log at60b42cd0b7(run 39683348463, job 119511306969) lists 7. My local reproduction below lists the same 7, by name.sql-driver-12998-shadow-null-safe-key.test.tscoalesceColumn 'organization_id' cannot be nullField 'organization_id' doesn't have a default valueColumn 'organization_id' cannot be nullsql-driver-13015-shadow-carried-index-drift.test.tsColumn 'organization_id' cannot be nullsql-driver-15479-shadow-plain-unique-duplicates.test.tsColumn 'organization_id' cannot be nullThere are two causes, not one.
initObjectscreatesorganization_idNOT NULL, so the suites' NULL-organization seeds are refused. That accounts for 5 of the 7.unique: 'organization'declaration now keys the PLAIN tenant column. On a fresh table this is correct and certified. So the shadow no longer carriesCOALESCE(organization_id, '__global__'), and a raw-column shadow is no longer drift. That accounts for the other 2.nullSafeColumns(normalizeDeclaredIndex: "honoured verbatim"), which is the shape a database built before 18.x holds.asPre18TenantColumnalone, the route the claim names, greens 5 of the 7 at most. The other 2 would still assert a COALESCE form that the declaration no longer produces.The change (fixture setup only, the three files)
fields: ['organization_id', 'v'], unique: true, nullSafeColumns: ['organization_id'].driver-turso'sturso-remote-drift-detection.test.tsandturso-remote-migration-entries.test.ts.orgUniqueOn, used by all four org tests.orgUniqueOn.pre18OrgUniqueOn, used only by the two failing live tests. The two passing live tests keep the plain declaration.asPre18TenantColumn(driver, table)follows eachinitObjectswhose table then receives NULL-organization rows: seven call sites. This is the pattern 7b-0 wired into the other driver-sql suites.organization_id: null. Only the control does; the plain and global arms stamp an organization or have no tenant column.Measured before the edit
initObjectsdoes not restore NOT NULL. A scratch probe against the built driver on live MySQL 8.0 readinformation_schema.COLUMNS.IS_NULLABLE:initObjects:NO;asPre18TenantColumn:YES;initObjectswith the index, on the same driver (12998 dirty/tail and the 15479 shape):YES;initObjectson a new driver (the 13015 apply shape):YES;detectManagedDriftthen reports[], andapplyMigrationEntries(..., { allowDestructive: true })leaves itYES.asPre18TenantColumnby 7b-0.driver-sqlsuites:declareDialectCell, a dialect cell or anOS_TEST_*_URL. Only these three insert organization-less rows without the relax. The one other hit,sql-driver-tenant-column-not-null.test.ts, inserts NULL on purpose to pin 7b-0's refusal.Verification
Live MySQL 8.0 (
mirror.gcr.io/library/mysql:8.0,SET GLOBAL time_zone = '+08:00') and PostgreSQL 16 (mirror.gcr.io/library/postgres:16, timezoneAsia/Shanghai), both in local containers, with CI's environment:TZ=America/New_York,OS_TEST_MYSQL_URL,OS_TEST_POSTGRES_URLandOS_EXPECT_LIVE_DIALECT_MATRIX=1.abc25a35Test Files 3 failed (3),Tests 7 failed / 12 passed (19): the 7 abovee4c6eaf7cTest Files 3 passed (3),Tests 19 passed (19)pnpm --filter @objectstack/driver-sql test, live PG + MySQL (CI's step)e4c6eaf7cTest Files 242 passed (242),Tests 5688 passed / 2 skipped (5690), exit 0pnpm --filter @objectstack/driver-sql test, default (no live servers)e4c6eaf7cTest Files 230 passed / 12 skipped (242),Tests 3742 passed / 212 skipped, exit 0pnpm --filter @objectstack/driver-sql typechecke4c6eaf7ctsc --listFileslists all three files.Gates on
e4c6eaf7c.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 54 families.check:dual-build-cjs-loadsandcheck:lean-entry-closureexited 3 (PREREQUISITE NOT MET); afterpnpm exec turbo run build --concurrency=2(77/77), both exit 0.--ranreconciliation: "54 derived, 54 run, 0 NOT-MEASURED, 0 UNRUN", a DERIVED zero.origin/mainwas merged before this PR opened: already up to date atabc25a35.Changeset.
skip-changeset:@objectstack/driver-sqlshipsfiles: [dist, README.md, CHANGELOG.md]. Built-dist grep: the test fixture symbols hit 0 files, and the controlrelax_not_nullhits 4.The hourly run.
Temporal Conformance (live PG + MySQL)runs only on push, schedule and dispatch, never on a PR or in the queue. This PR's CI therefore does not run the live cell. The local live run above is its proof here, and the next hourly full run after merge is the proof onmain.Acceptance notes
asPre18TenantColumnalone. The measurement shows that 2 of the 7 failures come from 7b-2's plain key form, not from 7b-0's NOT NULL. The fix stays in the claim's three files and in fixture setup, and follows feat(driver-sql,driver-turso,driver-memory,objectql,cli,metadata-protocol): plain organization key part in new unique indexes; the differ reads COALESCE(tenant) as tenant on a certified database (18.x step 7b-1 + 7b-2) #24893's own Turso precedent for the retained NULL-safe path.fccbd9d0d5. At60b42cd0b7and later it is 7: the extra one is 13015's "reports and repairs a shadow that hashes the raw columns".Generated by Claude Code