docs(drivers): scope the reference_to refusal docblocks to the authoring face - #14489
Conversation
…oring face The SQL DDL door (#11567) and the Mongo schema-sync door (#13222) each assert that `reference_to` "is a REJECTED ALIAS, not a normalised one". After the `field-reference-to-alias` conversion landed, that is true on the AUTHORING face only: stored `sys_metadata` rehydration and `os migrate meta` now NORMALISE the key. Left as written, the next reader infers "a stored `reference_to` stays verbatim forever" from a driver comment, which is false. Both docblocks now scope the original assertion to the authoring face and quote the split the conversion's own registry docblock already states, rather than inventing a parallel formulation. Two prose measurements in driver-mongodb that a later spec tightening left behind are refreshed in the same stroke: `{ type: 'lookup' }` with no `reference` and `{ type: 'lookup', reference: '' }` no longer "parse successfully" — the superRefine added on the relationship types refuses both with `custom` on the `reference` path. The shape still reaches the join-index arm, because `syncSchema(object, schema: unknown)` casts and forwards verbatim with no Zod, so no assertion changes. Comments only: no behaviour, no assertion, no public type. Card #13851. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
📓 Docs Drift Check1 anchor(s) derived from 2 changed package(s); no hand-written page names any of them. What this run could not see
Coarse fallback — 9 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 28b21226bd3ad460f9b8df21c59db6b0fa0160c5 && git checkout 28b21226bd3ad460f9b8df21c59db6b0fa0160c5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e5812fa435d27bd103afeec442bf7d420a28f8d6 f2884adc328fd9544127feb3f8403a527d0187b1 && git checkout -B drift-repro e5812fa435d27bd103afeec442bf7d420a28f8d6 && git merge --no-ff f2884adc328fd9544127feb3f8403a527d0187b1
node scripts/docs-audit/affected-docs.mjs --json e5812fa435d27bd103afeec442bf7d420a28f8d6 |
|
Landing provenance (engine execution seat,
Generated by Claude Code |
Fixes #13851
Comment-only. Two driver docblocks asserted that
reference_to"is a REJECTEDALIAS, not a normalised one". Since the
field-reference-to-aliasconversionlanded, that holds on the AUTHORING face only — stored
sys_metadatarehydration and
os migrate metanow NORMALISE the key — so a reader was onestep from inferring "a stored
reference_tostays verbatim forever" from adriver comment. Both docblocks now scope the original assertion and quote the
split the conversion's own registry docblock already states. No behaviour, no
assertion, no public type, no gate scaffolding moved.
Wording source — quoted, not re-invented
packages/spec/src/conversions/registry.ts,fieldReferenceToAlias(
id: 'field-reference-to-alias',toMajor: 18,retiredFromLoadPath: true,surface: 'field.reference_to'— all four read from the entry, confirming theretiredFromLoadPathshape the card describes). Its docblock:rehydration and
os migrate meta";to a driver, around both the gate and the stored pass); they are downstream
of this entry, not replaced by it."
Both edited docblocks quote those two clauses verbatim rather than paraphrasing
a parallel formulation.
Measured on this tree, before writing a word of it
FieldSchemafrompackages/specbuilt from this tree (packages/spec/dist/data/index.mjs):{ name:'parent', type:'lookup', reference_to:'p' }success:false, one issue,code = unrecognized_keys{ name:'company_id', type:'lookup', reference_to:'company' }{ name:'company_id', type:'text', reference_to:'company' }reference_tovalued'company'/null/''{ type:'lookup', reference:'company', reference_to:'company' }{ name:'company_id', type:'lookup' }(noreference)success:false,code = custom, path["reference"]{ name:'company_id', type:'lookup', reference:'' }success:false,code = custom, path["reference"]{ name:'parent_id', type:'master_detail' }(noreference)success:false,code = custom, path["reference"]{ name:'company_id', type:'lookup', reference:'company' }success:truereference_tois NOT an own keyTwo readings matter:
unrecognized_keysverdict is unchanged. The#13927superRefinedoes not add a second issue to the
reference_tofixtures — every rejectedalias case still answers with exactly one
unrecognized_keysissue. So thecode blocks inside both docblocks, the "any type, any value" claim, and the
complete-case-split argument next to the join-index arm are all still exact.
Only the "not a normalised one" half needed a face named on it.
{ type:'lookup' }with noreferenceand{ type:'lookup', reference:'' }are now REFUSED, where twodriver comments record them as parsing successfully. That is the second
instance folded into this card.
PR #13927 landed as commit
0fb8760be(subject: "require a non-emptyreference on lookup/master_detail fields"), an ancestor of
origin/main; the refinement is the[#13632]superRefine block added topackages/spec/src/data/field.zod.ts(around the former line 1691), which is what produces the
customissue on thereferencepath above.Per-mention ledger — every
reference_tomention on the declared surfacepackages/drivers/driver-sql/src/sql-driver.ts(the#11567docblock, now around:1488)packages/drivers/driver-mongodb/src/mongodb-schema.ts(the#13222docblock, now around:113)syncSchema(object, schema: unknown)casts and forwards verbatim, with no Zod and no stored pass).mongodb-schema.ts:40—FieldDef.reference_todocblockreference" and "FieldSchemaanswersunrecognized_keysfor this key", plus a measurement that'company'/null/''draw one identical verdict. All three are authoring-face statements and all three re-measured true above. It makes no claim about data at rest, so the two-face split falsifies nothing in it.mongodb-schema.ts:261— the join-index arm commentreference_towas refused at the door, so the old conjunct was unreachable. Re-measured true (every non-undefinedvalue refused;undefinedis falsy). The conversion runs on the stored and migrate paths, which never reach this arm, so it falsifies nothing here.mongodb-13222-reference-to-refusal.test.tsheader (:6)FieldSchemaanswersunrecognized_keysfor it on any field type, carrying any value" — measured true, and a statement aboutFieldSchemais by construction about the authoring face only.sql-driver-11567-lookup-no-foreign-key.test.ts.changeset/mongodb-lookup-index-canonical-reference.md:8Bounded in-place fix, declared
Two edits go past the card's literal two-docblock naming, both inside files
already on the claim's declared file surface, both the same defect class the
card is about (driver prose left behind by a spec tightening), both with the
correct shape pinned by the measurement above:
mongodb-schema.ts, theFieldDef.referencedocblock (around:66) —carried the exact same stale sentence as the second instance:
{ type: 'lookup' }with noreferenceand{ type:'lookup', reference:'' }"bothparse SUCCESSFULLY … a shape an author can really publish". Now records the
refusal, names
#13927, and keeps the truthiness conclusion on the reasonthat survives: the shape still reaches this arm because metadata gets here
without meeting Zod at all.
mongodb-13222-reference-to-refusal.test.ts, the last case's comment — thesecond instance named on the card, same refresh. No assertion changed:
the test drives
syncCollectionSchemadirectly, which is the seam thatbypasses Zod, so the targetless-lookup case is still reachable and the
expected index set is still exactly what the arm produces. It passes
unchanged.
Neither edit touches code. Nothing else in
sql-driver.tswas read or writtenbeyond the one docblock (the in-flight
#13564measurement reads that file).Changeset — decided by measurement, not by assumption
Both packages publish (
privateabsent;files: ["dist", "README.md", "CHANGELOG.md"]). Built both after the edit(
pnpm --filter @objectstack/driver-sql --filter @objectstack/driver-mongodb build,after the dependency closure) and grepped the emitted artifacts for a phrase
unique to the new text, "authoring face and only the authoring face":
packages/drivers/driver-sql/dist/index.d.ts— absentpackages/drivers/driver-sql/dist/index.d.mts— absentpackages/drivers/driver-mongodb/dist/index.d.ts— absentpackages/drivers/driver-mongodb/dist/index.d.mts— absentdist/index.js.map/dist/index.mjs.mapof both, viasourcesContent(stated for completeness:distships, so the sourcemapcopy does travel — but it is not a type, not an API and not observable
behaviour)
refuseRejectedReferenceAliasis module-private in both packages andFieldDefis a non-exported interface, which is why nothing reaches the declaration files.
Neither docblock reaches
dist/*.d.ts, so per the dispatched criterion this PRtakes the
skip-changesetlabel rather than apatchchangeset. Deferring toCheck Changeset/check-empty-changeseton CI if they read it differently.Verification — union run AFTER the final commit, at
f2884adc3Gate family re-derived on the real change set:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands(stderr confirms it answered for
objectstack-ai/objectstackat9e286e248,this checkout) — 3 paths, 28 commands. The dispatch's 36 included the 8
changeset-path families, which the script itself reports as "apply once this
card's changeset exists"; with
skip-changesetthere is no changeset path.prerequisite failures needing a full monorepo build, none is a finding:
node scripts/check-test-completeness.mjs— "Nothing was measured … ⛔ It isNOT a finding" (wants a saved
turbo run testlog).pnpm check:dual-build-cjs-loads— "PREREQUISITE NOT MET — this gate readsbuilt output, and some package has no dist/ … ⛔ This is NOT a pass".
pnpm check:type-check-debt— "39 workspace dependenc(ies) … have no builttype entry point on disk … ⛔ This is NOT a pass and NOT a finding".
pnpm lint(full repo,eslint . --no-inline-config,exit 0, no narrowing claimed),
pnpm check:nul-bytes("OK (scanned 7913 text file(s) … no raw ASCII control bytes)"),
pnpm check:error-status-conformance("✓ every derivable runtime status isdocumented, and every documented status is reachable").
pnpm --filter @objectstack/driver-sql typecheckandpnpm --filter @objectstack/driver-mongodb typecheck— both exit 0.driver-mongodb's tsconfig excludes**/*.test.ts, so that typecheck says nothing aboutmongodb-13222-reference-to-refusal.test.ts. The vitest run below is whatcovers it.
pnpm --filter @objectstack/driver-mongodb exec vitest run --maxWorkers=2 src/mongodb-13222-reference-to-refusal.test.ts src/mongodb-schema-declared-indexes.test.ts— "Test Files 2 passed (2) ·Tests 16 passed (16)", assertions untouched.
check-driver-conformance: OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt.check-driver-conformance: OK — 50 covered cell(s), 0 in the DEBT ledger, 0 exempt.No ablation is owed: the change is comments only.
Clause-② self-reading: no. Comments only — no accept/reject behaviour, no
public type, no gate moves. The diff is three files, +50/-15, every line inside
a comment or docblock.
🤖 Generated with Claude Code
https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68
Generated by Claude Code