Uh oh!
There was an error while loading. Please reload this page.
test(driver-sql): give ttl onlyWhen $null live pg + mysql legs through the existing cell testkit - #10989
Merged
Merged
Conversation
The suite pinned the Reaper-shaped where
`{ expires_at: { $lt: cutoff }, revoked_at: { $null: true } }` live on
sqlite but COMPILE-ONLY on pg and mysql2 — hand-rolled
`new SqlDriver({ client: 'pg', connection: {} })`, `.toSQL()`, string
assertions. Compile-only proves the SQL text; it cannot prove the server
returns those rows, and it never meets the column type each dialect
actually creates (sqlite TEXT vs a real temporal column).
Extends the existing file through the PG_CELL / MYSQL_CELL testkit the
sibling dialect suites already use, so the compile-only assertions stay
and the live legs declare themselves un-run when the URLs are absent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019yDEhPBC3tcGkW9bkce1HM…ve legs The card assumed CI provisions no live servers. It does: `Temporal Conformance (live PG + MySQL)` runs the whole driver-sql suite against a live postgres:16 and mysql:8.0 with OS_EXPECT_LIVE_DIALECT_MATRIX=1, so these legs execute there — on a required check, against real MySQL 8.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yDEhPBC3tcGkW9bkce1HM
Contributor
📓 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. |
os-elon
marked this pull request as ready for review
August 22, 2026 03:15
os-elon
enabled auto-merge
August 22, 2026 03:15
Uh oh!
There was an error while loading. Please reload this page.
Contributor
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 32548714365 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
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 freeto 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#10836
packages/drivers/driver-sql/src/sql-driver-ttl-onlywhen-null-dialects.test.tsmeasured theReaper-shaped where
{ expires_at: { $lt: cutoff }, revoked_at: { $null: true } }live onsqlite but compile-only on pg and mysql2 — a hand-rolled
new SqlDriver({ client: 'pg', connection: {} }),.toSQL(), string assertions, connection neveropened. It was the only dialect suite in that directory hand-rolling
connection: {}, and the only$nulldialect suite in the package.Compile-only proves the SQL text. It cannot prove the server returns those rows, and it never
meets the column type each dialect actually creates — which is exactly where these two dialects part
company with sqlite.
This extends that file (no new file, so no second
engine-double-contractpin) with live legs throughthe
PG_CELL/MYSQL_CELLtestkit the sibling dialect suites already use. Convergence ontomachinery the repo already has, not new machinery. The compile-only assertions stay — they run with
no server.
What the live legs assert, per dialect
columnInfo()reports a real temporal column, not the TEXT sqlite storessess_expired; the filter sparessess_tombstone(find+count)deleteManydeletes exactly 1 — survivors["sess_live","sess_tombstone"]onlyWhenand the same sweep deletes 2 — survivors["sess_live"]Taxonomy, named: these are coverage-extension controls, not defect controls. Nothing was broken —
the filer measured this by hand and it held on both servers, and it still holds. There is no red
pre-fix tree to point at, so what earns the legs is the UNFILTERED control plus the ablation below.
The two ordinary rows sit only four hours either side of the cutoff on purpose. A zone leak on
these servers is ±8h and ±4/5h from a skewed process, so if the stored instant and the ISO-Z comparand
were ever folded through different clocks,
sess_expiredandsess_livewould swap sides and thefixture would go red. A day-wide margin would absorb exactly the defect the live legs exist to expose.
Measured, on real servers
Provisioned in the dev container — the filer's exact versions:
columnInfo()types observed — they match the filed numbers exactly:expires_atrevoked_attimestamp with time zonetimestamp with time zonedatetimedatetimeRun at
419c627992, withOS_EXPECT_LIVE_DIALECT_MATRIX=1— so a cell that had silently skipped wouldhave been a red, not a green:
The skip is announced, not silent
With both URLs absent,
declareDialectCell(the total form — a provisioned cell is measured, anunprovisioned one is declared un-run, with no third outcome the caller can reach) emits a named
skip:
An un-run cell that reports nothing is the same defect class as the compile-only gap being closed here.
Ablation — the live legs are falsified on BOTH dialects
Predicted direction, stated before the run: red. Dropping
onlyWhenfrom the three live-leg callsites (the card's own UNFILTERED control, applied to the filtered assertions):
The tombstone gets reaped on both servers — the filter is what spares it. A live leg that stayed green
with the filter removed would not be testing the filter.
src/dist reasoning for this ablation: the mutation is confined to the
.test.tsfile itself, andthe subject enters through the relative
'../src/index.js', which vitest resolves to source — nodist/participates in what was mutated, so no rebuild leg applies. (driver-sql's registereddist-resolved deps are
@objectstack/formula,@objectstack/observability,@objectstack/types;none was touched.) Restoration proven on disk:
git hash-object==git rev-parse HEAD:PATH(
7eb670e77020ddc751a4db114490fca9ce8f1b51),git diff --exit-code0, porcelain empty.⚠ Finding: the card's CI premise is FALSE — these legs DO run in CI
The card deliberately deferred this work with "CI provisions no live servers, so a committed live test
adds no CI protection today."That is not true of this package.
.github/workflows/ci.ymltemporal-conformance—Temporal Conformance (live PG + MySQL)— provisions a livepostgres:16and a live
mysql:8.0(SET GLOBAL time_zone = '+08:00'), then runs— the whole suite, not a filtered subset — at
TZ: America/New_YorkwithOS_EXPECT_LIVE_DIALECT_MATRIX=1. So these legs execute in CI, and on a required check(
check:required-contextspins that job name literally).Two consequences worth stating plainly rather than discovering later:
says so; an earlier draft of it repeated the card's claim and was corrected in
419c627992ratherthan shipped.
only environment-dependent pin is the column type, and it is portable by construction: knex's mysql
columnInfo()mapstypefrominformation_schema.columns.DATA_TYPE, which isdatetimefor aDATETIME(3)column on MySQL 8.0 and MariaDB alike (precision lives inCOLUMN_TYPE). Everythingelse is fixed instants — no
now(), no clock dependence, no wording assertions.Per the card's fence, no MySQL error wording is pinned anywhere in these legs — MariaDB is a
protocol stand-in, fine for predicate compilation and row selection, not for error text.
Verification
pnpm --filter @objectstack/driver-sql typecheck— clean (tsc --noEmit, script name echoed)pnpm --filter @objectstack/driver-sql test --maxWorkers=2(no live URLs, the Test Core shape) —104 passed | 5 skipped (109) files, 1786 passed | 67 skipped (1853) tests
node scripts/pm/dispatch-gates.mjs(no path arguments), after the final commit,at
419c627992— 6 path-matched + 5 convention-triggered +check:nul-bytes, all green:check:slot-lookup,check:test-source-alias,check:type-source-resolution,check-ci-filter-parity,check-plugin-teardown-shape,check-affected-docs,check:query-options-erasure,check:type-check-coverage,check:type-check-debt(with theworkspace closure built),
check:engine-double-contract,check:where-matcher,check:nul-bytesNo changeset, deliberately: the diff is one
*.test.tsfile. Nothing user-visible changes andnothing ships —
driver-sqlpublishesfiles: ["dist", "README.md", "CHANGELOG.md"], and testsources are in none of them. Labelled
skip-changesetaccordingly.Generated by Claude Code