Repository navigation
feat(drivers): ADR-0139 E3 + E4 — the five drivers compile the composed ReadableIds leaf or refuse it with D3's envelope, with the conformance case-set - #23656
Conversation
…posed ReadableIds leaf, the shared driver refusal, and the parked case-set Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
… ReadableIds leaf Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
…ory compiles in process, mongodb refuses Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
…red helper's unit pins; changeset Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
…river's logger shape accepts it Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
…ptions erasure Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
…adable-ids-drivers
📓 Docs Drift CheckThis PR changes 7 package(s): 45 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 11 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 150 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 2489c7f91b523c0c307d969fca32921c2c7acd07 && git checkout 2489c7f91b523c0c307d969fca32921c2c7acd07
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 1ced0f82bd93260b660e6f448c7dc5952bc82371 45a871de4d1735f9c4bbaa5855f87c4c3039a023 && git checkout -B drift-repro 1ced0f82bd93260b660e6f448c7dc5952bc82371 && git merge --no-ff 45a871de4d1735f9c4bbaa5855f87c4c3039a023
node scripts/docs-audit/affected-docs.mjs --json 1ced0f82bd93260b660e6f448c7dc5952bc82371
|
…(optional-error sink contract) Claude-Session: https://claude.ai/code/session_01B1r5eJEPgvn7bUsfBvK2tS Co-authored-by: Claude <noreply@anthropic.com>
席位核对 ·
|
| Item | Reading |
|---|---|
| Shape | Draft PR → main. The first line is Fixes #23639. A closing-keyword scan of the whole body finds one hit, line 1. |
| Scope | 21 files (+1779 / −29), no content/docs/releases/ edit and no governed path, under the 3,000-line threshold. The claim's surface (6187884851) was amended for the packages/core helper, the driver-sqlite-wasm name override and turso-driver.ts. The domain:spec surfaces (the case-set, its export, the regenerated shards, the CASE_SETS row) were declared to #18883 (6187941311), with no objection on record. |
Clause-② |
yes, on the claim, the PR body and the changeset. The new exports of @objectstack/spec/data (11, matching the api-surface/data.json hunk) and of @objectstack/core widen the public surface. |
| Changeset, sentences read | Seven minor rows (spec, core and the five drivers). The title line "the five drivers compile the composed ReadableIds leaf or refuse it with one envelope …". Clause-②: yes with no arm. |
| Ledger | Driver conformance: 50 covered / 0 DEBT before, 55 covered / 0 DEBT after (the dev's reading; check:driver-conformance inside the green Lint & Repo Gates agrees). Zero ledger rows. |
| #5499 freeze | driver-memory +32/−2 and driver-mongodb +20/−0 carry only the two D3 rows. |
| Contract review | The record posted below this comment: CONTRACT_REVIEW_TIER, PASS at this head, nothing escalated. |
| Gates | Every check that has concluded on this head is green. Build Core, Test Core 1–6 and three Type Check lanes were still running at the review's read. Landing needs every check green. |
Residual, accepted. The new driver-sql suite's PG and MySQL cells run first on main's full battery (Temporal Conformance (live PG + MySQL), a path skip on the PR). A red there is this lane's main-red under the standing convention, and this seat owns it.
Disposition:
open_questions0–4 are as the contract review answers them: the core helper kept, mongodb'sconsole.erroronce per process, Turso remote resolving on the write doors, drivers atminor, and the role file over the harness defaults.out_of_scope_findings: none filed,dropped — environmentfor the two local-environment notes.- The dev's derivation note (
check:optional-error-sinkabsent fromdispatch-gates --commands) is by design: the gate's header records itREFUSE-WIDEinscripts/pm/bare-root-worklist.mjs(every non-test source underpackages/).dropped — by design.
Generated by Claude Code
Contract reviewServed-tier: Reviewed on the card (#23639, body and every comment), the PR body, its 21-file list, the net diff against ① Derived judgmentsPublic surface, Public surface,
The envelope. One helper, Logging. Conformance. Five suites import Residuals, named, none a breach. (a) The PG and MySQL cells of the new Check-runs on the head. Green: ② Semver level
③ Boundary flagsEvery dev flag answered; nothing escalated.
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
Landed ·
Status: #23639 is closed, and its Main-red watch: the next Generated by Claude Code |
Fixes #23639
Clause-②: yes
ADR-0139 plan rows E3 and E4 in one PR, as
domain:specseat 3 ruled for the case-set: "the case-set lands in the same PR as the five driver suites that run it, with zero ledger rows." D3 is the spec. #22788 is the parent card.What changes
Every driver now either compiles the composed
ReadableIdsleaf or refuses it. The engine has composed the leaf at its executor boundary since E2.driver-sqlfield IN (SELECT id FROM P_TABLE WHERE SCOPE AND TENANT)$inarm ofSqlDriver#applyFilterCondition, plus the newSqlDriver#readableIdsSubquery. The subquery is walled bySqlDriver#applyTenantScopeon the parent table, using the outer read's own options.driver-sqlite-wasm,driver-tursolocal facereadableIdsDriverName)driver-tursoremote faceTursoDriver#toRemoteWhereresolves each leaf into the parent's remote table, its scope (in storage form) and its tenant wall, built by the same chokepoint,remoteTenantScope→applyTenantScope.RemoteTransport's$inarm then compiles"field" IN (SELECT "id" FROM … WHERE (scope) AND (tenant)).driver-memoryconvertToMongoQuery, the single funnel forfind,count,aggregateanddistinct, rewrites each composed leaf into the ids of the parent's rows under the scope (readableParentIds) before the shape gate. No tenant wall is owed, because memory refuses every tenant-scoped call.driver-mongodbtranslateFilter, the funnel every door and the aggregation$matchgo through, refuses ahead of the shape gate (which would otherwise answerINVALID_FILTER)The refusal is one envelope on every driver (ADR-0112):
INTERNAL_ERROR/ 500, neverINVALID_FILTER. A driver refuses:isReadableIdsalone;$incomparand;driver-mongodb.The message names the driver, the leaf (its path and parent object) and the remedy. It is logged at
erroronce per driver. NoDriverCapabilitiesbit is added.Landing point outside the claim's file surface, and why:
@objectstack/core. The walk, the copy-on-write rewrite and the refusal live inpackages/core/src/utils/readable-ids-driver-refusal.ts. Four compilers need them: SQL, Turso remote, memory and mongodb. None of them imports another, but all of them already import@objectstack/core. This follows the precedent ofjson-column-operator-refusal.ts, shared between the drivers in the same place for the same reason. The alternative was four hand copies of one refusal.The case-set was carried from the parked
e641ab6d8withgit restore --sourceand no branch checkout. The files arepackages/spec/src/data/readable-ids-conformance.ts, its oracle test (readable-ids-conformance.test.ts, 18 tests), thedata/index.tsexport line and theCASE_SETSrow.api-surface/data.jsonandexport-origins/data.jsonwere regenerated withcheck:generated --fix, which proved those two (and only those two) stale. One edit to the carried file: its header linked a symbol that does not exist (readableIdsCaseHoldsComposedLeaf). It now linksReadableIdsMatchesCase.holdsComposedLeaf.SqlDriver#applyFiltersand#applyFilterCondition(bothprotected) take the read'sDriverOptionsas a new optional last parameter. The lazily invoked knex group callbacks capture it, so the subquery under a$oror$notis walled with the outer read's options and never reads them from instance state. Every in-file caller passes the options it already handedapplyTenantScope.Pins (red before, green after)
READABLE_IDS_CASESmatches(find + count)refuses-uncomposed→INTERNAL_ERROR/ 500countequals rows servederroronce per driverE4, the conformance table:
node scripts/check-driver-conformance.mjsrecordsREADABLE_IDSokfor all five drivers.Ablation: each implementation was mutated after its commit, using
scripts/ablation-replace.mjs(anchor hit 1 → 0, blob compared to HEAD after restore,git diff HEADempty).driver-sql, the$incomposed arm disabled: 13 failed / 4 passed.RemoteTransport, the semi-join arm disabled: 12 failed / 13 passed. The local face stays green, as it should.driver-memory, the rewrite disabled: 10 failed / 4 passed.driver-mongodb, the refusal disabled: 11 failed / 1 passed.O1: what the subquery binds
The statements below were captured from knex's
queryevent on the SQLite cell, whereorg_ais the tenant.rlsMembership, record shares) still binds its ids, now inside the subquery.The measured and documented ceilings:
too many SQL variables.Verification record (measured at the commits named below; the PR head is
52dc068bfc)Driver conformance ledger, the lane's standing reading:
23e689dc7d):OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exemptOK — 55 covered cell(s), 0 in the DEBT ledger, 0 exempt. The new suite runs the matrix (9 conformance suite(s) … 8 run the matrix).Tests, each run as
pnpm --filter PKG test:The spec files
readable-ids-conformance.test.tsandreadable-ids.test.tspass 47/47.Typecheck:
pnpm --filter PKG typecheckexits 0 for core, driver-sql, driver-sqlite-wasm, driver-turso, driver-memory and driver-mongodb. driver-mongodb's test layer needed@objectstack/objectqlbuilt first; locally itsdisthad no.d.ts.Spec:
pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated: 12 of 14 were up to date, and the 2 stale ones were regenerated.Gate families from
node scripts/pm/dispatch-gates.mjs --commands: all 111 derived families were run and reconciled with--ran(111 derived famil(ies) accounted for — 110 run, 1 NOT-MEASURED). Two results need saying:pnpm check:query-options-erasurewas red on the first pass: the new suites carriedas anyon query arguments, and the test-surface count went 236 → 242. Fixed by typing the queries in813e08cd73, then re-run green.pnpm check:dual-build-cjs-loadsis NOT MEASURED. It exits 3 withPREREQUISITE NOT METbecause it reads every package'sdist, which needs a full-repo build. CI runs it.813e08cd73. On that head I re-ran driver-conformance, query-options-erasure, test-source-alias, cross-package-test-inputs, type-check-coverage, nul-bytes and doc-authoring, all green.origin/mainwas then merged in (52dc068bfc) becausepackages/spechad moved. On the merged tree: spec rebuilt,check:generatedreports all 14 artifacts up to date, thedriver-sqlite-wasmsuite (the package main touched) passes 695/695, the five new suites are green again, the driver conformance gate holds at55 covered, 0 DEBT, and the derived gate list is unchanged.Size: 1,806 changed lines (1,777 additions + 29 deletions), generated files included.
Acceptance notes
driver-mongodbhas no injectable logger, and its refusal is raised inside the puretranslateFilter. So the once-per-drivererrorline goes toconsole.erroronce per process. The caller still sees every refusal.updateMany/deleteMany) too, matching the local face, which compiles whereverapplyFiltersruns. The engine refuses the leaf on writes before any driver is asked (D1).driver-mongodb's suite runs server-free attranslateFilter, which every door and the aggregation pipeline call before any I/O. The mongod-gated suites in that package are opt-in (test-mongod.ts).Generated by Claude Code