Repository navigation
finding(tooling): rule 2's citation window still reads prose words as cited symbols when the claim sentence never terminates #4610
Description
Observation-class finding, measured while implementing #4607 (PR #4609). Nothing is broken today and nothing is changed for it there beyond a pinned test — filing so the next seat to touch findClaim finds it measured rather than discovers it.
Background
findClaim in scripts/check-spec-symbol-derivation.mjs extracts the symbols a spec-alignment claim CITES by taking the capitalised identifiers in a 48-character window after each @objectstack/spec mention.
Until #4607 that list only decorated the failure message of a declaration that had already failed the tie test, so noise in it was free. #4607 made it load-bearing: a claim whose cited symbols are ALL absent from the installed spec is now flagged regardless of an incidental tie. Noise in the citation list is therefore a potential false-positive source.
PR #4609 contained the reachable half — the window used to run past the end of the claim's sentence and scrape the capitalised opening words of the NEXT one, so ActionDef (packages/core/src/actions/ActionRunner.ts) reported Open as a cited symbol from "…mirroring @objectstack/spec's ActionSchema. Open key set on a data bag is correct". Symbols are now taken from the mention's own sentence.
What is left
The sentence test is "a ., ;, ! or ? followed by whitespace or end-of-string" — the same shape the claim/mention pairing already uses. A comment whose claim line simply does not end in punctuation is one sentence as far as normalizeDoc is concerned, because the line break collapses to a space.
Live instance, PageNodeSchema (packages/types/src/layout.ts:533):
* Aligned with @objectstack/spec PageSchema
*
* This is the SDUI NODE, not the authored page DOCUMENT — the spec's `Page`
measured citation list:
mixed PageNodeSchema packages/types/src/layout.ts:533 cites: [PageSchema, This, SDUI, NODE] dangling: [This, SDUI, NODE]
This, SDUI and NODE are prose.
Why it costs nothing today
PageSchema IS exported by the pinned spec, so the citation list is not all-dangling and the declaration is governed by the tie test exactly as before — the verdict is right and only the (unrendered) message would be odd.
The measured repo-wide population of the shape that would actually misfire — a claim citing NO real symbol, with an incidental live tie — is zero (PR #4609's census: 3 declarations carry a claim and pass the tie test; 2 cite only live symbols, 1 is mixed, 0 are all-dangling). So this is a latent precision gap, not a defect anyone hits.
Why it is not obviously worth closing
Tightening further means deciding what a citation LOOKS like, and the two candidate rules both have costs that were not paid down here:
- Require the symbol to be code-quoted (backticked). Real citations are frequently unquoted — the finding(tooling): rule 2's tie test is symbol-agnostic, so a declaration can cite a retired spec symbol and pass because it references a different, live one #4607 specimen itself read "Aligned with @objectstack/spec FeedItemSchema" — so this trades a rare false positive for a common false negative, which is the wrong direction for a guard whose whole design note says false-positive honesty matters more than catch rate.
- Require the capitalised word to look like a spec symbol (a
Schema/Config/Typesuffix, or membership in the spec's export set). Membership is circular: a symbol is "cited" only if the spec exports it, which is exactly the question being asked, and it would make every genuinely-retired citation invisible — the finding(types,i18n): eight doc comments claim alignment with @objectstack/spec symbols the spec does not export #4597 class this guard exists to catch.
A third option is to leave it and fix the two or three comments instead — PageNodeSchema only needs a full stop after PageSchema. That is a one-character edit in a package #4580-round2 currently owns, which is why PR #4609 did not make it.
Deliberately not established here
- Priority. No user hits this, no metadata is refused, and no verdict in the tree changes. It is a precision gap in a guard's message-and-input path, which is why this is an observation rather than a defect.
- Whether the message noise alone justifies action. The list is only rendered for a declaration that is already failing, where a reader has the file open anyway.
Pinned as a KNOWN LIMITATION test in scripts/__tests__/check-spec-symbol-derivation.test.ts (PR #4609) so the behaviour is asserted rather than assumed, and so a future fix shows up as a deliberate change to that assertion.
Refs #4607, #4592, #4597, PR #4609.
Generated by Claude Code
Activity
os-support-ai commentedon Aug 18, 2026
First-touch grading (triage seat): closing not planned (maintainer can veto by reopening). The card's own analysis is the rationale: the misfire population is measured zero, the behaviour is pinned as a KNOWN LIMITATION test, and both tightening directions trade a rare false positive for costs the guard's design notes reject. The one-character
PageNodeSchemafull-stop edit can ride any future prose PR inpackages/typesat zero marginal cost. Reopen if the all-dangling-with-live-tie population ever becomes nonzero.Generated by Claude Code