Uh oh!
There was an error while loading. Please reload this page.
fix(types): read the SPEC_DERIVED_PAIRS re-check off the AST, not raw text - #7277
Merged
Conversation
… text `zod-mirror-parity.test.ts` decided which mirrors are spec-derived by slicing the source between `export const` boundaries and testing the slice against a `\bSpec[A-Z]` word pattern. That had two independent defects, and one docstring fired both: a `Spec…` token in PROSE counted as a reference, and the slice ran past its own declaration to the next `export`, so the red named the neighbouring export instead of the edited one. `specReferencingExports()` parses instead. `Spec…` identifiers come off the AST, so comments and string literals are not references and nothing has to strip them. Attribution is by declaration; file-local references through PRIVATE consts are resolved to a fixed point so a mirror built from a spec-derived field map keeps its dependency, while exported mirrors are not hopped through. Two entries leave the derived list as false positives of exactly those two defects — `base.zod.ts#BaseSchema` (its file's only `Spec…` token is a comment) and `objectql.zod.ts#ObjectViewSchema` (a `BaseSchema.extend` of local literals whose window swallowed a private `SpecKanbanConfigSchema` block ~50 lines past its end). No corpus and no ledger changes. Seven fixtures pin both directions: a comment-only mention yields nothing, a code reference still fires. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
PR #6704 reworded this docstring to dodge a literal `Spec` + capital-letter token and left a comment asking the next editor to remember, because the `SPEC_DERIVED_PAIRS` re-check scanned raw text and misattributed the mention to `ObjectTreeSchema`. The previous commit made that scanner parse, so the convention held by discipline is no longer needed and the workaround is retired: the docstring names `SpecGanttConfigSchema` in prose again, which is what it wanted to say. This doubles as the live positive proof for objectui#6705 — the pre-fix scanner goes red on this file state, the fixed one stays green. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Empty frontmatter — the presence gate's own explicit exemption. The scanner change is test-only and the one change under `packages/types/src/zod/` is a docstring; no runtime, type or schema surface moves. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
September 2, 2026 03:10
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#6705
What was wrong
The
SPEC_DERIVED_PAIRSre-check decided which zod mirrors are spec-derived by slicing the source betweenexport constboundaries and testing the slice against a\bSpec[A-Z]word pattern. Two independent defects, both of which one docstring fired:SpecGanttConfigSchema.extend(...)from the same token in prose.export const Xto the nextexport, so everything in between — private consts and the next export's own docstring — was charged toX.The fix
specReferencingExports(fileName, source)parses instead of scanning:Spec…identifiers come off the AST, so comments and string literals are not references. Nothing strips anything, so there is no comment-stripping regex to get wrong on a string containing*/sequences — a fixture pins exactly that string.Two entries leave the derived list — please read this part
This is the one thing in the PR that is not purely mechanical, and it is reported rather than absorbed. Neither mirror changed; the re-check stopped mis-reading them. Neither references a spec schema:
base.zod.ts#BaseSchemaSpec…token is in a comment:rather than calling `SpecSchema.omit({…}).partial()`. Prose.objectql.zod.ts#ObjectViewSchemaBaseSchema.extend({…})where every member is a local literal. Its declaration ends at line 212; the nextexport constis ~50 lines later, and the old window swallowed the privateKanbanConfig = SpecKanbanConfigSchema…block that belongs to no export.ObjectViewSchemaremoval has a consequence this PR deliberately did not settle. This file's header records objectui#6058's remedy split, which routesObjectViewSchema's unmirrored declared keys as SPEC-DERIVED — "the LOCAL declaration carries members the spec schema does not model, which is objectui#2231's unification question and NOT a local mirror edit". That routing rests on the false positive. Re-routing those keys is a remedy decision on theUnmirroredDeclaredledger, which this card was fenced out of, so the split is left standing as written, counts and all, with aKnownDrift/UnmirroredDeclared/RuntimeOnlyDeclared) and no corpus schema is touched.Evidence — both directions, and the gate is not blinded
The card's fence is that a fix which stops seeing comments and stops seeing real references goes green on the old suite while destroying the gate.
Live reproduction (ablation 1). The pre-fix scanner, run against this branch's restored docstring, reproduces the reported failure exactly — and names the innocent neighbour:
Mutation proven on disk (
old window code present = 1,new AST helper present = 0); restored by blob hash,1a45bced…before and after.Positive direction (ablation 2). Neutering the fixed helper to return an empty set reddens 5 tests — the live re-check plus every positive fixture:
Mutation proven on disk (injected marker = 1, removed expression = 0); restored by blob hash with
git diff HEADempty. All eight surviving pairs are found by code reference alone.Seven fixtures pin the shape in memory: comment-only mention yields nothing; code reference fires; a
Spec…token inside a string literal carrying*/and//is not a reference; a private const between two exports charges its prose to neither neighbour; a private const with a real reference is charged to its user, not its neighbour; the next export's docstring is not charged to the previous export; plus a non-vacuity pin against the realobjectql.zod.ts.The docstring restoration
PR #6704 reworded a docstring to dodge the literal token and left a trap comment asking the next editor to remember. That convention is what a gate is supposed to replace, so with the scanner fixed the workaround is retired and the docstring says what it wanted to say. This is the only change under
packages/types/src/zod/, it is comment-only, and it doubles as the live positive proof above.Gates run — all verdict lines quoted, against final commit
85e014af2Test Files 1 passed (1)/Tests 12 passed (12)packages/typessuiteTest Files 84 passed (84)/Tests 1070 passed (1070)@object-ui/typestype-checktsc --noEmit && tsc -p tsconfig.examples.json && tsc -p tsconfig.test.jsoncheck:control-bytes✅ check-control-bytes: OK (scanned 6005 tracked text file(s); skipped 85 binary).check:vi-mock-specifiers✅ check-vi-mock-specifiers: OK (4129 tracked source file(s) …)check:vi-mock-inherit✅ check-vi-mock-inherit: OK (…)check:spec-symbols✅ spec symbol derivation: 1333 files scanned against 4959 spec export names; … 0 untriaged collisionscheck:phantom-deps✅ Every in-scope import is declared by the package that publishes it.✅ 2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)— empty frontmatter, "the explicit exemption and a complete answer to this gate"check-changeset-fixed/-no-major/-overwritetype-checkis a real measurement, not a vacuous pass:tsc -p tsconfig.test.json --listFilesshows the edited test file (2 hits),objectql.zod.ts(1) andtypescript/lib/typescript.d.ts(1) in the compiled set.Declared narrowing — lint. Repo-wide
turbo run lintis CI's run. Locally lint was narrowed to the affected package and the narrowing is measured, not assumed: ① the population came from eslint's own traversal under the root flat config, not a guess; ②--format jsonreports 148 files linted, 0 errors, 267 warnings, exit 0 — the package's ownlintscript (eslint .) verbatim; ③eslint.config.jsdeclares noprojectServiceand noparserOptions.project, so linting is not type-aware and this diff cannot move the verdict of any file it does not contain.Merge state.
origin/mainwas merged at1a1235c94(picking up #7241, #7216, #7236, #7262), and every verdict above was taken after that merge.🤖 Generated with Claude Code
https://claude.ai/code/session_01BGMDbrVa8JjZcCQ7DWYH1b
Generated by Claude Code