Skip to content

fix(lint): named listViews/formViews entries keyed by the runtime identity, single spelling (#6422) - #6800

Draft
os-project-manager wants to merge 1 commit into
mainfrom
claude/issue-6422-view-record-map-key-only
Draft

fix(lint): named listViews/formViews entries keyed by the runtime identity, single spelling (#6422)#6800
os-project-manager wants to merge 1 commit into
mainfrom
claude/issue-6422-view-record-map-key-only

Conversation

@os-project-manager

@os-project-manager os-project-manager commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Fixes #6422

What

validateTranslationReferences's collectViewRecord() accepted two spellings for every named listViews.<key> / formViews.<key> entry — the map key and the entry's inner name — while the composer (expandViewContainerWithDiagnostics in packages/spec/src/ui/view.zod.ts) constructs each named entry's runtime identity from the map key alone and ignores v.name entirely.

Per the #5164 ruling (2026-08-06: canonical = the runtime identity's bare key), restated for this card in the PM claim on #6422, the named branches now read their _views keys from the composer, exactly as the default list already does via defaultListViewKey (#6038):

  • an inner name diverging from its map key stops being a legal bundle key — the runtime never resolves it;
  • a collision-renamed entry becomes legal under its renamed key. This is the issue's sharpest shape: { list: {...}, formViews: { default: {...} } } registers crm_lead.default (the list) and crm_lead.default_2 (the form). The rule previously accepted default for the form (a key that resolves the OTHER view) and reported default_2 — the one spelling that actually resolves the form — as an orphan.

New helper namedViewKeys() is defaultListViewKey's sibling: a thin reader of the composer, never a re-derivation. Positional alignment rests on two documented facts of the composer (named entries expand first per family, one item per object-typed map value, in authoring order).

The assembler is untouched (teaching it to honour inner name is the direction #5164 rejected). validate-null-guards.ts is untouched (claimed in parallel under #6458).

Stop conditions, re-measured

  1. In-repo blast radius: zero, re-measured rather than inherited. Full os lint --json over all 12 ratchet-covered configs (the exact set in scripts/i18n-coverage-baseline.json), before vs after, diffed on (rule, path, message) triples: added: 0 / removed: 0 on every config — verdicts are byte-identical. No baseline entry was added anywhere.
  2. Downstream corpora. objectui at its 2026-08-08 HEAD: 36 files contain listViews/formViews; a brace-walking scan found zero entries whose inner name diverges from its map key, and objectui authors no stack.translations bundles of its own. The HotCRM corpus itself (source of the "authors write either" comment) is not in this repo or in objectui, and I could not reach it — its blast radius is unmeasured, not zero. If a HotCRM-family corpus is linted downstream, bundles keyed by a diverging inner name will newly warn (warning severity — the rule's findings are never errors).

Tests

Four new pins in validate-translation-references.test.ts, each "legal" assertion paired with a planted bad key on the same fixture so a green run is never an empty run:

  • inner name diverging from map key → flagged (listViews branch, formViews branch);
  • the collision-rename sharp case: default and default_2 both legal (each resolves a real registry entry), planted default_3 flagged. Dormant in shipped configs only because lint-view-refs.ts makes collisions a hard error — dormancy that depends on another rule staying strict is pinned, not trusted;
  • inner name matching its map key stays legal (the ubiquitous authored shape — the narrowing removes a spelling, not a view).

Reverse verification (direction predicted first)

  • Ablation A — restore the inner-name limb (addView(binding, strName(sub.name))). Predicted: exactly the two diverging-inner-name tests go red, collision + matching-name pins stay green. Measured: 2 failed | 38 passed, both failures the named tests.
  • Ablation B — feed the raw map key instead of the composer's key. Predicted: exactly the collision-rename pin goes red. Measured: 1 failed | 39 passed, the failure being that named test.

Verification

  • pnpm --filter @objectstack/lint test: 65 files, 1656 passed (1652 baseline + 4 new)
  • pnpm --filter @objectstack/lint typecheck: clean
  • pnpm exec eslint --no-inline-config packages/lint: exit 0
  • node scripts/check-nul-bytes.mjs: OK
  • changeset: .changeset/view-record-map-key-only.md (@objectstack/lint patch — published lint verdicts change)

Note: the Docs Drift Check advisory on this PR fired on package paths, not semantics — none of the three listed docs documents the named-view-key spelling surface, so it is not actionable here (and content/docs/releases/** is never edited in a code PR; the changeset is the release-notes input).

🤖 Generated with Claude Code

https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn

…ntity, single spelling (#6422)

collectViewRecord accepted two spellings for a named view entry — the map
key and the entry's inner name — while the composer constructs the runtime
identity from the map key alone. Per the #5164 ruling (canonical = the
runtime identity's bare key), the named branches now read their keys from
the composer via namedViewKeys, defaultListViewKey's sibling: a diverging
inner name stops being legal, and a collision-renamed entry becomes legal
under the renamed key — the one spelling the runtime resolves.

Measured over the 12 ratchet-covered configs: os lint verdicts are
byte-identical before/after (added: 0 / removed: 0).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 8, 2026 6:04pm

Request Review

@github-actions github-actions Bot added the size/m label Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/lint.

3 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/automation/hook-bodies.mdx (via @objectstack/lint)
  • content/docs/permissions/authorization.mdx (via @objectstack/lint)
  • content/docs/releases/v17.mdx (via @objectstack/lint)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

2 participants