- buf.compare / buf.equals / Buffer.compare arguments that are not statically bytes route through checked-dynamic validators (buffer.compareChk / bytes.equalsChk / bytes.compareChk) running Node's own ladders: ERR_INVALID_ARG_TYPE with the API's argument names and determineSpecificType renders, validateOffset's ERR_OUT_OF_RANGE, undefined slots taking Node defaults — and well-typed dyn values still compute real answers.
- The bytes range ladders (validateOffset, boundsError, checkInt, swap, fill, randomBytes, fs.readSync) stamp their Node codes (ERR_OUT_OF_RANGE / ERR_BUFFER_OUT_OF_BOUNDS / ERR_INVALID_BUFFER_SIZE / ERR_INVALID_ARG_VALUE); validateOffset renders ±Infinity as 'an integer' like Number.isInteger.
- The deprecated `new Buffer(number, enc)` string arm throws Node's ERR_INVALID_ARG_TYPE (the throwing path fires no DEP0005, so compiled silence matches); other ctor forms keep their fences.
- assert.throws/rejects accepts a plain expected object held in a variable (the shared `{ code: ... }` expectation record) through the errValue key walk.
- scr_dyn_specific_type/scr_dyn_arg_type_fail move beside the DOM core (scr_json.c) so always-linked validators render through them; the handle unit keeps the listener gate.
- The differential lanes learn `// @no-deprecation` (Node oracle runs --no-deprecation) for fixtures pinning deprecated-API error paths; corpus 2556 pins the whole ladder byte-identically on both backends.
- The promise forms ride the callback machinery: scr_sp_finished/scr_sp_pipeline park a settling watcher (fulfilled on a clean finish, rejected with the stream's error or ERR_STREAM_PREMATURE_CLOSE), verified byte-exact against Node including the already-closed async settlement
- lower-stream's stream/promises arm replaces its not-yet fence: finished(stream) and pipeline(...streams) lower to sp.finished/sp.pipeline (stream stages only — the options argument and iterable/generator/function stages keep pointed fences); both specifier spellings and the CJS require forms resolve
- Both backends emit it: the C compound-literal stream list and an LLVM stack array beside the callback pipeline's emission; sp.* joins the may-throw seeds, the loop-liveness set, and moduleUsesStream's link gate
- The SC1010 hint gains stream/promises and the long-missing querystring; hint snapshots and the surface manifest repin
- Corpus 2560/2561/2562 pin pipeline success/error teardown, finished's clean/errored/premature/writable arms, and the CJS destructured-require spelling — green on both backends and under ASan + RC audit
- `const f = (...args) => from(...args)` ICEd with SC9001: the fenced arrow's PoisonError deferral built the runtime-fence lambda from funcType.params, which excludes the hidden trailing DOM-array param a rest-marked type implies — the closure no longer matched its own target signature. The fence lambda now spells that slot (island rest types already spell theirs), so any future fence inside a rest arrow stays a clean deferral.
- The idiom itself now compiles: spread arguments a compile-time completion cannot take ride a new runtime-arity lane (lowerSpreadArgsCall). Checked-dynamic spreads box the callee (dynFrom) and emit a spread-marked dynCall — both backends build one fresh DOM argument array (plain args move in, spreads flatten via the new scr_dyn_arr_push_spread) and apply through scr_dyn_apply, the boxed thunk delivering JS arity; island (--dynamic) spreads marshal the callee and ride the new jsOp callSpread through an island prelude helper with real `f(...pre, ...s)` spread syntax.
- Non-iterable spread sources throw V8's exact spread-call TypeError texts, catchably, on both lanes: nullish sources spell the spread expression ("v is not iterable (cannot read property undefined)"), everything else the generic Spread-syntax text.
- Direct calls of the --dynamic islandRest lambdas complete like completeArgs' island pack (fixed slots positionally, surplus into one fresh engine array), so `f(1, 2)` on a `(...args) =>` binding works at any arity.
- Corpus fixtures 2557-rest-spread-forward.js and 2558-rest-spread-forward-dynamic.js: forwarding to a declaration, a closure, a const re-binding, leading fixed params, rest-to-rest chains, mixed spread positions, JS-arity drops/fills, string/array spread sources, and the error texts — byte-identical vs Node on both backends and under --dynamic.
- A hierarchy upcast in the C backend is a raw pointer cast, so one object's rc/vt and fields are accessed through both the base and derived struct types; clang's TBAA at -O2 treated those as non-aliasing and reordered/elided the inlined rc updates, freeing an upcast-compared object while a global still owned it (SIGSEGV in sc_release_globals — a runtime miscompile, not a compile-time crash; the generated C's RC bookkeeping was already balanced).
- The flag joins all three lockstep option sets: compileC's single-invocation buildArgs, the cache-miss cflags, and compileLibArchive; the cache key hashes the full command line, so stale binaries and runtime objects re-key on their own.
- The LLVM backend emits no TBAA metadata, so the flag also makes the two backends' memory semantics identical instead of coincidentally so.
- New differential fixture 2556-upcast-identity.ts: identity compares through a three-deep hierarchy at every view, both operand orders, !==, constructing operands on either and both sides, compares as call arguments and as standalone expression statements, and field liveness after the compares — it SIGSEGVs without the flag and is Node-exact with it on both backends, plain and sanitized.
- Promise.reject(value) with an untyped JS reason (a dyn-typed arg — the tracingChannel promise shape) crashed the LLVM emitter's object-only assertion; the IR contract (validate.ts) admits object OR dyn reasons and the C backend already emitted both.
- Widen the assertion and route the dyn reason through emitThrowValue's existing REF arm — scr_throw_ref with the dyn retain/release pair and no trace, byte-identical to the C lowering; identity flows to catch/unhandledRejection observers.
- Corpus fixture 2556-promise-reject-dyn-reason.js: Error/string/number/object reasons through .catch and awaited rejection, byte-identical vs Node on both backends.
- SC1010's wording routes through one helper (unsupportedModuleFeatureOf): pending modules keep the plain not-yet story, out-of-scope ones append the reason
- v8/inspector name the missing V8 engine, node:sqlite the unbundled SQLite library, domain its deprecation and engine-level interception, and the fourteen underscore-prefixed legacy modules their Node-internal implementation objects
- All five fence sites reword together: the four import/require edges in program.ts and the fenced-binding use site in lower-exprs.ts
- New diagnostics fixture module-out-of-scope.ts pins the reasons (and that stream/web stays plain not-yet); the coverage import-fences snapshot repins with the v8 reason
- Eligible packages compile statically into the archive through the npm-static machinery, transitive deps judged to the same bar at a fixpoint
- Ineligible packages refuse with a teaching naming the package, the failed bar, and the vendor-or-drop remedy — never the executable lane's dynamic advice
- npm module bytes join source_hash and build_id; npm declarations stay out of the contract type tables by construction
- Inter-package requires run the dependency's init in both lanes
# Conflicts:
# packages/compiler/src/diagnostics/diagnostic.ts
# packages/compiler/src/frontend/lowering/lowerer.ts
# packages/compiler/src/index.ts
# tests/harness/library-mode.test.ts
- The helper pair verifies by structure; recognized call sites pad down to the bare require at original offsets so the dead helper chain sweeps away
- .default semantics decided at build time per Node: binding for node-mode and unstamped CJS targets, member read for __esModule-stamped ones
- Bare requires of opted-in packages now run the dependency's init and bind as CJS namespaces — a static-claimed package can no longer crash at load
- Anything recognition can't finish degrades the package to the island with the construct named; auto mode shares the path
- SC4013-SC4019 classify the runtime trap kinds (escaped exception, range, type, syntax, OOM, internal invariant, residual); the funnel assembles text/code/symbol with the baseline line unchanged as field 0
- Every generated entry prologue records its exported symbol for the funnel; init counts as an entry
- Profile teachings and remediations overlay per code through a program-TU table identical on both backends
- The executable lane is proven byte-identical; K5/K7/K11 pins extended, K12 pins the overlay and default forms
- Adds the ts7 canary entries for 2560-2562 and the intl diagnostics fixture, plus the missing baselines for the pre-existing 2510-2513 and 2520-2523 fixtures the re-record picked up — purely additive, nothing removed or changed.
- purely additive re-record: the four width/index-signature corpus programs and the record-width diagnostics fixture, plus eight earlier corpus entries (2510-2513, 2520-2523) the default canary subset had never sampled
- no existing entry's order or preflight diagnostics changed
- recordWidthPlan narrows index-signature sources into declared-only targets (declared fields copy off their struct slots, the overflow drops with the width); absent-field completion declines there — the overflow could hold the key at runtime, and a completed undefined would drop the value Node keeps
- the overflow capture initializes same-named declared target fields directly off the source, admitting REQUIRED declared members; literal writes to names the target does not declare go overflowOnly, and a dispatch-writes gate keeps the validator's collision rule for the rest
- widthLiftPlan gains dynIn (a typed field into an 'unknown' slot — the static→DOM deep copy), upcast (derived into base, the prefix-layout reinterpret), and funcAdapt (funcCoerceAdapter's CLEAN subset — the stranded trap-only dispositions stay top-level, never inside a width plan)
- SC2002 now names the first blocking rule per record pair (describeRecordWidthBlocker mirrors the planners' gates) and its message/hint/registry entry speak the width-copy truth — the manifest flips the one entry name
- corpus 2556/2557 pin both hybrid directions and the new lifts byte-identical vs Node on both backends; diagnostics fixture record-width pins the residue's pointed messages
- isSupportedIndexValue admits func/map/set: the overflow map's RC and trace machinery is already fully type-directed (scr_closure/scr_map adapters, the cycle fixpoint's map rule recursing on the value), and nested index-signature records rode the record kind all along
- the C keyed-read miss trap can now describe Map/Set-typed slots (dynDesc), reachable only through that message — no dynCheck ever expects a container
- SC2006's message and hint name the real value domain (functions, Maps, Sets, RegExps, Promises, ...) and the honest blockers left: symbol keys, dual signatures with unequal value types, and values with no representation at all
- diagnostics fixtures pivot to still-fenced shapes (Uint8Array values, unequal duals, a Date-valued bag); corpus 2558/2559 pin the command-registry and container-table patterns — declared+overflow hybrids, enumeration, delete, registry-capturing cycles, container churn — byte-identical vs Node on both backends
- new Intl.NumberFormat("en-US").format(x), the callable spelling, and x.toLocaleString("en-US") lower to one runtime formatter with default options: decimal notation, 0-3 fraction digits rounded half-up on the SHORTEST round-tripping decimal (ICU's rounding input, probed against Node — format(1.0005) is "1.001" though toFixed(3) answers "1.000"; 1e23 prints the shortest form's zeros, not the exact expansion), "," grouping, "∞"/"NaN" texts, and "-0" for negatives rounding to zero. The en-US/latn symbols are the whole embedded locale surface — no ICU is linked.
- The Ryū digit core factors out of scr_f64_to_str as scr_f64_digits (same bytes; the 1M-double oracle gate stays green) and feeds the formatter; a 30,000-double ad-hoc fuzz across magnitude regimes matched Node byte-for-byte on both backends.
- Every unlowered Intl form fences by NAME with its own reason: the environment-default locale a compiled binary cannot carry (no-locale forms), other locales and the rest of the namespace (DurationFormat, DateTimeFormat, PluralRules, getCanonicalLocales — ICU data the binary does not embed; Node 24's DurationFormat additionally throws V8-internal Temporal errors with embedded source paths, so byte parity there is a version-dependent landmine), options bags, formatter values (the composed form is the lowered shape), and non-number format arguments.
- Differential fixture 2562 pins the rounding discriminators, grouping, ±0/NaN/∞, tiny and huge edges, and both spellings byte-identically vs Node on both backends; the new intl diagnostics fixture pins every named fence, and the Intl hints across the identifier/member/type chokepoints now teach what lowers.
- The bundler-CJS rewrite erases recognized __toESM(require("x")) wrappers — module-scope bindings, the `, 1` node-mode variant, inline member reads — down to the bare require at its original offsets; .default accesses pad to the binding where Node's answer is the module (plain-CJS targets, node mode) and stay member reads for __esModule-stamped targets, decided by a require-resolution probe over the target's shipped source (forwarding chains followed)
- Interop the recognizer cannot finish — deviant helper text, escaping interop objects, non-literal arguments, ESM-output calls — answers { degrade }: the fs shadow reports the package as an offender with a note naming the construct and the fallback loop islands it, never a failed build and never the silent alternative (a live helper chain's `var __create = Object.create;` fences at module load while the report claims static); auto and explicit opt-ins share the path
- Bare requires of opted-in packages now behave like relative ones end to end: requireInitStmt emits the dep's inline %init (previously the module never initialized before its exports were read), and cjsLocalModuleBindingOf/resolveValueSymbol resolve member reads and namespace method calls through the npm-static dep's export table
- Erased wrappers join the neutralize set so the helper sweep drops the whole dead chain, hoisted canonical-table texts copied off the source drop .default on module-valued bindings exactly like the pads do, and a file with interop pads but no canonical table still rewrites pads-only
- Fixtures gtcore/gtwrap/gtdrift with cases 2556-toesm-external (byte-matches Node across both dep shapes and the comma-call spelling) and 2557-toesm-drift (construct-naming degrade under explicit and auto opt-ins), excluded from the flagless island lane like the 246x family
- Number pairs take a new scr_num_same_value runtime primitive (NaN equals NaN, +0 differs from -0 — the two divergences from ===); strings, booleans, unit literals, and every reference kind (arrays, records, class instances with hierarchy widening, functions, class values, Maps/Sets, symbols, typed arrays, promises) ride exactly the strict-equality machinery, whose answers SameValue shares.
- Union operands lower through unionEq, which grows a sameValue flag: the f64 arm's payload compare upgrades to SameValue (a separate interned C helper per union; the LLVM lane calls the runtime primitive inline), every other arm is shared between the two semantics.
- Statically disjoint kind pairs answer the constant false with the operands still evaluated for their effects (Object.is is (any, any) — tsc admits every pair); dyn/jsval operands and partially-overlapping unions fence by name with strict equality's validate/narrow-first stance.
- Differential fixture 2561 pins the NaN/±0 edges, mixed-kind calls with effect counting, reference identity across kinds, and union payloads (including NaN/±0 inside a union and union-vs-plain wraps) byte-identically vs Node on both backends; stdlib-fence pins the named fences.
- Found pre-existing (reproduced at the base commit): the C backend SIGSEGVs on console.log(asBase === d, asBase === new Base()) — an upcast identity compare plus a constructing compare in one call; the fixture avoids the shape and the bug is reported for a follow-up lane.
- compileLibrary runs the --npm-static eligibility bar automatically over every bare specifier the graph exposes (opted-in packages' own import and top-level require edges included, iterated to a fixpoint) — an eligible package compiles statically into the library graph, and every fallback the shared frontend records refuses as SC4013 naming the package, the specific failed bar, and the vendor-or-drop remedy (with the profile's SC4013 teaching riding the hint), never SC1010/SC2013's executable-lane teachings.
- requireInitStmt now emits the guarded %init call for a bare require naming another opted-in package: the dep's module body never ran before (NULL-closure crash at first use), a latent npm-static gap on both lanes that the library fixpoint hits immediately; the executable lane never exercised an inter-package require.
- Contract facts exclude statically-compiled npm files (their .d.ts is dropped by construction, so no npm declaration can name a wire-contract type) while their bytes keep joining source_hash/build_id through moduleOrder; the sidecar stays byte-deterministic and a package-file edit flips both identity hashes.
- Builtins keep their story under the npm posture: async_free builtin imports compile alongside npm code, event-loop surfaces still refuse SC4005, no new fence.
- New fixtures npm-static, npm-refuse, and contract-npm vendor fake packages per the tests/fixtures/npm precedent; the K12 suites assert the compile and refusal sides on both emissions and the contract suite covers the identity-hash implications.
- The library trap funnel (scr_library.c) now assembles every detected trap into the ratified 0x01 text 0x1F code 0x1F symbol [0x1F remediation] form: the baseline human line rides unchanged as field 0, and 0x01-led messages (facade-authored throws, the compile-time SC4012 contract trap) still pass verbatim.
- Trap kinds classify over the runtime's own message conventions into a new SC4013-SC4019 runtime code family (escaped exception, range, type, syntax, OOM, internal invariant, residual), documented beside SC4012 in the diagnostics registry; no arithmetic kind exists because no runtime site can fire one.
- Every generated entry prologue (init, reset, collect, each export, both emissions) records its external symbol in a SCR_LIB-only static slot the funnel reads, so the structured message names the trapping entry as the host linked it; profile teachings/remediations for the family land as a program-TU overlay table both backends emit identically.
- K5/K7/init-trap fixtures now pin the structured layout with the spec's parse rule (default text, code, entry symbol, fields=3 on a no-teachings profile), and new K12 tests pin the SC4014 teaching/remediation overlay plus the undeclared-code default; the verbatim and text-leads-printable pins stay.
- The default executable lane is byte-identical (signature-stripped cmp over a stash/rebuild pair); all library suites and the diagnostics suite are green on both emissions.
- new Uint8Array/Uint32Array/Int32Array/Float32Array(new ArrayBuffer(n)) erases the buffer into a zero-filled view exactly like the SharedArrayBuffer sleep idiom (literal byte length divisible by the element size), and new DataView(new ArrayBuffer(n), off?, len?) views a fresh zeroed allocation — nothing else can reference the buffer, so the erasure is exact.
- The DataView setter family (setUint8/Int8/Uint16/Int16/Uint32/Int32/Float32/Float64) lowers end to end: one scr_dataview_set runtime mirror of the getter (ToIndex offsets, Node's constant RangeError, modular integer truncation, double→float rounding, both endiannesses) wired through both backends; the bigint and Float16 setters keep the member fence.
- The resizable surface fences by NAME everywhere it can appear: new ArrayBuffer/resize/transfer/maxByteLength and SharedArrayBuffer.grow now state the reason (no free-standing ArrayBuffer value exists; grow has no threads to share with) at the constructor, identifier, member, and declared-type chokepoints, including the maxByteLength options bag inside an otherwise-erasable position.
- Differential fixture 2560 pins the erasure forms, every setter width/endianness/coercion, aliasing through x.buffer views, and the RangeError edges byte-identically vs Node on both backends; es2025-fences/dataview/stdlib-fence snapshots pin the new named hints.
- keyof-constrained generics specialize per literal key; keyed record writes take the literal-key type rule
- Generic methods called through interface-typed receivers monomorphize against the proven class
- Generic-signature annotations monomorphize their function initializers; generic-fn aliases register their target
- Fixtures 2550-2555 byte-identical on both backends
# Conflicts:
# packages/compiler/src/diagnostics/diagnostic.ts
# packages/compiler/src/frontend/lowering/lower-modules.ts
# packages/compiler/src/frontend/lowering/lower-stmts.ts
# packages/compiler/src/frontend/types.ts
# packages/compiler/test/ts7/baselines/order-parity.json
# tests/harness/__snapshots__/generic-methods.ts.txt
# tests/harness/__snapshots__/generic-value-bindings.ts.txt
# tests/harness/__snapshots__/mixins.ts.txt
# tests/harness/__snapshots__/stdlib.ts.txt
- Trap messages assemble as 0x01 text 0x1F code 0x1F symbol with an optional remediation field, built once at export resolution so both backends emit identical bytes
- Thrown messages already leading with the marker pass to the sink verbatim through a length-delimited funnel entry
- Profiles refuse teaching and remediation strings containing the reserved bytes; embedder codes validate only as clean tokens
- A conformance fixture parses the structured bytes with the ten-line host rule and pins printable-first-byte on baseline messages
# Conflicts:
# packages/compiler/src/diagnostics/diagnostic.ts
- SC4010 refuses tabled types gathered from multiple declaration sites, naming every site; SC4011 refuses conditional and mapped types with a point-at-one-declaration teaching
- Spread-composed unions flatten depth-first in source order; duplicate arms across constituents keep the first occurrence
- Conformance fixtures pin cross-file payload order, a global-shadowing enum member, and alias transparency on both emissions
- Contract facts now collect across the program's source files, and type-only modules join source_hash/build_id
- New contract-order conformance fixture (both emissions): union arms anti-alphabetical with payload records declared in a separate file (import order never perturbs table order), an anti-alphabetical enum with a global-shadowing "Infinity" member, and a union referenced through a type alias (the table derives from the aliased declaration; the alias adds no entry and no reordering).
- Contract facts now scan the whole program graph, not just the entry: type-only modules join (they have no runtime edge, so they ride the program's source files rather than moduleOrder), non-entry modules anchor after the entry in bytewise path order, and the identity hashes cover type-only modules so contract-bearing edits always move source_hash/build_id.
- SC4010: a tabled or designated type whose members gather from multiple declaration sites (interface merging, module augmentation, a same-name exported type in another module) refuses with every site named file:line.
- SC4011: a conditional or mapped type producing a tabled/designated type refuses with its own teaching.
- Union composition (type Msg = A | B where A/B are kind-tagged unions) is allowed and pinned: arms flatten depth-first in source order, each constituent in its own declaration order, and an arm name appearing in several constituents keeps its first occurrence; a repeat among one declaration's own inline arms still refuses.
- Baselines added for corpus 2550-2555 (plus the previously unrecorded 2490-2500 entries the sweep now sees); no recorded entry changed.
- tests/diagnostics/generics.ts keeps its alias/annotation sections as reached COMPILING bodies (their absence from the snapshot is the point), fixing the dangling calls the earlier edit left.
- A library-mode trap that carries a diagnostic code and/or the trapping symbol is assembled as 0x01 text 0x1F code 0x1F symbol [0x1F remediation]: the teaching text leads so plain-text hosts degrade gracefully, the whole remediation field is absent when the profile supplies none, and the frozen sink signature is untouched — all structure lives in the message bytes. The compiler assembles the buffer once at export resolution (library/trap-teaching.ts), both backends emit the same bytes, and the runtime funnel carries them opaque; the first wired site is the inbound-bytes host-contract trap (new runtime code SC4010), naming the trapping export's C symbol.
- The profile's determinism riders now feed the encoding: teachings gains a remediations sibling, both keyed by code, with keys validated only as tokens free of the reserved bytes (SC space stays the compiler registry's; embedder codes are embedder-prefixed) and values refused at load (SC4001) when they contain 0x01 or 0x1F.
- The escaped-exception renderer honors the verbatim rule: a thrown string or Error message that already begins with 0x01 reaches the sink byte-for-byte — no "Uncaught " prefix, no added newline — which is how facade-authored structured teachings ride the throw channel; everything else keeps the baseline shape, whose printable first byte is what makes the marker unambiguous.
- New K11 conformance fixture (tests/library-mode/teach) drives all of it through a real C host on both emissions: exact structured byte layout via the spec's parse rule, verbatim 0x01-led throws (Error and string), and the printable-first-byte pin on baseline trap and throw messages; library-profile tests cover the remediations round-trip and the reserved-byte refusals.
- The executable lane is untouched: every change sits behind SCR_LIB or the library emission path, verified by byte-identical executable binaries on both backends before and after.
- `o[k] = v` whose key identifier's type proves one literal — a keyof-bound parameter inside a generic instance, or a literal-typed const — lowers to a static field write, mirroring the read side.
- Literal-UNION keys keep the fence (a runtime-keyed write needs an index signature), with the instantiation context naming the binding.
- Fixture 2555 (writes, read-modify-write, literal-typed key consts, per-literal swaps), byte-identical vs Node on both backends.
- Nested patterns and member targets in assignment position, with JS's reference-before-value evaluation order pinned
- Class-instance sources call getters exactly once per element; a latent double-call in the accessor-default path is fixed
- Class rest packs the inheritance chain in Node's key order, fencing where enumeration can't be reproduced
- Fixtures 2536-2540 for the promotions; 2530-2535 and 2541 pin the already-static declaration-position surface
# Conflicts:
# packages/compiler/test/ts7/baselines/order-parity.json
- 2530-2535 and 2541 lock in the destructuring forms the static tier already compiled but the corpus never pinned: object/array/tuple declarations (renames, defaults, holes, nesting, fresh rest tails), the options-object parameter pattern (element and whole-pattern defaults, tuple/rest parameter patterns), for-of heads (containers, defaults, rest, existing bindings), object rest freshness and key order, assignment basics (swaps, chains, expression value), and evaluation order (RHS once, elements left to right, lazy defaults that see earlier bindings).
- All byte-identical against Node under both backends, and each reports 100% static coverage.
- Destructuring assignment now takes nested patterns (`({ p: { q } } = src)`, `[[a], b] = t`) and property/element targets (`[c.x, box.vals[i]] = arr`, `({ a: rec.f } = o)`, rest into members) — receivers temp at their pattern position, JS's reference-before-read order; defaults on member targets test against the target's own type. Defaults on nested targets keep a named fence (no single binding type to test against).
- Class instances destructure in assignment position like they already did in declarations: field slots and getter calls per element via the same fieldGetExpr dispatch, defaults, renames, and member targets; methods and undeclared names keep their pointed fences.
- Rest over class-instance sources packs the remaining instance FIELDS into a fresh record (JS's CopyDataProperties copies own enumerable properties — never prototype methods/accessors, matching the checker's rest type), in declarations and assignments; non-public fields, runtime-provided chains (Error/EventEmitter/stream), and key orders the packed shape cannot reproduce fence instead of diverging.
- Defaults on destructured getter results now lower (record and class accessors alike), with the getter result temped so the default's undefined test never calls it twice; numeric-literal pattern keys (`const { 2: x } = o`) fold to JS's canonical property name.
- Corpus 2536-2540 pin the new forms byte-identically against Node on both backends; the destructuring-fences diagnostics program keeps the honest residue (method extraction, non-public rest fields, nested-target defaults, index-signature rest).
- The ts7 order-parity baseline re-record backfills the entries the released file was missing (2490-2500 included) alongside the new fixtures; no existing entry changed.
- `const g: Mapper = (x) => x` under `type Mapper = <T>(x: T) => T` (aliases and inline generic function types alike) registers like `const g = <T>(x: T) => x`: the type parameters come off the annotation's one call signature, whose symbols are exactly what the checker types the initializer's parameters by (bindingContextualGenericFnNodeOf).
- Function-expression initializers, pinned-value uses, aliases of the annotated binding, and multi-parameter signatures with generic callbacks all ride the existing instance table.
- The SC2001 generic-signature message now names every binding shape that monomorphizes; escapes with no statically enumerable instantiations (generic-signature parameters, stored results) keep the fence with that precise wording.
- Fixtures 2553 (alias and inline annotations, function expressions, pinned values) and 2554 (keyof + aliases + signature bindings + interface methods composing), byte-identical vs Node on both backends.
- `const r: Repo = new MemRepo()` over an interface whose every member is a generic-callable method keeps the initializer's CLASS representation (genericIfaceBindingKeepsClass): the record shape maps empty — generic members are excluded — so the width copy would drop the class the calls dispatch against, and in JS the binding IS the instance.
- Calls like `r.get(...)` resolve through exactInstanceClassOf to a class generic-method call on the exact class: `this` works, state mutates on the one real instance, and record-typed USES width-coerce at the use site instead of the declaration.
- Receivers with no provable class (parameters, `let`, produced values) keep the fence, now naming the actual blocker: static dispatch needs a const bound to its `new` expression.
- Fixture 2552 (stateful implementations, two classes, block scope, casts back to the class, record-typed uses), byte-identical vs Node on both backends.
- Instantiations carry ts-level bindings alongside the mapped IrTypes: a `K extends keyof T` parameter keys its instance on the bound literal (no cross-literal sharing — the bodies read different fields), and literals forward through generic-to-generic calls.
- `T[K]` inside instance bodies resolves through the bound checker types (mapBoundIndexedAccess via the new resolveTypeParamTs hook), and `o[k]` reads whose key TYPE proves one literal — a keyof-bound parameter or a literal-typed const — lower to static field reads.
- `const h = id` registers the target's GenericFnInfo under the alias's symbol (chains, block scope, pinned values, and calls all resolve like the target's own name); non-const/reassigned aliases fence by name, and unpinned VALUE uses keep their fence at the reference.
- Fixtures 2550 (keyof/pick shapes, forwarding, runtime keys, literal-typed key vars) and 2551 (alias chains, contextual pinning, annotated generic aliases), byte-identical vs Node on both backends.
- SC2005 generic call signatures, SC2006 index-signature shapes, SC2007 overloads, SC2008 unresolved intersections, SC2009 supported shapes over an unsupported component with the component named
- Stdlib nominal types reroute to the SC2020 story instead of a duplicate code
- SC2001 keeps only bigint/symbol, constructor objects, and unresolved library generics — its registry name now says so
- Five new diagnostics programs pin one frame per code; manifest entries added; zero behavior change to accepted programs
# Conflicts:
# tests/harness/__snapshots__/regex.ts.txt
- X.#m() calls, const-bound class expressions, decorated names, and const aliases all reach static #private members when the receiver provably holds the declaring class
- The write path's exactClassOfReceiver and leaf-class rules extend to the call and read paths through one shared predicate
- Slots that can hold a descendant still fence; the read path gains the subclass-spelling fence the other paths had
- Fixtures 2520-2523 on both backends
- tsc's evolving-array analysis answers the pushed element type at later call sites; the monomorphizer trusted it while the receiver value lowered as array<jsval>, producing an ill-typed call the validator rejected
- The receiver value's element type now wins across the array method family, riding the explicit-any[] handle path; unannotated locals and file-scope aliases adopt the same spelling
- .find on handle-element arrays fences honestly instead of ICEing
- Fixtures 2510-2513 under --dynamic, byte-identical on both backends
- T[K] indexed access resolves against instantiations; Object.hasOwn/assign on records and DOM values; runtime-keyed writes to fixed shapes with a key-miss trap
- Regex union arms with instanceof RegExp as the tag test; string | RegExp shapes map
- Island literals gain getters, spreads, and real TemplateStringsArray identity for tagged templates
- JS variadics under --dynamic bind the engine's arguments array; fn(...args) lowers to engine apply
- Fixtures 2470-2476 on both backends; SEMANTICS entries 385-390
# Conflicts:
# packages/compiler/src/frontend/types.ts
# packages/compiler/test/ts7/baselines/order-parity.json
- An evolving-any array (const fns = []; fns.push(() => 1)) lowers array<jsval> at its any[] declaration, but tsc's evolving-array analysis answers the pushed element type at later method calls, so the lowering handed monomorphized helpers a jsval-element receiver under a typed signature — the SC9001 validator ICE.
- lowerArrayMethodCall now adopts the receiver VALUE's element type when it is a jsval-element array, riding the explicit-any[] handle-element lowering; HOF callback lead params bind the handles via jsvalParamOverrides whatever the evolved contextual type spelled.
- Derived bindings keep the handle-element array instead of the evolved spelling: locals adopt the initializer's type in lowerVarDecl, and file-scope globals register the handle-element array for aliases and receiver-type-preserving chains (filter/slice/splice/concat) rooted at a registered one.
- concat over a handle-element receiver decides spread-vs-element by the argument VALUE's array-ness, exactly JS's IsArray, instead of the evolved checker spelling.
- Corpus fixtures 2510-2513 pin map, filter/forEach/some/every/findIndex, mixed push sites, and the slice/concat and function-scope derived shapes, byte-identical vs Node under --dynamic on both backends.
- New codes, minted in badType's classification order: SC2005 values whose type keeps a generic call signature, SC2006 index-signature shapes outside the supported set, SC2007 overloaded function types, SC2008 intersections with no resolved lowering, SC2009 supported container/function/record shapes over a component outside its slot — the SC2009 message names the offending component (Map/Set key-value domains, array/tuple elements, union arms, function rest/params/returns, record members) via describeComponentBlocker/describeRecordMemberBlocker in frontend/types.ts, which mirror mapType's own rules on the failure path only.
- Standard-library nominal types with no lowering at all (Date, ArrayBuffer, WeakMap, the iterator and constructor interfaces) now route to the existing SC2020 story instead of the supported-set recitation; stdlib provenance is checked after the container claims so Map/Set/Promise instantiation failures keep their component story.
- SC2001 keeps the honest remainder — bigint and symbol primitives, constructor objects, and library-derived or unresolved generic shapes — and its registry name now says so; across the diagnostics corpus its rendered sites drop from 57 to 5.
- Every new code flows through the diagnostics registry, the regenerated surface manifest, and coverage-report grouping; five new tests/diagnostics programs pin one rendered frame per code, and the ts7 order-parity baselines re-record to include them.
- Zero behavior change to accepted programs: the differential corpus (900 programs) is untouched and green, and the full suite passes.
- staticCallOn and lowerClassValueProperty fenced every #private static access with a through-a-VALUE receiver, so C.#m()/C.#f on a const-bound class expression, A.#f through a const alias of the class, and Example.#m() under a replacing decorator all died with SC1090 while the direct class-name spelling compiled.
- The static-WRITE path already knew the sound rule (exactClassOfReceiver plus the leaf-class arm); classValueIsExactlyOwn now shares it with the call and read paths: a receiver that provably IS the class, or a class with no strict descendants, always carries the declaring class's brand — the fence stays for slots a subclass can inhabit, where Node throws TypeError.
- Rebindable decorated names ride the leaf arm for free: replacement decorators fence any class with subclasses before minting the rebindable global, so the decoration result is always the declaring class object.
- The read path additionally gains the subclass-spelling fence (reading an inherited private static through a subclass-named binding) that the call and direct-read paths already had.
- Fixtures 2520-2523 pin the four call forms (class-name calls including static field initializers and subclassed declarers, const-bound class expressions with reads/writes/calls, decorated classes under both replacing and void decorators, aliased class values local/module/param) byte-identical vs Node on both backends; the private-members diagnostics fixture repins the residual fence on a descendant-capable slot.
- the mockImplementations body defers one statement in static builds (SC2011, never executed) — the @deferred-fences directive keeps the coverage sweep honest
- order-parity baselines re-record for corpus 2470-2476 (new fixtures only)
- regex.ts drops the RegExp | undefined fence (regex union arms compile)
- spread-fences.ts drops the optional-into-required SC2002 (the checked NARROW lift, divergence 38's stance: the flow traps at runtime where it used to fence at compile)
- LIB_FN_SYMS mapped net.{get,set}AutoSelTimeout to scr_net_{get,set}_auto_sel_timeout; the runtime defines autosel — every LLVM-tier program touching the surface died at link
- The ABI guard gains a table-existence audit: every scr_* string the backend sources can emit must exist in scr_runtime.h as a prototype or extern data symbol
- Fixture 2500 exercises the surface differentially on both backends
- LIB_FN_SYMS mapped net.getAutoSelTimeout/setAutoSelTimeout to scr_net_get_auto_sel_timeout/scr_net_set_auto_sel_timeout, but the runtime defines scr_net_get_autosel_timeout/scr_net_set_autosel_timeout (the C backend already used the correct spelling), so any program touching net.getDefaultAutoSelectFamilyAttemptTimeout on the LLVM tier died at link with undefined symbols.
- The ABI guard could not see this: the literal-declare source scan only checks fully-literal declare strings, and the emitted scan's corpus slice never exercises the net autosel surface — a table entry whose fixture doesn't exist was invisible from both directions.
- llvm-runtime-abi.test.ts grows a third, table-driven direction: every scr_* name the backend sources can ever emit — the static string tables plus every literal @scr_* template reference (interpolated per-type families excluded) — must exist in scr_runtime.h as a prototype or extern data symbol, so a two-string name skew now fails at test time instead of at the user's link step.
- parseHeader additionally collects extern data symbols (scr_emitter_vt, scr_error_vts) so vtable-global references audit cleanly.
- New corpus fixture 2500-net-autosel-timeout.ts round-trips the default attempt timeout (set then get, integers >= 10 to stay clear of Node's clamp) and is byte-identical vs Node through both backends.
- The synthesized-name pattern is two-part: container helpers, member the helper's own name — no _return suffix
- Parameter synthesis (helpers_<name>_<param>) is unchanged
- A contract fixture helper with an inline-record return pins the spelling on both emissions
- The return shapeRef now seeds container 'helpers' with the helper name as the member, so an inline-record helper return tables helpers_<name> instead of helpers_<name>_return; parameter naming (helpers_<name>_<param>) is unchanged
- The contract fixture gains 'extent', a helper returning an inline record, pinning the synthesized name helpers_extent in the type table and the value-kind helper return with the arena bit
- The anti-alphabetical suite asserts the new struct entry and helper row on both emissions; V13 byte-determinism stays green
- T[K] resolves against record bindings, Object.hasOwn/assign lower over records and the DOM, fixed shapes take runtime-keyed writes with the miss trap, and string|RegExp unions narrow by instanceof
- the width family gains the checked NARROW lift and the tuple-arm literal route (the option-table shapes)
- island literals complete: get accessors, plain spreads, tagged templates with .raw, jsval ??, and call-time fence deferral for unlowerable members (lambda poisons defer too)
- JS variadic rests under --dynamic bind the engine arguments array and re-invoke through apply; dyn values marshal into the island as the deep copy
- corpus 2470-2476 pin every landing against the Node oracle on both backends
- All twenty schema fields: declaration-ordered type tables, wyhash-64 build_id, descriptor families
- Deterministic byte-equal emission on both backends, validated against rules V1-V14
- Identity getters synthesize as constants: pre-init and post-poison reads match the sidecar
- A computed determinism attestation from a conservative ambient-surface scan