Skip to content

alias-integrity: fail an alias row a guidanceSet already consumes - #7952

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-7889-alias-guidance-reachability
Aug 12, 2026
Merged

alias-integrity: fail an alias row a guidanceSet already consumes#7952
os-zhuang merged 1 commit into
mainfrom
claude/issue-7889-alias-guidance-reachability

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#7889

What

strictUnknownKeyError (packages/spec/src/shared/suggestions.zod.ts) consults three channels for each unrecognized key, in order: exact guidance, then guidanceSets, and only then the aliases rename fallback. A guidanceSets match continues past the alias lookup entirely (confirmed by reading the actual control flow, not assumed from the issue body):

constprescription=guidance[key];if(prescription){prescriptions.push(prescription);continue;}constset=guidanceSets.find((s)=>keySetMatches(s,key));if(set){/* … */continue;}// <-- alias table never consulted for this keyconstcanonical=aliases[aliasProbe(key)]??findClosestMatches(...);

So an alias row whose written key also matches a guidanceSet declared on the same strictObject table is dead on arrival — the set answers first, every time — and nothing checked for that before this PR. PR #7884 had to place its one view-family alias (disabled → readonly on FormFieldSchema) outside VISIBILITY_KEY_PATTERN's reach by hand; a future visible: 'visibleWhen' row on the same shared table would have shipped exactly as dead, with every existing gate green.

Change

Extends packages/spec/src/shared/alias-integrity.test.ts (test-only, no other files touched) with:

  • unreachableAliasRows(surfaces) — reads only options.aliases and options.guidanceSets (never .shape), and flags any alias key a guidanceSet on the same table already matches via keySetMatches (the same function the real error map calls).
  • Live-table verdict: unreachableAliasRows(SURFACES) must be empty, plus an explicit pin that the one existing view-family alias (disabled → readonly on FormFieldSchema, ui/view.zod.ts:1775) exists and sits on a table carrying VISIBILITY_KEY_PATTERN — so the empty-array assertion is judging a real, non-trivial table rather than passing vacuously.
  • Self-test: a synthetic strict-options + alias table (no live schema touched) proves the check can go red on a planted dead row, plus two controls (no guidanceSet on the table; a guidanceSet present but not matching the alias key) proving the verdict tracks an actual pattern match rather than mere presence of a guidanceSets array.

No acceptance-behavior change anywhere — publish/parse behavior of every schema is byte-identical before and after. No *.zod.ts files touched.

Tests

pnpm --filter @objectstack/spec exec vitest run src/shared/alias-integrity.test.ts src/shared/strict-object.test.ts src/shared/visible-when-alias-guidance.test.ts
Test Files 3 passed (3)
Tests 69 passed (69)
pnpm --filter @objectstack/spec run test
Test Files 381 passed (381)
Tests 10033 passed (10033)
pnpm --filter @objectstack/spec run typecheck
tsc --noEmit ✓ / check:scripts-typecheck ✓ / check:test-typecheck: OK (57 file(s) / 265 error(s) held in shrink-only debt, unchanged)
eslint src/shared/alias-integrity.test.ts — clean
node scripts/check-nul-bytes.mjs — OK

This is a test/gate-only change with no reader-visible behavior — no changeset; skip-changeset label requested.


Generated by Claude Code

…consumes
`strictUnknownKeyError` consults `guidance`, then `guidanceSets`, and only
then the `aliases` rename fallback — a guidanceSets match `continue`s past
the alias lookup entirely. An alias row whose written key also matches a
guidanceSet on the same strict-options table is therefore dead on arrival,
and nothing checked that until now.
Extends alias-integrity.test.ts with `unreachableAliasRows`, which reads
only `options.aliases` / `options.guidanceSets` (never `.shape`) and flags
any alias key a guidanceSet already matches. Two tests: the live-table
verdict (also pinning that the one existing view-family alias, `disabled ->
readonly` on FormFieldSchema, stays reachable outside VISIBILITY_KEY_PATTERN),
and a self-test proving the check can go red on a planted synthetic dead
row without touching any live schema.
Fixes#7889
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WocN37om5bw81JDoEEMA2e
@vercel

vercelBot commented Aug 12, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 12, 2026 8:45am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

No hand-written docs reference the 0 changed package(s). ✅

@os-zhuangos-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 12, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review August 12, 2026 09:10
@os-zhuang
os-zhuang added this pull request to the merge queueAug 12, 2026
Merged via the queue into main with commit f7dceedAug 12, 2026
30 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-7889-alias-guidance-reachability branch August 12, 2026 09:22
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-zhuang@claude