Repository navigation
fix(spec,objectql): correct six false edit distance cannot reach citations - #19126
Conversation
…tations `aliases` has two jobs, not one: filling a gap the distance fallback leaves empty, and overruling a hit the fallback reaches and gets wrong. The lookup is `aliases[aliasProbe(key)] ?? findClosestMatches(key, knownKeys, budget, 1)[0]`, with the budget `Math.max(2, Math.floor(key.length / 3))`. Six citations denied the second job, and three of them cited an example OF it as proof. Measured against the real `findClosestMatches` and the shapes' own key lists: latitude budget 2 lat 5 edits (out of reach) altitude 2 edits -> OVERRULE longitude budget 3 lng 6 edits, nothing closer -> GAP postal_code budget 3 postalCode 1 edit -> pure fallback hit uri budget 2 url 1 edit -> reachable, agrees Prose plus new pins; no alias, schema, key list, strictness, suggestion or error message moves. Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude <noreply@anthropic.com>
…it-distance-citations
📓 Docs Drift CheckThis PR changes 2 package(s): 3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 137 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 f15528887fc976d3084b13a0f0095137b6afa9f9 && git checkout f15528887fc976d3084b13a0f0095137b6afa9f9
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin b7eaf6a617b7353825935631f73b5bdcf7b78f90 f61417bb2d4c410cd035f34c75b237d7cc5c678f && git checkout -B drift-repro b7eaf6a617b7353825935631f73b5bdcf7b78f90 && git merge --no-ff f61417bb2d4c410cd035f34c75b237d7cc5c678f
node scripts/docs-audit/affected-docs.mjs --json b7eaf6a617b7353825935631f73b5bdcf7b78f90
|
Fixes #17664
Clause-②: no
aliaseshas two jobs, not one: filling a gap the distance fallback leaves empty, and overruling a hit the fallback reaches and gets wrong. The lookup isaliases[aliasProbe(key)] ?? findClosestMatches(key, knownKeys, budget, 1)[0]— the table is consulted first and wins outright — and the budget isMath.max(2, Math.floor(key.length / 3)). A sentence saying distance "cannot reach" the cited case denies the second job. In three of the six places corrected here, the cited case is itself an example of it.The three sites the card names — three separate verdicts
Measured against the real
findClosestMatchesand each shape's own key list (read off.shape, never transcribed), atorigin/main1124c4564.1.
packages/objectql/src/validation/record-validator.ts— FALSE, high confidenceCited: "The rename IS the prescription, and edit distance cannot reach it (
latitude->lat)".latitudeis 8 characters, so the budget is 2.latis 5 edits away and out of reach — but the fallback is not silent: the declaredaltitudeis exactly 2 edits away, inside the budget. The refusal an author would see without the alias, printed by the ablation below:So the entry is overruling a confident wrong answer, and the sentence cites it as proof that no such category exists. Confidence: high — the ablation reproduces the wrong answer verbatim from the running schema.
2.
packages/spec/src/data/default-value-shape.ts— FALSE, high confidence, plus a second errorSame sentence, same measurement, so the same verdict. This site carries an additional error the card does not name: the docblock's own worked example is
postal_code -> postalCodeonAddressValueSchema, and it attributes that output to the curatedaliasesmap.postal_codeis not an alias key on that shape at all — scoring folds case and separators on both sides, so it is 1 edit against a budget of 3 and the example is the plain fallback's own answer. The corrected text names both channels and says which produced which. Confidence: high (both halves re-measured).3.
packages/spec/src/data/driver/turso.zod.ts— FALSE, high confidence, and in a different position from the other twoTwo things set this one apart, and they are the same distinction read twice.
Position. Sites 1 and 2 cite a single example inline, as proof of a rule. This one is a blanket header standing above a table: "Semantic near-misses only — the spellings edit distance cannot reach." The word doing the damage is only, and it is quantified over six rows.
Bucket. Sites 1 and 2 are in the overrule bucket (reachable, fallback answers a different key).
uriis in the agrees bucket: 3 characters, budget 2, anduri/urldiffer by 1, so the bare fallback already answersurl— identically. Five of the six rows (connectionstring,dsn,database,databaseurl,syncinterval) are genuine gaps;uriis not, and the row's real value is that it keeps answeringurlif this shape ever gains a key within 2 ofuri. Confidence: high for theurirow; the other five rows are re-measured and the header's claim holds for them.Three more carriers of the same claim, fixed in place
The
latitude -> latsentence has five carriers, not two. Three more were corrected here under the bounded in-place-fix exemption, and all four of its conditions are named and shown:packages/spec/src/data/field-value.zod.ts(the table's own comment),packages/spec/src/data/field-value.test.ts,packages/spec/src/data/default-value-shape.test.ts.aliases, not only the gap it fills #17662 landed inpackages/spec/src/kernel/manifest.zod.ts: name the budget formula and where it lives, give the exact distances, say which of the two roles the entry plays, and name the pin test. Prose only.cloud ADR-NNNN, not bare numbers that resolve to this repo's own records #19119 holding 10 files, matching the dispatch's own reading. Dark control: a fabricated path matches 0 rows. All five carrier paths read FREE.packages/spec/src/data/**, already inside this card's declared file surface, and adds no gate. The two newdescribeblocks live in test files the card's own sites already depend on.Leaving them would have made the repository contradict itself inside one alias table's documentation. The boundary held elsewhere: the same claim shape about a different table is reported below, not fixed.
Pins
aliasesentries are now asserted by role, because the two roles fail differently:packages/spec/src/data/field-value.test.ts—longitude(GAP: nothing within budget),latitude(OVERRULE, with the negative half asserted: the reachable wrong answer must not appear), andaltitudas the control that a plain typo still rides the fallback.packages/spec/src/data/driver/turso.test.ts—dsn(GAP) besideuri(reachable, agreeing).Population re-derivation, its radius, and one target outside it
The card reports the phrase pattern occurring 19 times across 17 tracked files and roughly a dozen unclassified. Re-derived at
origin/main1124c4564, printing every hit, never a count://stripped per lineThe card's instrument has a demonstrable blind spot, and it hides carriers of this very defect. The card's prescription names the JSDoc-star wrap and stops there. A line-comment wrap is invisible to it: when
//falls between "edit" and "distance", or between "distance" and "cannot", the flattened text readsedit // distance cannot reachand no pattern anchored on the adjacent phrase can see it. Three hits in two files surface only under the comment-aware flatten, and two of them are further carriers of the falselatitude -> latclaim — includingfield-value.zod.ts, the file that owns the alias.Radius. This instrument sees: tracked files at one commit of
objectstack-ai/objectstack, matching the literal words "edit distance" plus a negated modal plus "reach". It does not see: other repositories, untracked files, published npm tarballs, GitHub issue and PR bodies, or any paraphrase that does not spell "edit distance".One named target outside it:
packages/spec/src/automation/builtin-node-config.zod.tssays "object->objectNameis four edits against a threshold of two, so the suggester would say nothing at all for the single most common wrong spelling on this surface". That is exactly the same claim about exactly the same mechanism, and both patterns score that file 0. Lit control on the same file: the paraphrase itself matches twice. (Re-measured:object -> objectNamereally is a GAP on every CRUD node config, so it is true — but the radius, not the truth, is the point.) The sibling repoobjectuiwas also swept and carries no member of this pattern.Acceptance notes — noted, not filed
Four members of the population are FALSE and left alone, with the reason each is out of scope:
packages/spec/src/ui/action.zod.ts— "Edit distance cannot reach these (visibleWhen->visibleis 4 apart)" heads a ~50-row table containing 6 overruling rows (path -> targetwith the fallback reachingpatchat 1; alsoargs,success,style,op,acl) and 5 agreeing ones. The cited example is itself a genuine GAP, so this is a false blanket, not a false example. Different table, different lane (packages/spec/src/ui/**, outside this card's file surface).packages/spec/src/data/object-strictness-batch20.test.ts— thedescribetitle "aliases — semantic near-misses edit distance cannot reach" blankets three cases, andexport -> exportCsvis an overrule (the fallback reachesimportat 2). Inside the file surface, but a different alias table: fixing it would widen the diff past the coherence boundary above.packages/spec/CHANGELOG.md— "Three spelled-out near-misses that edit distance cannot reach are curated as aliases:filesystemandpathspoint atfs, andhostspoints atnetwork".hostsis an overrule (the fallback reacheshooksat 2) — the very row PR docs(spec): state both roles ofaliases, not only the gap it fills #17662 corrected in the source. RELEASE-OWNED: AGENTS.md prescribes amending a released entry in a dedicated docs-only PR, never as a rider on code changes.packages/objectql/CHANGELOG.md— carries thelatitude -> latclaim. RELEASE-OWNED, same remedy.One more, true but worth knowing:
packages/spec/src/data/field-value.zod.ts's second citation (zipCode -> postalCode, a genuine GAP) sits above a table whosepostcode -> postalCoderow is in the agrees bucket. The sentence is scoped tozipCodeand is therefore true; it is noted because it is one edit away from being the same blanket error as the turso header.Also noted: the whole class would be closed by a guard rather than by sweeps — an assertion that no comment attached to a
strictObjectoptions literal claims unreachability for a row that measures reachable.shared/alias-integrity.test.tsalready forces every table and already computes what is needed. That is a new gate and a decision, not a rider on this PR.Evidence
latitude: 'lat'fromLocationValueSchema's table throughscripts/ablation-replace.mjs— anchor hit 1 -> 0, blobac90b42d814a->2610f8d9477b— turns the new pin red and prints the runtime refusal quoted in site 1 above. Restored: blob back toac90b42d814a, equal to HEAD,git diff HEADempty.packages/spec494 files / 14526 tests pass;packages/objectql299 files / 5003 tests pass. All five new pins confirmed to have run by name.pnpm --filter @objectstack/spec --filter @objectstack/objectql typecheckexit 0.scripts/pm/dispatch-gates.mjsfor this change set are accounted for — 83 exit 0, 2 NOT MEASURED (check:dual-build-cjs-loads,check:type-check-debt), both of which printedPREREQUISITE NOT MET — nothing was measuredbecause they need a full-repo build. Those are CI's run; neither can be moved by a comment-and-test diff.pnpm lintexit 0 atf61417bb2d, 6878 files linted, 0 errors, 0 warnings, and all 7 edited source files verified present in the linted population.What on the card turned out otherwise
origin/mainbefore anything was written.//wrap), and two of the hits it misses are carriers of the defect it is about.visibleWhenstill classifies GAP in 4 tables; a fabricated alias token matches 0 rows.Generated by Claude Code