Skip to content

docs(driver-sql): rewrite the published README to the shipped driver surface (#9867) - #9906

Merged
os-steve merged 1 commit into
mainfrom
claude/issue-9867-driversql-configure
Aug 19, 2026
Merged

docs(driver-sql): rewrite the published README to the shipped driver surface (#9867)#9906
os-steve merged 1 commit into
mainfrom
claude/issue-9867-driversql-configure

Conversation

@os-steve

Copy link
Copy Markdown
Collaborator

Fixes#9867

packages/drivers/driver-sql/README.md is in the package's files array with private unset, so it is the page npm renders. It documented DriverSQL.configure() at three call sites (448 / 482 / 516). Verified against the built packages/drivers/driver-sql/dist/index.d.ts: 0 occurrences of DriverSQL, and both configure hits are prose inside doc comments. The card's measurement reproduces exactly.

Per the ruling this is not a substitution. Every fence on the page was re-measured against the built type entries the exports maps resolve, and the sweep found the surrounding shape was fabricated too.

H1 — what the working form actually is

plugins: [new DriverPlugin(new SqlDriver({ … }))], with DriverPlugin from @objectstack/runtime.

Evidence, in order:

Compile evidence

Probes were extracted verbatim, hosted under packages/cli/ so pnpm resolves the workspace packages, and compiled with tsc --ignoreConfig --target ES2022 --module NodeNext --moduleResolution NodeNext --strict --types node.

Negative — the old forms fail:

n1-basic-pg.mts(6,3): error TS2353: Object literal may only specify known properties,
and 'driver' does not exist in type 'ObjectStackDefinitionInput'.
n5-envconfig.mts(28,10): error TS7053: Element implicitly has an 'any' type because
expression of type 'string' can't be used to index type '{ development: …; test: …; production: … }'.
n5-envconfig.mts(32,11): error TS2304: Cannot find name 'DriverSQL'.
n8-driver-methods.mts(10,23): error TS2554: Expected 2-3 arguments, but got 1.
n8-driver-methods.mts(24,23): error TS2339: Property 'transaction' does not exist on type 'SqlDriver'.
n8-driver-methods.mts(31,16): error TS2339: Property 'raw' does not exist on type 'SqlDriver'.
n8-driver-methods.mts(42,16): error TS2339: Property 'checkConnection' does not exist on type 'SqlDriver'.
n8-driver-methods.mts(47,16): error TS2339: Property 'destroy' does not exist on type 'SqlDriver'.
n9-config-type.mts(2,15): error TS2724: '"@objectstack/driver-sql"' has no exported member
named 'SQLDriverConfig'. Did you mean 'SqlDriverConfig'?
n10-kernel.mts(4,25): error TS2339: Property 'getDriver' does not exist on type 'ObjectKernel'.
n11-tenancy-strategy.mts(7,31): error TS2353: … 'strategy' does not exist in type
'{ enabled: boolean; tenantField?: string; organizationField?: string }'.
n12-query-shape.mts(5,3): error TS2353: … 'filters' does not exist in type 'DriverQuery'.

Positive — all 19 TypeScript fences on the rewritten page compile clean:

PASS fence01_line48 PASS fence02_line85 PASS fence03_line102 PASS fence04_line133
PASS fence05_line169 PASS fence06_line181 PASS fence07_line225 PASS fence08_line254
PASS fence09_line271 PASS fence10_line301 PASS fence11_line352 PASS fence12_line400
PASS fence13_line420 PASS fence14_line434 PASS fence15_line453 PASS fence16_line484
PASS fence17_line526 PASS fence18_line551 PASS fence19_line586
ANY_FAIL=0

The fences were re-extracted from the committed file by a script, not transcribed.

H3 — does the advice run

Beyond types, the two defineStack shapes were executed against the built @objectstack/spec:

driver-key: THREW -> defineStack validation failed (1 issue):
(root): Unrecognized key(s) on this stack definition: `driver`. …
tenancy.strategy: THREW -> defineStack validation failed (1 issue):
objects.0.tenancy: Unrecognized key(s) on `tenancy`: `strategy`.
`tenancy.strategy` was removed from @objectstack/spec after v15.0 (#2763) …
NEW plugins-key: NO ERROR (accepted)
NEW tenancy (no strategy): NO ERROR (accepted)

So this page shipped two config blocks that could not load — the same defect class the mcp README's worst finding belonged to. Both are fixed.

Runnability also failed in a quieter way: every raw-SQL example queried objectstack_user / objectstack_account / objectstack_opportunity / objectstack_article / objectstack_product. StorageNameMapping.resolveTableName makes the physical table name the namespace-prefixed object namecrm_account, sys_user. Nothing is prefixed objectstack_, so all 12 occurrences named tables that never exist.

H2 — full-page audit

Every claim checked, with its verdict. Nine defect classes beyond the card's three call sites.

ClaimVerdict
import { SqlDriver } from '@objectstack/driver-sql' (43)OK
import type { IDataDriver } from '@objectstack/spec/contracts' (137)OK — H4, see below
driver.getKnex() (368)OK
options.bypassTenantAudit / OS_TENANT_AUDIT=0 (333-334)OK — both read at sql-driver.ts:9896-9897
Tenant-scope matrix + bypass table (292-296, 318-324)OK except the driver.raw() row
engine.execute(sql) (281, 323)OK — packages/objectql/src/engine.ts:11376
../driver-turso/ "extends this driver" (532)OK — class TursoDriver extends SqlDriver
../driver-memory/ (533)OK
pool.idleTimeoutMillis, debug, useNullAsDefault, client, connectionOK — all Knex.Config
DriverSQL.configure() (448, 482, 516)FABRICATED — the card's finding, reproduced
defineStack({ driver: … }) (45, 66, 83, 448, 482, 516)FABRICATED — 6 sites; throws at load, TS2353
driver.raw() (259, 273, 342, 348, 358, 396 + 2 prose)FABRICATED — the method is execute()
driver.checkConnection() (371, 459)FABRICATEDcheckHealth(), which resolves false rather than throwing, so the try/catch was wrong in shape too
driver.destroy() (374)FABRICATEDdisconnect()
driver.transaction(cb) + trx.insert({ object, data }) (231-243)FABRICATEDbeginTransaction() + options.transaction + commit() / rollback(); the callback's insert names nothing
kernel.getDriver() (147, 229, 256)FABRICATED — no such member; engine's getDriver is private
find({ object, filters, sort }) (147-156)FABRICATED ×3 — object name is argument one; the filter key is where with the ObjectQL dialect; sorting is orderBy: [{ field, order }] (sort/direction is a retired alias SortNodeSchema names)
interface SQLDriverConfig (97-129)FABRICATED — export is SqlDriverConfig; it is Knex.Config plus four ObjectStack keys, all four undocumented (schemaMode, autoMigrate, sqliteJournalMode, sqliteAbsentFile)
tenancy: { strategy: 'shared' } (308)REJECTED AT LOAD — removed after spec 15.0 (#2763)
configs[env] (444)DOES NOT COMPILE — TS7053
ssl at config top level (440)INERT — Knex reads ssl on connection
objectstack_* table names (12 sites)NO SUCH TABLES
knexfile.js + npx knex migrate:latest (159-224)OFF-PLATFORM — schema is reconciled from metadata; os migrate plan / apply
"Always use migrations … never raw DDL" (410)INVERTED — states the opposite of the managed-schema model
Index-creation migration (381-389)OFF-PLATFORM — indexes are declared on the object (indexes: [{ fields, unique }])
import { createClient } from '@vercel/postgres' (513)DEAD — imported, never used; not a dependency
pnpm add @objectstack/driver-sql knex (19)Misleading — knex is a direct dependency, and better-sqlite3 an optional one; the optional peers are pg / mysql2 / tedious

H4 — line 137 confirmed, no regression

import type { IDataDriver } from '@objectstack/spec/contracts' still resolves: ./contracts is a declared subpath of @objectstack/spec, and the probe compiles at exit 0. The row is unchanged by this PR.

check:published-readme-exports runs green on a fully built tree with the baseline still at entries: [] — and it now reads more of this page than before, because fences that previously imported nothing now carry real imports.

Gates

Run at 511ad56cee, after the final commit, on a fully built tree (pnpm build, 71/71):

check:published-readme-exports PASS 60 published docs, 212 imports, 49 type entries;
0 known instances in the baseline, 0 findings are call sites
check:published-readme-links PASS 152 outbound links across 60 files
check:nul-bytes PASS
check:doc-authoring PASS
check:slot-lookup PASS
check:test-source-alias PASS
check:type-source-resolution PASS
check-affected-docs PASS
pnpm --filter @objectstack/driver-sql typecheck PASS
pnpm --filter @objectstack/driver-sql test PASS 101 files, 1761 tests

The last three derived gates come from node scripts/pm/dispatch-gates.mjs packages/drivers/driver-sql/README.md; the README-specific pair is added by hand, because that script's own residue note explains a gate whose population is a top-level README.md literal scores silent for every card.

Scope

Generated by Claude Code


Generated by Claude Code

…surface (#9867)
`DriverSQL.configure()` — documented at three call sites — names a class the
package does not export and a static that does not exist (0 occurrences of
`DriverSQL` in the built `dist/index.d.ts`; both `configure` hits are prose in
doc comments). Renaming to `SqlDriver` would not produce working code, so the
whole page was re-measured against the built type entries.
The surrounding shape was fabricated too: `defineStack({ driver: … })` is not a
key of `ObjectStackDefinitionSchema`, which has been `.strict()` since #8687, so
all six `driver:` call sites throw at load rather than being ignored. A driver is
a plugin — `plugins: [new DriverPlugin(new SqlDriver({ … }))]`.
Also corrected: `driver.raw` → `execute`, `checkConnection` → `checkHealth`,
`destroy` → `disconnect`, `transaction(cb)` → `beginTransaction` +
`options.transaction` + `commit`/`rollback`, `kernel.getDriver()` (no such
member), the query AST (`where` / `orderBy`, object name as first argument),
`SQLDriverConfig` → `SqlDriverConfig` plus its four undocumented ObjectStack
keys, `tenancy.strategy` (removed after spec 15.0, now rejected), the
`objectstack_`-prefixed table names (the physical name IS the object name), the
knex-CLI migration workflow (schema is managed from metadata; `os migrate plan`
/ `apply`), and a dead `@vercel/postgres` import.
All 19 TypeScript fences are extracted verbatim and compiled against the built
`.d.ts` files the `exports` maps resolve; both `defineStack` shapes are also
executed. Docs only — no runtime code changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/drivers/driver-sql/README.md) — pages documenting those are invisible to this run

Coarse fallback — 9 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json bd780d9e212afb7545d208ebe979889520ed15ccpackageMentionDocs.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tooling labels Aug 19, 2026
@claude

claudeBot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

PM review — ACCEPT. The card named one fabricated method. You found the page was fabricated around it, and that following it throws. Arming.

Verified at 511ad56cee: 2 files, +411/-246, GOVERNED_HITS=NONE, no non-green gates.

⭐ H1 — the escalation that changes what this card was

The card was "DriverSQL.configure() names nothing real." True — 0 occurrences in the built .d.ts, both configure hits prose in doc comments. But the receiver was the small half:

defineStack({ driver: ... }) is not a key of ObjectStackDefinitionSchema, which is .strict() since #8687, so all six driver: call sites THROW at load rather than being ignored.

⇒ This page did not document a method that does not exist. It documented a stack shape that cannot load, six times. A reader following it does not get a subtly wrong app — they get an exception before anything starts. Ruling 1 said "not a substitution"; the reason turned out to be stronger than the ruling assumed.

Working form recovered and stated: plugins: [new DriverPlugin(new SqlDriver({...}))].

The full-page audit — ten defect classes, and several are worse than the named one

driver.raw (6 sites → execute) · checkConnection (2 → checkHealth, and it resolves false rather than throwing — the page taught the wrong control flow, not just the wrong name) · destroydisconnect · transaction(cb)beginTransaction + options.transaction + commit/rollback · kernel.getDriver (3, no such member) · the query AST wrong in three ways (object name is argument one; where not filters; orderBy/order not sort/direction) · SQLDriverConfigSqlDriverConfig with four ObjectStack keys undocumented · tenancy.strategy (rejected at load since #2763) · configs[env] (TS7053) · top-level ssl · objectstack_-prefixed table names at 12 sites, for tables that do not exist · a knex-CLI migration workflow · an inverted "never raw DDL" best practice · a dead @vercel/postgres import.

H2 asked whether configure was the only fabrication. The honest answer was no, and the page barely has a true paragraph in it.

The verification standard is what makes this landable

19/19 TS fences script-extracted verbatim from the committed file — not transcribed — and compiled against the built .d.ts, ANY_FAIL=0. Negative probes with real error codes rather than assertions:

n1 TS2353 'driver' does not exist in type ObjectStackDefinitionInput
n9 TS2724 has no exported member named 'SQLDriverConfig'. Did you mean 'SqlDriverConfig'?
n10 TS2339 Property 'getDriver' does not exist on type 'ObjectKernel'
n11 TS2353 'strategy' does not exist in type { enabled: boolean; ... }
n12 TS2353 'filters' does not exist in type DriverQuery

And then past types into runtime: the driver key threw "Unrecognized key(s) on this stack definition: driver", tenancy.strategy threw with its own #2763 provenance, and both new shapes were executed and accepted with no error. Compiling proves the shape typechecks; executing proves the strict schema accepts it. On a page whose defect was precisely a shape the schema rejects, only the second one settles it.

Extracting the fences by script from the committed file closes the last gap — a transcription error would have reintroduced the class silently.

Rulings held

The note about the two README gates being added by hand, because dispatch-gates.mjs's own residue note says a gate whose population is a top-level README.md literal scores silent for every card, is the third independent sighting of that deriver blind spot this round. It is logged on #9747.

#9907 — filed correctly, and it is NOT my lane

the objectstack-platform skill still teaches that an unknown top-level defineStack key is silently stripped, which #8687 changed to a throw — three sites in rules/bootstrap-patterns.md plus a general statement at SKILL.md:189

Filing it unassigned with finding and no pm:queue, and not touching it, was right on both counts: skills/** is a governed surface, and this is a published skill teaching a load-time behaviour that inverted.

I have added domain:skills — routing only. ⛔ I am deliberately not setting pm:queue or any priority: domain:skills is a different seat and its scheduling is theirs, not mine. Flagging for that lane that a PR fixing it will be human-merge-only.


Generated by Claude Code

@os-steve
os-steve marked this pull request as ready for review August 19, 2026 07:12
@os-steve
os-steve enabled auto-merge August 19, 2026 07:12
@os-steve
os-steve added this pull request to the merge queueAug 19, 2026
Merged via the queue into main with commit 86431f7Aug 19, 2026
26 checks passed
@os-steve
os-steve deleted the claude/issue-9867-driversql-configure branch August 19, 2026 07:46
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/ltooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

packages/drivers/driver-sql/README.md documents DriverSQL.configure() three times — the class is not exported and the static does not exist

2 participants

@os-steve@claude