Uh oh!
There was an error while loading. Please reload this page.
spec: withdraw the never-honored introspection indexes promise; widen defaultValue/maxLength to the measured emitted types - #11270
Conversation
…maxLength, retire Omit workarounds Declaration edits only so far; tests, changeset, verification to follow. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RadETjNRLALFLhFA3xehZP
…lue/maxLength; changeset Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RadETjNRLALFLhFA3xehZP
📓 Docs Drift CheckThis PR changes 3 package(s): 35 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 2 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 129 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 e4c31ea0ada7649c7c863577a5867c4ab831ee02 && git checkout e4c31ea0ada7649c7c863577a5867c4ab831ee02
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 064d484bd7adc8874a609c7ec226a2f0e3bc25aa 96b4153cd3638a7965ec4a9e90215e8016014bfd && git checkout -B drift-repro 064d484bd7adc8874a609c7ec226a2f0e3bc25aa && git merge --no-ff 96b4153cd3638a7965ec4a9e90215e8016014bfd
node scripts/docs-audit/affected-docs.mjs --json 064d484bd7adc8874a609c7ec226a2f0e3bc25aa
|
云读数已到并已关卡:#11232 两项读数均贴于该卡(cloud Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#11122
Implements the maintainer ruling recorded 2026-08-23 (comment 5383569868, verbatim 「其他同意你的意见」 adopting recommendation B): withdraw the never-honored promise. Wiring the index read (option A) is explicitly NOT done here; if real consumer demand appears, that is a new card with its own
onFailureruling.What changed
packages/spec/src/contracts/schema-diff-service.ts— the two ruled keys only (kept tight for the An UNREACHABLE federated remote is reported asmissing_table— a transient outage is indistinguishable from a dropped table, and aborts boot under the default onMismatch: 'fail' #11166 serial handoff, which lands in this file after this PR):IntrospectedTable.indexesis now optional, with TSDoc fixing the semantics: absent = "the producer did not read indexes"; empty array = a positive claim the table HAS none. Producers that did not look must omit the key — never emit a false-empty array.IntrospectedColumn.defaultValuewidens from the never-honoredstringtounknown— raw as the driver reported it, with the measurements in the TSDoc.packages/drivers/driver-sql/src/sql-driver.ts+packages/objectql/src/util.ts— the deliberateOmitworkarounds and their explanatory notes are retired: both packages'IntrospectedColumn/IntrospectedTable/IntrospectedSchemanow extend the spec contract directly (same PR, per the ruling). The SQL layer still adds only extra facts (isUnique,maxLength,foreignKeys,primaryKeys), never a second spelling of a spec key.maxLength(the noted same-class case) widens fromnumbertonumber | stringat all three SQL-layer sites: driver-sqlIntrospectedColumn,PhysicalColumninschema-drift.ts(fed directly from the same read; its varchar differ already narrows via typeof before comparing), and objectqlIntrospectedColumn.Premise check (re-verified on today's origin/main, base e5ea701)
Both premises held: the spec still declared
indexesrequired anddefaultValueas optional string; theOmitworkarounds still stood at driver-sql sql-driver.ts (formerly lines 3687/3711/3725) and objectql util.ts (formerly lines 34/66/83).Re-measurement (SQLite in-memory, knex
columnInfo()pass-through — the driver's exact source, 2026-08-23)t.string('id').primary()null"255"t.string('name').defaultTo('abc')'abc'(quoted)"255"t.integer('n').defaultTo(5)'5'nullt.boolean('b').defaultTo(true)'1'nullHonest limit, as the card states: SQLite only — no PG/MySQL server is reachable from this container. Both keys are built at a single dialect-independent site (
introspectSchema/introspectColumns), so the SHAPE cannot vary by dialect; per-dialect CONTENT is not claimed.unknown(not a closed union) is deliberate fordefaultValue: a closed union would claim completeness across dialects nobody measured;unknownalso forces consumers to narrow, which is the authoring-safety direction the four-axis analysis picked.Consumer readings (recorded per the ruling; a found consumer would have forked back to the card)
(a) objectstack repo-wide — CLEAN. Every typed consumer of the spec introspection types was enumerated (imports of the types across all packages): service-datasource (
external-datasource-service.tsreads columns andprimaryKeys; nevertable.indexes, never a string operation ondefaultValue— itsPhysicalColumn.defaultValuewas alreadyunknownand comparisons go throughphysicalDefaultIsToken), objectqlconvertIntrospectedSchemaToObjects(readscolumns/foreignKeys; copiesdefaultValueopaquely behind a null-guard), and test fixtures.IntrospectedIndexhas zero consumers outside the spec itself. The wire never carries the shape either: the REST family servesRemoteTable(name + columnCount only), so no UI can readindexesstructurally. Fixtures in service-datasource/rest/runtime tests that carryindexes: []remain legal under the optional key (an empty array is still a valid positive claim) and were deliberately left untouched — outside this card's file surface, and service-datasource is H17-adjacent (neither H17 hold-trigger file is in this diff).(b) objectui — CLEAN, positive-controlled. Read at fetched origin/main
3ddc8c261aa31ee85ce307330fb2ff4d246b15db:git grep -nE "Introspected(Schema|Table|Column|Index)|introspectSchema|introspectIndexes"over all .ts/.tsx → NO MATCHES. Positive controls on the same SHA:defaultValue(matches — e.g. apps/console/dev/tests/setup/common-mocks.ts) and@objectstack/spec(matches — e.g. apps/console/src/tests/component-input-union-specimens.test.ts) both hit, so the empty result is a measurement, not a broken grep.(c) cloud — NOT this PR's reading to take. Requested as seam card #11232 (which gates enqueue only). This PR parks as draft until #11232's reading (a) posts clean.#11232 remains open and is not addressed here.
Tests
packages/spec/src/contracts/schema-diff-service.test.ts: compile-time pins (a table WITHOUTindexestypechecks;indexes: []and populated stay distinct legal claims;defaultValue: null/ quoted-string /trueaccepted; a string operation ondefaultValuewithout narrowing does not typecheck — spelled as the narrowing guard).sql-driver-introspection-spec-contract.test.tsgains three pins on live introspection bytes:'indexes' in table === false(absence, never a false-empty[]), the emitted schema assigned to the spec type (the compile-time seam pin), and the measured raw emissions (defaultValue === nullfor a no-default column; varcharmaxLengthwithin the declarednumber | stringunion,Number(...) === 255).Verification (all at HEAD 96b4153, the final commit — quoted from the runs themselves)
check:generated: "All 14 generated artifacts are up to date." (No api-surface/docs churn — the surface records existence, and no export was added or removed.)node scripts/pm/dispatch-gates.mjs(no paths passed; stderr line: "gate list derived from the tree of 'objectstack-ai/objectstack' at commit 96b4153"; change set = exactly the 7 files of this PR). All 24 path-matched + 5 convention-triggered families run locally, every one exit 0 with its own OK line — includingcheck:type-check-debt("33 ledger entries re-measured … none above its recorded number", after the full turbo package build it requires),check:type-check-coverage,check:cross-package-test-inputs,check:engine-double-contract,check:adr-0087-registration(patch changeset — not declared-breaking, no marker owed), andcheck:nul-bytes. Two initial refusals were environment artifacts, each fixed by its own printed remedy and re-run green:check:dev-prereqs(fresh worktree, unbuilt sibling dists → full turbo build) andcheck-engine-split-ratio(shallow clone → deepened to 2026-05-18).Reverse verification (mutation proven on disk, both legs rebuilt)
Mutation = restore the OLD declarations (required
indexes, stringdefaultValue) from base e5ea701; proven on disk by grep (old lines present 1/1, new line absent 0) and in the rebuilt spec dist (old required-indexes line present in dist contracts d.ts). Predicted directions stated before running:check:test-typecheck→ predicted RED, observed RED (exit 1: 5 type errors in the new pin file — exactly the literals the old declaration refuses).tsc→ predicted RED, observed RED (exit 2:TS2741: Property 'indexes' is missing … but required in type 'IntrospectedTable'at theintrospectSchemaconstruction site — the Omit-retirement failing to compile, as required).tsc→ predicted RED, observed GREEN — prediction wrong, and the reason is worth recording: objectql's tsconfig excludes all test files from tsc and the package has no test-typecheck program, so thedefaultValue: truefixture inutil.test.tsis compiled by no tsc program (vitest strips types) — a genuinely uncoupled compile surface, not a broken discriminator. objectql src itself only CONSUMES introspection values (no construction site), so its green under mutation is correct. This hidden test layer is a known, ledgered state —@objectstack/objectqlcarries a measured TEST_DEBT entry (354 frozen raw errors) incheck:type-check-coverage, tracked under the standing coverage program ([P2] framework: 66 个包用 tsup 构建、无人做类型检查 —— 实测 18 个包共 380 处 code-tier 错误(#4118 的 framework 侧对应) #4311 / [finding][devx]check:type-check-debt的 ledger 余量会让新写的 pin 变哑:mongodb 曾有 33 条余量吞掉一次真实回退,另有 5 条目前带 4–19 余量 #6376) — so no new issue is filed; recording the fact here instead. The compile-time pins for this card therefore live in spec and driver-sql, both proven able to fail.check:test-typecheckonly (the program carrying the pins; spec src compiles under either declaration), objectql ran main tsc only (its scripts program does not touch introspection). The green-tree runs above were full.Notes for review
needs:contract-reviewis expected on this PR; the PM reviews it.missing_table— a transient outage is indistinguishable from a dropped table, and aborts boot under the default onMismatch: 'fail' #11166 lands in the same contracts file after this PR; the edit here is confined to the two ruled keys plus their TSDoc. An UNREACHABLE federated remote is reported asmissing_table— a transient outage is indistinguishable from a dropped table, and aborts boot under the default onMismatch: 'fail' #11166 is not addressed here.Generated by Claude Code
Generated by Claude Code