ReviewOS

home-lang/home

fix(ts): preserve contextual paths beside opaque siblings

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

Parent: #548

Problem

After #666–#670, an imported mapped/conditional/Extract handler graph is exact across three modules while every discriminated member is wholly transferable. Adding one unrelated unsupported sibling to the same object erases the entire contextual member path:

export interface A {
  _zod: { def: { type: "a" }; opaque: Set<string> };
  a: number;
}
export interface B {
  _zod: { def: { type: "b" }; opaque: Set<string> };
  b: string;
}

Nothing in the handler reads opaque. TypeScript 6.0.3 and the native preview still infer handler property a as (item: A, rewritten: boolean). ReleaseFast Home changes from the exact 2× TS2322 + 2× TS2339 control multiset to two false TS7006 diagnostics and misses the callback controls.

The Program schema already has contextual-only projection semantics that may preserve exact outer callable/object structure while degrading an unsupported leaf to any. The current projection lowers an entire member to any when any nested declaration/unsupported leaf is present, so the supported _zod.def.type chain disappears with its sibling.

This minimal differential mirrors the remaining Zod 4.5.2 core/visit.ts boundary: schema interfaces expose exact nested discriminants and handler-relevant members alongside large unrelated graphs.

Fair strict oracle

  • Same three modules, root order, NodeNext, strict, and noEmit for TypeScript 6.0.3, native TypeScript, and ReleaseFast Home.
  • The only change from the passing #670 oracle is one unused opaque sibling with a standard generic type.
  • Valid keys, invalid key, wrong assignment, missing discriminated member, and missing boolean member remain independent controls.
  • An additional negative control attempts to consume the projected handler alias as a general imported type; it must not publish the leaf-degraded approximation outside contextual callable input.

Acceptance

  • Preserve exact supported object/function/mapped/conditional/indexed/Extract scaffolding inside contextual callable input while degrading only the unsupported leaf.
  • Keep source declaration and type-parameter identities and allow Extract to discriminate on the retained nested literal path.
  • Do not expose a contextual projection through ordinary imported annotations, assertions, variables, returns, or structural relations.
  • Do not fabricate members, flatten namespaces, broaden key domains, or treat a failed projection as a supported whole declaration.
  • Keep recursive graphs finite by declaration identity and retain existing class/function/nominal safety guards.
  • Add permanent schema and Program positive/negative regressions and match the exact TypeScript 6.0.3/native focused oracle with no TS7006/TS2345.
  • Run complete Program/checker suites, ReleaseFast, formatting, whitespace, and required Pickier.
  • Run the unchanged pinned Zod 4.5.2 graph twice, require zero additions, and document exact removals or unchanged results.
  • Publish the detailed audit and linked README table.

No Zod/package/path/name/property/line special cases, source-text matching, whole-object any, callback-value-driven overload selection, or benchmark-only member synthesis.

8 days ago

Implementation evidence for 290487c0f (pushed directly to origin/main):

  • Builder admission is limited to mapped callback contexts and non-class/non-function declaration bodies. Unsupported declarations remain contextual-only and are not exported as ordinary complete types.
  • The checker projects only properties demanded by the Extract target, keeps unrelated sibling names with opaque local values, evaluates the resulting union with normal distributive conditional semantics, and terminates declaration cycles by identity. There is no source-name special case or depth cap.
  • Exact three-module oracle (opaque Set<string> sibling): TypeScript 6.0.3, native TypeScript preview, and ReleaseFast Home each report exactly 2× TS2322 + 2× TS2339; Home reports no TS7006 or TS2345.
  • Complete Program suite: 201/201 passed.
  • Complete checker suite: passed.
  • ReleaseFast build: passed.
  • Bounded Zod closure: completed normally in 20.57s (no signal/crash/runaway expansion).
  • Pinned 106-file Zod 4.5.2 A/B versus #670 parent: 394 → 374 diagnostics; 389 → 369 unique path/line/column/code identities; exactly 20 false TS7006 identities removed (8 classic/in-out, 8 mini/in-out, 2 classic/deep-partial, 2 mini/deep-partial); zero identities added.
  • Two independent candidate runs are byte-identical. Raw stderr SHA-256: 5353246e2b9172390011adff013f5807c60da3019b28e34f3d814e50d80fcf80. Normalized identity SHA-256: 30f2defec18b4b81b6795a59a626cd00ffccb69bbdaface112ba1d7d25982bb7.
  • zig fmt --check and git diff --check: passed.
  • Required repository-wide bunx --bun pickier .: unchanged baseline failure, 22,427 findings (11,834 errors, 10,593 warnings).

Next small chunk: publish the detailed audit and README summary table, then close this child issue and update #548/#416.

8 days ago

Completed and documented on origin/main:

  • 290487c0f — fix(ts): preserve contextual paths beside opaque siblings (#671)
  • 6e199a3e2 — docs(ts): publish contextual path audit (#671)

Acceptance is satisfied: exact three-engine oracle parity, permanent schema and Program coverage, complete Program/checker suites, ReleaseFast and formatting checks, crash-safe bounded Zod closure, two byte-identical full Zod runs, 20 false TS7006 identities removed with zero added, and README/detail documentation linked to this evidence.

Sign in to comment on this issue.