ReviewOS

home-lang/home

fix(ts): make transferred mapped utilities safe and exact

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

Parent: #589

A strict three-file reduction for the remaining Zod nested-array callback gap shows that an imported function returning EnumValue[] transfers correctly until its parameter is Readonly<Record<string, EnumValue>>. The program schema currently rejects the standard utilities, so the imported function falls back to any and its result loses array callback context.

A direct exact encoding of Record<K,V> and Readonly<T> using the schema’s existing mapped/keyof/indexed-access expressions passed the full ts_program suite, but failed the real corpus gate:

  • reduction gained a false TS2345 for values({})
  • untouched Zod compiler process crashed with exit 139 before emitting diagnostics
  • no result from that crashed run is counted as an improvement
  • the experiment was fully reverted and was not committed

Reduction: /Users/chris/Code/Home/lang-ts-perf-416-evidence/nested-array-context

Acceptance criteria:

  • isolate the mapped utility instantiation crash with a minimal program regression
  • transfer Record<K,V> and Readonly<T> without unsafe recursion or argument false positives
  • preserve local shadowing of utility names
  • make Home, pinned tsc 6.0.3, and pinned tsgo 7.0.2 agree on the reduction
  • require zero added diagnostics and no crash on the untouched 106-file Zod corpus
8 days ago

Safety rollback landed on origin/main as 67adab666 (revert(ts): remove unsafe utility schema transfer (#591)).

Three intervening commits (0574617b5, 50e6b4288, and ff67a3396) briefly published the rejected qualified-reference / Record / Readonly transfer experiment. The utility path was actually dead behind if (false and ...), its new regression failed, and enabling it reproduced invalid cross-program TypeIds and a Zod process crash. They did not satisfy this issue or the corpus admission gate and have now been completely reverted in one issue-linked commit.

Post-rollback validation:

  • ./pantry/.bin/zig build test -Dfilter=ts_program passes
  • ReleaseFast home-tsc builds successfully
  • untouched pinned Zod 4.5.2, 106-file config: 1,162 diagnostics
  • two runs completed normally with expected exit 1
  • both outputs are byte-identical: 6,147 lines, SHA-256 0d1d85991dcbb73deb00dba10da1bbef60c10c48fd50b3819887096553110ab9
  • commit author is Chris Breuer only; no coauthor trailer

The issue remains open. The next design must make readonly/indexed utility structure part of a safe schema and interning model, rather than materializing checker-owned TypeIds across program boundaries. The regression also needs a negative call such as values(1) so a parameter silently degraded to any cannot pass.

8 days ago

Correction after a full corpus-integrity audit: the 1,821-diagnostic result below was invalid and must not be used. A compiler invocation had emitted 82 .js files into src/v4 despite noEmit in the project config; NodeNext then resolved those generated files instead of the pinned TypeScript sources. The extra files were moved intact to /tmp/zod-4.5.2-generated-js-20260903-1248, and the entire src/v4 tree now matches the official 4.5.2 tarball byte-for-byte.

With --noEmit also passed explicitly, the admitted baseline is restored: 1,162 diagnostics, 6,147 lines, SHA-256 0d1d85991dcbb73deb00dba10da1bbef60c10c48fd50b3819887096553110ab9, with zero generated JavaScript files afterward.

The schema-native Readonly<Record<primitive, V>> experiment remains uncommitted and fully removed, but its prior 1,821 rejection is withdrawn pending a clean retest. The broader standalone Record variant still legitimately failed with recursive schema expansion / process crashes and remains rejected.

8 days ago

Crash-hardening chunk landed directly on origin/main as 6c4c9be01 (fix(ts): stabilize object mismatch members (#591)).

The macOS crash report identified a use-after-reallocation in tryReportObjectLiteralPropertyMismatchWithOptionalDisplay: the checker iterated a borrowed object-member pool slice while nested contextual/diagnostic checks could intern types and relocate that pool. The loop now owns a stable snapshot.

Validation for the landed safety fix alone:

  • full ts_checker suite passes
  • untouched pinned Zod 4.5.2 corpus completes normally twice with explicit --noEmit
  • 1,162 diagnostics in both runs; exact delta 0 added / 0 removed
  • both outputs byte-identical to the admitted baseline, SHA-256 0d1d85991dcbb73deb00dba10da1bbef60c10c48fd50b3819887096553110ab9
  • generated .js files: 0

A separate compact Readonly<Record<...>> schema experiment was rejected and fully removed before this commit. It fixed both focused reductions and removed six corpus diagnostics (including the two target .every TS7006s), but produced 158 additions: 156 TS7006s across processor declarations plus two false TS2430s. The unsafe broad mutable-Record form also reproduced declaration-instantiation stack exhaustion. No utility-schema code from those failed candidates was committed.

8 days ago

Completed on origin/main in two small commits authored only by Chris Breuer:

  • d8fc967a9 — fix(ts): accept compatible generic interface overrides (#591)
  • 23a559690 — fix(ts): transfer readonly record function schemas (#591)

The implementation keeps the transfer deliberately narrow: exact readonly Record<K, V> structure is admitted for function declarations; mutable or structural declaration graphs remain unsupported; contextual-only callable shells degrade unsupported referenced leaves safely; local Record shadowing still resolves normally; and generic defaults reserve their definitions before recursive resolution. Generic interface member compatibility now accepts exact instantiations and direct covariant wrapper overrides while a Pair<B> versus Pair<I> negative control still reports TS2430.

Validation:

  • full ts_checker suite passes
  • full ts_program suite passes
  • the same suites pass again after cherry-picking onto the latest main landing worktree
  • nested-array-context: TypeScript 6.0.3, native TypeScript 7.0.2, and Home all exit 0
  • mapped-utility-cycle: TypeScript 6.0.3, native TypeScript 7.0.2, and Home all exit 0
  • compiler versions were verified as Version 6.0.3 and Version 7.0.2
  • untouched pinned Zod 4.5.2 corpus, 106 files, explicit --noEmit: 1,162 → 1,153 diagnostics
  • exact corpus delta: 0 added / 9 removed
  • two candidate runs are byte-identical, SHA-256 265739efe928fd81e15df0d5a7012cc8bb1aabe6d355903760b227559ede451e
  • generated .js files under src: 0

The nine removed false positives are four callback-context TS7006 diagnostics, two impossible-comparison TS2367 diagnostics, two generic-interface TS2430 diagnostics, and one downstream RegExp assignment TS2322. No timing claim is being made from this semantic admission run.

Sign in to comment on this issue.