ReviewOS

home-lang/home

fix(ts): admit qualified interface schemas without Zod regressions

#609
Closed chris opened this 8 days ago ·
8 days ago

Parent: #589 Umbrella: #548

Resolving qualified namespace-imported type references before declaring them opaque makes the focused interface reduction exact, but the untouched pinned Zod 4.5.2 corpus gate exposes four added diagnostics and only two removals.

Clean ReleaseFast evidence (explicit --noEmit, zero generated .js files):

  • baseline: 1,162 diagnostics, SHA-256 0d1d85991dcbb73deb00dba10da1bbef60c10c48fd50b3819887096553110ab9
  • candidate: 1,164 diagnostics, SHA-256 3bddb86ac12581c73bcbd9d6d48c0a55e206e8a1b418c438fa3a20426e41f84a
  • candidate output is byte-identical across two runs
  • exact delta: 4 added, 2 removed

Added diagnostics:

  • src/v4/core/schemas.ts:1204 TS2430 on $ZodCustomStringFormat<Format>
  • src/v4/core/schemas.ts:2002 TS2322 assigning an inferred option-key array
  • src/v4/core/schemas.ts:3789 TS2774 on a function condition
  • src/v4/core/schemas.ts:4424 TS2430 on $ZodPreprocessDef<B, I>

Acceptance criteria:

  • isolate each added diagnostic with a minimal reference-validated reduction
  • fix the underlying relation/inference/narrowing semantics rather than suppressing diagnostics
  • retain qualified imported interface member types without marking resolved paths contextual-only
  • require zero added diagnostics on the untouched 106-file corpus
  • keep the corpus tree byte-identical to the official Zod 4.5.2 tarball and pass --noEmit explicitly
  • do not publish timing or README claims until semantic admission
8 days ago

First conservative #609 slice landed directly on origin/main as 0bd698363 (fix(ts): retain qualified scalar interface types (#609)).

The program schema now retains namespace-qualified aliases inside exported interface members only when their entire declaration graph is scalar/value-like (primitives, literals, parameters, references, and unions). Structured, mapped, conditional, indexed-access, class, function, contextual-only, and otherwise unsupported projections remain rejected. This is a semantic support boundary, not diagnostic suppression.

Validation:

  • focused class_schema and ts_program suites pass
  • regression proves Shapes.Value[] supplies (value, index) callback context across two import boundaries
  • negative control proves a qualified structured alias remains unsupported
  • zig fmt --check and git diff --check pass
  • untouched pinned Zod 4.5.2 corpus: 1,162 -> 1,162 diagnostics
  • exact delta: 0 added, 0 removed
  • two ReleaseFast --noEmit runs are byte-identical to the admitted baseline, SHA-256 0d1d85991dcbb73deb00dba10da1bbef60c10c48fd50b3819887096553110ab9
  • generated .js files after both runs: 0

The earlier broad candidate remains rejected: it exposed four false diagnostics in Zod. This issue stays open for principled admission of richer qualified schemas.

8 days ago

Two broader #609 experiments were completed and fully reverted without commits.

  1. Reusing whole-declaration schema admission for qualified references passed ts_program, but Zod moved 1,153 → 1,159 with 6 additions and 0 removals. The additions exactly undid the readonly-Record gains admitted in #591, so this path was rejected.

  2. A dedicated partial-interface state preserved supported members while degrading unsupported siblings. Its focused regression passed all 165 ts_program tests, but the untouched Zod run was invalid for admission: 1,054 total diagnostics hid 336 additions and 435 removals, and none of the five target callbacks disappeared. The additions included widespread false call/return/property errors. This was also fully reverted.

Both runs used the untouched 106-file corpus with explicit --noEmit and produced zero generated .js files. The repository is back to the admitted source state. Aggregate diagnostic counts are not being treated as improvements; only exact zero-addition set changes qualify.

The evidence shows that whole-interface materialization is the wrong boundary. The remaining work should project requested members from qualified imported declarations without publishing an approximate whole structural type.

8 days ago

Landed 2fdb7d0c9 (fix(ts): project qualified assertion array members (#609)) directly on origin/main.

This conservatively projects a directly declared array member from an explicit namespace-qualified interface assertion while keeping unsupported whole declarations out of normal structural resolution. No corpus-specific paths or names are special-cased.

Validation:

  • zig build test -Dfilter=ts_program: pass (165 tests)
  • zig build test -Dfilter=ts_checker: pass
  • focused reduction matches TypeScript 6.0.3 and native TypeScript 7.0.2: all report only the intentional TS2322 and no TS7006
  • Zod 4.5.2 admitted corpus: 1,153 -> 1,149 diagnostics, exact delta 0 added / 4 removed
  • removed: TS7006 for x/i at json-schema-processors.ts lines 373 and 416
  • two Home runs byte-identical: SHA-256 9a171804efa705d3c9cc15053c5b6b02e87704b415af3c638b1e6e9ef3c27145
  • --noEmit; generated JS count remains 0

Keeping this issue open for the remaining indexed/mapped mime.map projection at line 245.

8 days ago

Completed and landed on origin/main in a5ae69070 (fix(ts): project indexed assertion array bindings (#609)).

The final change retains complex qualified references only for explicit projection, never for ordinary whole-type publication. It resolves the mapped constituent before the broad string index, then projects the direct destructured array binding into normal callback contextual typing.

Validation:

  • zig build test -Dfilter=ts_program: pass (166 tests)
  • zig build test -Dfilter=ts_checker: pass
  • ReleaseFast home-tsc: pass
  • faithful three-module reduction matches TypeScript 6.0.3 and native TypeScript 7.0.2: each reports only the intentional TS2322 at consumer.ts:10, with no TS7006
  • admitted Zod 4.5.2 corpus: 1,149 -> 1,148 diagnostics, exact normalized delta 0 added / 1 removed
  • sole removal: json-schema-processors.ts:245:31 TS7006 for m in mime.map
  • repeated Home outputs are byte-identical: SHA-256 a9747a7f3a4f28de0fc3737b17fd3af2cad83a72ff6fed03ed2aff4c11734b4a
  • explicit --noEmit; generated JS count 0

This completes the qualified interface assertion projection work tracked here.

Sign in to comment on this issue.