Repository navigation
fix(driver-sql): refusals, drift reports and log lines state each decision in words instead of a tracker number (stage 1) - #20795
Conversation
…ision in words instead of a tracker number Text only: no error code, field name, status or behaviour changes. The prose-id ledger is recomputed with --census-ledger; only driver-sql rows leave. Three aggregate refusals keep their citation because a driver-turso test compares them byte for byte with the remote transport's copies. Claude-Session: https://claude.ai/code/session_01DEvba2nBuD4tWzfq8r8NFY Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check38 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 11 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 3d2d460b2a807d73f191b1daa6619f016a1c8814 && git checkout 3d2d460b2a807d73f191b1daa6619f016a1c8814
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 4b4ee88fbc530a155ce3ea0570ad81d905d3afbb 733b0e6815e750e41fdcb3b23efa15cbb799323c && git checkout -B drift-repro 4b4ee88fbc530a155ce3ea0570ad81d905d3afbb && git merge --no-ff 733b0e6815e750e41fdcb3b23efa15cbb799323c
node scripts/docs-audit/affected-docs.mjs --json 4b4ee88fbc530a155ce3ea0570ad81d905d3afbb |
Contract reviewServed-tier: Read-only, at tier, adversarial to the dispatch. Inputs: card #20513 (body and all 13 comments — the census 5900801368, the ruling 5902360492 「20513 A」 A / A, the lane checklist 5902678544, the services pointer 5903999785, the stage-1 claim 5904785587, the stage-1 Check-runs on ① Derived judgmentsScope against the ruling and the claim — right. The ruling orders stages per package until the ledger is empty, all three categories, form D, Text only — right, checked line by line. Every removed and added line in Accept-set and public surface — nothing moves — right. No schema, filter grammar, DDL, route or export changes; a caller sees different prose in the same envelopes with the same Ledger diff — right, exact. Only four Form D, string by string — right. I judged each sentence against its cited card — or, for the five that answer 404 (11067, 11374, 12380, 12999, 13015), against the landing commit and today's docblock:
Pins — right, 18 lines in 6 files. Each number pin moved to the phrase that carries the decision: Two wording notes, not FAIL items (carrier: a later stage of this lane, or whoever next edits these lines): (a) the datetime and time "every value is now one … text form" info line can print beside the warn that follows it naming withheld bare-numeric rows; "every converted value" would be exact. (b) at about 14020 the failed-restore arm reads "Rows without an organization are not constrained, because SQL UNIQUE is NULL-distinct", while the reason in that arm is that no index exists at all; the statement is not false and the remedy it gives is right. ② Semver level
Clause-②: no — right. Nothing an author can write is widened or narrowed; the PR body carries ③ Boundary flagsDev flags (report 5905390342), each answered:
Implemented-by: VERDICT: PASS Generated by Claude Code |
Part of #20513
Clause-②: no
Stage 1 of 5 of this lane (
driver-sql), under the maintainer's A / A ruling on the card. The card stays open for stages 2-5, so this PR carries no closing keyword. Text only: no errorcode, field name, HTTP status, export or control flow moves. Every changed line in the four source files is a string-literal line.What this does
The SQL driver's refusals, drift reports and log lines sent the reader to a tracker number for the reason behind them. Each rewritten string now says that reason in words (form D, as the migration-entry rewrite applied it). Where the sentence already stated what was decided, only the citation goes. Where it did not, the decision is added in words:
sql-driver.tsreference_toDDL refusalregisterObjectskips Zod; the FOREIGN KEY DDL the key used to gate is retired, because it could never fire for a spec-conformant lookup.sql-driver.tsNULL-safe UNIQUE messages (drift plan, restore, hash-shadow, direct, bare-composite fallback)sql-driver.tsforeign column in the hash-shadow slotsql-driver.tsSQLite canonicalisation info linessql-driver.tsMySQL widening info linesTIMESTAMPends at 2038-01-19, keeps no milliseconds and converts through the session timezone; a zero-precisionTIMErounds the canonical milliseconds to the second.cross-field-conformance-cases.tscase notes$notis NULL-safe because each leaf is totalised; the=spelling of a field reference lowers to$eq; only a declared column reaches a SQL identifier position; scalar operators on a JSON column compare the whole serialized text;$fieldcomparands compile, and the positions that cannot compile are refused.The withheld-detail wording now reads "withheld from the message; the full diagnostic is in the server log". That is exactly the Turso remote transport's existing copy, which
remote-transport-compile-refusal-seam.test.tsderives from this driver's sentence by stripping the citation, so the pin still holds.Three strings kept for the driver-turso stage
Three aggregate refusals keep their citation:
sql-driver.tsabout 1674 (undeclared function, 5907), 1778 (per-aggregationfilter, 10413) and 1812 (count_distinctwithoutfield, 6409). Their twins indriver-turso'sremote-transport.ts(about 948, 1071 and 1014) carry the same citation. Tests compare the two faces byte for byte:remote-transport-aggregate-function-refusal.test.tsabout 348, 408, 510 and 576;remote-transport-undeclared-aggregate-keys.test.tsabout 201.So one face cannot drop the number alone. Measured with a one-off ablation on the committed head: deleting only the 5907 citation here, rebuilding
driver-sql(the marker present indist/, 2 files) and running those two driver-turso files gave 8 failed, 25 passed. After the restore (blob equal to HEAD,git diff HEADempty, the marker absent fromdist/, working tree clean) they gave 33/33. No test file was left behind. The order forbids moving another package's ledger rows here, so these three rows (#5907: 1,#10413: 1,#6409: 1) are handed to thedriver-tursostage, where both twins change together.Pins re-pinned: 18 assertion lines in 6 test files
Each asserted a number; each now asserts the words that carry the decision:
#5030(12 lines):sql-driver-unique-violation-predicate.test.ts199, 208, 218, 232, 289;sql-driver-14902-plain-unique-duplicate-preflight.test.ts222, 301, 308;sql-driver-15479-shadow-plain-unique-duplicates.test.ts172, 199, 222;sql-driver-unique-tenancy.test.ts694. They now assertNULL-distinct. The negative pins (289, 222 in 14902, 172 and 199 in 15479) keep their meaning: the plain-unique messages do not borrow the NULL-safe arm's story.#11374(2) and#12999(3):sql-driver-12999-stale-text-remedy.test.ts193, 243 and 196, 210, 224. They now assert the declare-maxLengthsentence, and the absence of the stale-column sentence ("re-declaringmaxLengthchanges nothing here").#11535(1):schema-drift.base-type-mismatch.test.ts114. It now asserts "receives one opaque id instead of a list".Ledger burn-down
scripts/doc-authoring-prose-id.baseline.jsonwas regenerated withnode scripts/check-doc-authoring.mjs --census-ledger. It was generated into a scratch file first, so the growth refusal ran against the checked-in baseline, and then copied into place. Onlydriver-sqlrows moved:driver-sql/src/sql-driver.tsdriver-sql/src/cross-field-conformance-cases.tsdriver-sql/src/schema-drift.tsdriver-sql/src/live-dialect-matrix.testkit.tsWhole ledger: files 227 to 224, pairs 611 to 572, occurrences 931 to 861. The gate's printed "pinned site(s)" (id-bearing string literals) go 794 to 732. A census of every other package's sites before and after is identical.
The two counts on the card, reconciled. The census counted 52 messages, and the ledger holds 73 occurrences. The census's 52 are
sql-driver.ts48 plusschema-drift.ts4. It folds a+chain into one message, so its 48 messages are the gate's 54 string literals. Those 52 messages carry 66 occurrences, the ledger's 62 + 4. The census listing prints ids deduplicated per message, which gives 65. The one gap is the hash-shadow warning, whose two ternary branches each cite 13015. The remaining 7 occurrences are the 7src/-shipped test strings (the six case notes and the testkit error), which sit outside the census's 52-message population.Verification (head
733b0e6815)turbo run buildover thedriver-tursoanddriver-sqlite-wasmclosures (which includedriver-sql): 9/9. Then every package underpackages/: 71/71. Both runs exited 0 under the verify lock.dist/index.jsanddist/index.mjs. The three held citations are the only runtime citations left in them; the other hits are docblocks, which the bundle keeps.@objectstack/driver-sql: 200 files passed and 11 skipped (the live PG / MySQL cells, no server here); 3,248 tests passed and 188 skipped.sql-driver-15479-shadow-plain-unique-duplicates.test.tsis MySQL-only.@objectstack/driver-turso(the byte-parity consumer, reading the rebuiltdist/): 80 files, 2,195 tests passed, 33 skipped.@objectstack/driver-sqlite-wasm(extendsSqlDriver): 36 files, 675 tests passed.@objectstack/driver-sql typecheckexits 0;--listFilesshows it reads all 211 of the package's test files.node scripts/pm/dispatch-gates.mjs --commands(no paths; 12 paths against merge base085ca6bc1) names 71 commands, and all 71 exit 0.check:dual-build-cjs-loads,check:lean-entry-closureandcheck:type-check-debtfirst answered PREREQUISITE NOT MET (exit 3) on the partial build. After the full build they exit 0, andcheck:dts-closurewas re-run there too (71 packages swept).--ranreconciliation: "71 derived, 71 run, 0 NOT-MEASURED, 0 UNRUN".check:doc-authoring: "sibling-package prose ids hold the baseline — 732 pinned site(s) across 224 file(s) ... no growth, no burn-down unrecorded".eslint --no-inline-config --format jsonover the 10 touched TypeScript files reports 10 files, 0 errors and 0 warnings. The population is the touched files, and the count is read from eslint's JSON. The narrowing is safe becauseeslint.config.mjsenables no type-aware linting: the resolvedparserOptionsareecmaVersionandsourceTypeonly, with noprojectorprojectService. So this diff cannot move an untouched file's verdict. The repo-widepnpm lintis CI's.driver-sqlsuite, including the three re-pins in the MySQL-only 15479 file. The requiredTemporal Conformance (live PG + MySQL)job runs the wholedriver-sqlsuite against both servers. Also CI's: the Test Core shards, the Dogfood jobs and the workspace type-check lanes.Acceptance notes
driver-tursostage (stage 4 of this lane). It should rewrite each pair together, thedriver-sqlstring and itsremote-transport.tstwin, and that PR's ledger diff then moves onedriver-sqlrow as well. That is the same serial ledger, one stage later.driver-tursostage.$fieldidentifier note is not readable from this session; that note is rewritten from its own sentence. Each rewritten sentence describes today's code:$fieldcomparands are compiled (the enforce-or-remove question was answered "enforce"), the=lowering fix landed, and the FK DDL is retired.Generated by Claude Code