- The tls server/secure-context walker validates every present typed option before the pem walk and its fences: the ciphers/passphrase/ecdhCurve string contracts, the engine trio's string-or-null-or-undefined clause, handshakeTimeout/sessionTimeout number contracts with validateInt32's exact range text, ticketKeys' view contract and exactly-48-bytes value ladder (Received renders the byte length, Node's shape), and minVersion/maxVersion's ERR_TLS_INVALID_PROTOCOL_VERSION with %j rendering. Literals carrying a validated key ride whole to the walker (JS sources), and createSecureContext gains the runtime-record form (tls.createSecureContextDyn) — a validated { cert, key } bag builds the real context.
- tls.connect validates checkServerIdentity's function contract with Node's presence semantics (a PRESENT key replaces the builtin verifier even holding undefined — the defaults spread); tls.getCACertificates walks validateString plus the documented name set before its fence.
- stream.finished/stream/promises.finished over a provably-non-stream value throw Node's isNodeStream ERR_INVALID_ARG_TYPE; socket write's two-argument encoding form implements the stream_base typecheck (write(string, 'buffer') is the synchronous "Second argument must be a buffer") with utf8 spellings as the plain write; Readable.toWeb's type option answers Node's one-of ladder.
- Unions with boxable FUNCTION arms now cross into the DOM (canConvertToDyn + both backends' union-to-dyn walkers) — the invalid-input probes iterate [1, null, () => {}, true]; scr_dyn_specific_type renders functions as Node's `function ${name}` (anonymous keeps the trailing space).
- Corpus 2581 (tls) and 2582 (stream, both backends) pin the ladders byte-identically vs Node.
- net.createServer with a provably-non-object argument, connect option bags (literal, computed-key, and runtime-record spellings) walking Node's Socket-constructor order — the objectMode trio's ERR_INVALID_ARG_VALUE, validatePort's ERR_SOCKET_BAD_PORT, host's string and autoSelectFamily's boolean contracts — and the autoSelectFamilyAttemptTimeout range ladder (validated and then inert, the single-dial simplification's sibling); setDefaultAutoSelectFamilyAttemptTimeout validates from 1 and keeps Node's sub-10ms floor.
- listen's and dgram.createSocket's options.signal answer validateAbortSignal's ERR_INVALID_ARG_TYPE for provably-non-AbortSignal values; plausible signals keep the fence (abort-driven close has no lowering yet).
- dgram.Socket.send replicates Node's signature shuffle over DOM arguments: slice type/bounds contracts (ERR_BUFFER_OUT_OF_BOUNDS over Buffers, subarrays, DataViews, and strings), the buffer-list per-element contract with the list as the Received tail, the unconnected port ladder with the specific-type tail and trailing period, the null/undefined-only address gate, and the connected-state ERR_SOCKET_DGRAM_IS_CONNECTED arms — a fully-validated unconnected single-payload send RUNS; callback/list/connected forms meet the post-validation fence. The dgram state errors now carry Node's ERR_SOCKET_* codes, and dgram bind/connect/close callbacks accept checked-dynamic wrappers through the dynCheck boundary.
- Corpus 2579 (net, both backends) and 2580 (dgram) pin the ladders byte-identically vs Node; order-parity baselines re-recorded.
- The checked-dynamic fs.*Chk lane (JS sources) replicates Node-order argument validation over DOM values: exists/mkdtemp/readFile callback contracts, mkdtemp's prefix slot, assertEncoding on readFile/opendirSync/stream options, watchFile's path/listener pair, createReadStream/createWriteStream's options.fd and path contracts, fs.read's buffer/fd/offset/length/position ladder, and the lchmod family's cb/path/mode ladder with parseFileMode's octal-string and uint32-range arms — each throwing Node's exact ERR_INVALID_ARG_TYPE / ERR_INVALID_ARG_VALUE / ERR_OUT_OF_RANGE texts.
- A validated pass meets the honest tail: the real operation where one exists — fs.exists is REAL now (async answers through the callback, Node's synchronous-false wart for unvalidatable paths kept), mkdtempSync runs through the ladder, lchmodSync/fsPromises.lchmod apply lchmod(2) on macOS and answer Node's not-a-function / ERR_METHOD_NOT_IMPLEMENTED shapes elsewhere — or the compiler-rendered SC2020 fence thrown AFTER validation (scr_throw_lowering_fence), so Node's errors always come first.
- error.propTypeThrow joins argTypeThrow as the property-flavored always-throwing lowered arm; scr_dyn_prop_type_fail / scr_dyn_arg_value_fail / scr_num_received become shared runtime vocabulary for the remaining option-bag ladders.
- Destructured sub-namespace bindings (const { promises } = fs) resolve as the module they are, so fs.promises members reach their lowerings through that spelling.
- Corpus 2578 pins the whole surface byte-identically on both backends; order-parity baselines re-recorded for the new fixture.
- Array patterns over strings split by code points via the string-iterator machinery: positions, holes, defaults, rest, nesting, and for-of heads
- Destructured stdlib-global members bind their builtin identity tokens with Node-agreeing === identity; aliases register the twin
- Surfaced-global members like Math.max fence eagerly by name — a token would quietly degrade them
- Object patterns over strings bind length; wrapper-method extraction names the detached method
# Conflicts:
# packages/compiler/test/ts7/baselines/order-parity.json
- assert-fences drops its non-literal expected-object pin (that form lowers now through the errValue key walk — corpus 2556 pins the behavior); the diagnostics snapshot re-records.
- order-parity baselines re-record for the five new corpus fixtures.
- Instance setMaxListeners over a non-number routes through the checked-dynamic ladder (emitter.setMaxChk): ERR_INVALID_ARG_TYPE with the rendered Received tail, the existing ERR_OUT_OF_RANGE range gate for numbers, and a well-typed dyn still applies.
- events.defaultMaxListeners is a real module property now: reads answer the process-wide default, writes (statement and expression position) validate through emitter.setDefaultMaxChk with Node's own message slot ("defaultMaxListeners"); the qualified static EventEmitter.setMaxListeners(n) shares the ladder under its "setMaxListeners" slot, and the per-target static form with a provably-non-emitter target throws ERR_INVALID_ARG_TYPE on "eventTargets".
- error.argTypeThrow joins error.nodeThrow as the generic always-throwing lowered arm whose Received tail renders at runtime.
- Corpus 2560 pins the ladders byte-identically on both backends.
- URL.revokeObjectURL() with no argument throws Node's ERR_MISSING_ARGS ('The "url" argument must be specified') — the check runs before any registry lookup, so the zero-argument contract is exact without blob machinery; the one-argument form and createObjectURL keep their fences.
- fs._toUnixTimestamp lowers over a DOM time value: numeric strings pass ToNumber's loose-equality gate, finite numbers pass (negatives answer now/1000, Node's shape), and everything else throws Node's exact ERR_INVALID_ARG_TYPE with the rendered Received tail.
- Corpus 2559 pins both ladders byte-identically on both backends.
- emitReadable_ clears emittedReadable AFTER the 'readable' emit and only when it really fired — a listener observes true during the pass, exactly Node's readable.js.
- read() clears the flag for absent sizes too (Node's `if (n !== 0)` sees NaN there); only read(0) leaves it standing.
- Corpus 2558 pins the lifecycle byte-identically on both backends. The suite's needReadable/resumeScheduled probes remain blocked by the documented stream-tick station divergence (stream ticks drain at the next checkpoint instead of interleaving the user nextTick queue), not by flag semantics.
- Array patterns over checker-typed string sources split once through %str.chars (code points, astral characters whole) and ride the array machinery — declarations, assignments, for-of heads in both declaration and expression position, and parameters; object patterns bind the wrapper's one own data property, length, with renames and dead defaults. Static builds claim exactly what staticStringPattern vets; every other string form keeps the engine gate, and --dynamic keeps the engine route wholesale.
- Object patterns over stdlib globals in JavaScript files bind MEMBER identity tokens (const { subtle } = globalThis.crypto, const { Console } = console — 27 of the node suite's 28 SC1031 first-blockers), so programs run past the destructure and each use meets its own per-site fence; globalThis members are provenance-vetted, bind the member global's own token, and register the stdlibGlobalAliasDecl twin, so surfaced members (Math) keep their receiver-keyed lowerings.
- Members of SURFACED globals (Math.max, process.env, console.log) fence eagerly by member and global name instead of degrading detached uses to quiet token reads, and IR-string sources the checker does not type as strings fence naming the checker's type, never the token's carrier.
- Corpus 2556-2558 pin the string forms and the token identity/truthiness/alias agreements under the Node oracle, byte-identical through both backends; errors.test.ts pins the surfaced-global fence and the lazy per-site token failure.
- order-parity baselines re-recorded additively: the new entries plus the 2510-2555 fixtures that landed without one.
- Method values through Function.prototype.call/apply with a receiver that is provably not a URLSearchParams throw ERR_INVALID_THIS ('Value of "this" must be of type URLSearchParams') — the brand check runs before any conversion; searchParams-typed and dyn receivers keep their existing paths.
- Too few arguments throw ERR_MISSING_ARGS with Node's per-method messages before any conversion (the WHATWG arity ladder).
- Name/value slots convert with ToPrimitive's string hint: statically-string args lower directly, symbols throw V8's 'Cannot convert a Symbol value to a string' TypeError, and every other value coerces through the DOM — a user toString/valueOf member is CALLED and its throw propagates (scr_dyn_string_coerce_js, the new dyn.toStringCoerce libCall); func-carrying records box just their toString member into a DOM carrier.
- error.nodeThrow is the new compiler-resolved Node-parity throw for always-throwing lowered arms (the global.undefRead polymorphic-result pattern), shared by these ladders and future ones.
- Corpus 2557 pins the whole surface byte-identically on both backends, including the stringifier's post-sort re-serialization.
- Upcasts reinterpret derived pointers as base structs, so one object's rc/vt header is legally accessed through two struct types only without TBAA
- clang -O2 elided refcount updates under the aliasing assumption, freeing objects still owned through a base-typed view; the LLVM lane emits no TBAA and was immune
- -fno-strict-aliasing lands on all three compile paths, the standard posture for refcounted-header C object systems
- The regression fixture SIGSEGVs without the flag
- Spread calls build one fresh argument array with JS's left-to-right evaluation, on both backends and under --dynamic, with V8's exact non-iterable TypeError texts
- Fence lambdas inside rest arrows spell the hidden rest slot, curing an ICE the destructuring promotions exposed
- The LLVM promise.reject lowering admits dyn reasons, mirroring the C backend and the IR contract
- pipeline and finished settle real promises over the existing watcher machinery, on both backends
- domain, v8, inspector, node:sqlite, and the underscore-prefixed internals each name why a compiled binary cannot provide them
- stream/web, the Console class, and dns/promises stay honest not-yets with documented paths
- The SC1010 hint gains stream/promises and the long-missing querystring
- The DataView setter family lands end-to-end; fresh ArrayBuffers erase into zero-filled typed-array views; resizable/shared surfaces fence by name
- Object.is compiles with the spec's SameValue across every kind, including union operands
- Composed en-US Intl.NumberFormat and toLocaleString print byte-exact through the Ryu digit core's shortest-round-trip rounding, 30k-double fuzz-verified; the rest of Intl fences by name with reasons
- DurationFormat deliberately fences: Node throws V8-internal Temporal errors with embedded source paths on plain inputs
# Conflicts:
# packages/compiler/test/ts7/baselines/order-parity.json
- Hybrid records width-coerce in both directions: declared fields copy off struct slots, overflow drops or carries per the target shape
- Per-field lifts cover unknown destinations, derived-to-base upcasts, and clean function adapters, composing recursively
- The overflow store admits func, Map, and Set values; the keyed-miss trap can now describe them (a C-backend ICE fixed)
- Every remaining width and index-signature fence names its first blocking rule
- 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.