Commit Graph
207 Commits
Author SHA1 Message Date
Chris Tate 124ea659ec fix(test): preserve POSIX sandbox workspace paths
- Keep remote workspace reset paths POSIX across host platforms.

- Add targeted Windows CI coverage for Sandbox preparation.
2026-07-28 20:07:34 -05:00
Chris Tate 3487b26d38 fix(test): isolate sandbox scheduling and cleanup
- Clear inherited scheduler controls outside intentional shards.

- Bound Sandbox removal and escalate stalled CLI termination.
2026-07-28 19:18:06 -05:00
Chris Tate 6886bcf24b fix(test): load sandbox runner settings from local env
- Load .env.local before capturing runner tuning values.

- Cover configured values and documented defaults.
2026-07-28 19:00:04 -05:00
Chris Tate 680dbfe458 fix(test): isolate sandbox sanitizer lanes
- Pin sanitizer state for every local and remote lane.

- Cover inherited environment overrides with a regression test.
2026-07-28 18:43:53 -05:00
Chris Tate 297c68125c Preserve sandbox gate coverage and worktree fidelity
- Run host artifact and ASan contracts on supported platforms with a Sandbox fallback.
- Clear image-seeded workspace files before extracting the dirty worktree.
- Pin current Linux artifact size classes and regression coverage.
2026-07-28 18:27:28 -05:00
Chris Tate 177d025452 Harden sandbox gate across host platforms
- Retain representative Darwin kqueue coverage in the default gate.
- Schedule native runtime tests by host and make Linux clang invocations portable.
- Resolve canonical OCI manifest digests for direct and indexed images.
2026-07-28 17:48:17 -05:00
Chris Tate 61d399bb7a Fix sandbox gate coverage and isolation 2026-07-28 15:36:19 -05:00
Chris Tate a504ccb850 Cut full sandbox validation to four minutes
- Shard portable coverage across 16 sandboxes while retaining focused Darwin contracts.

- Run invariant suites once and keep differential and sanitizer-sensitive coverage in both lanes.

- Harden sandbox transport, exit-status parsing, and Linux runtime test portability.
2026-07-28 14:58:34 -05:00
Chris Tate 81091a1a49 Preserve effectful toFixed defaults
- Evaluate undefined precision expressions before substituting zero.
- Cover effectful optional precision with a differential corpus case.
2026-07-26 21:21:07 -05:00
Chris Tate a3a5863cca fix optional toFixed lowering 2026-07-26 19:50:06 -05:00
Chris Tate bc2cd2b7d1 Support Number.toFixed statically
- Lower Number.prototype.toFixed through the compiler IR and native backends.
- Match JavaScript rounding, range errors, and numeric edge cases in the runtime.
- Add differential coverage and update surface metadata and diagnostics.
2026-07-26 18:43:53 -05:00
Chris Tate 481dd9c974 fix: flush console output promptly
- Submit console, process, readline, and island writes before returning.
- Add live-pipe and SIGKILL parity coverage against Node 24.
2026-07-26 01:30:42 -05:00
Chris Tate 1a5bc86bc9 fix: harden outbound FFI validation 2026-07-25 11:52:55 -05:00
Chris Tate 2098e0df6d fix: validate unused FFI bindings 2026-07-25 10:57:54 -05:00
Chris Tate bed63d3223 feat: add outbound native FFI
- Add a strict versioned manifest and direct C ABI lowering for both backends.
- Link declared native inputs through the CLI and compiler APIs with precise diagnostics.
- Cover the ABI under plain and sanitized integration tests and document its contracts.
2026-07-25 09:56:48 -05:00
Chris Tate a7538fd87d URL-string and URL-object arguments to the http and https clients
- `http.get("http://host/path")` and its https spelling now compile. The declarations only described the options-record form, so the first thing a from-scratch client writes was a type error — the shape worked under --dynamic, where the engine does not consult our declarations, which is how it read as a hello-world failure.
- A URL object is accepted the same way, as its href through the same parse. An unparsable input is the WHATWG "Invalid URL" TypeError and a scheme that is not the calling module's is ERR_INVALID_PROTOCOL, both catchable, matching Node rather than silently upgrading the dial.
- `request` and `get` take one signature with a union first parameter instead of Node's two overloads: `tls ? https.request : http.request` unions two function types, and resolving a call on that union collapses each side to a single signature, so an overload set misresolves in either declaration order. The lowering dispatches on the argument's own type.
- Both rows run on the LLVM backend, and the tls CA-store entries joined it too — the omission there was stale, so 2557-tls-ca-store moved off the C lane with identical output.
- Corpus 2644 and 2645 cover both schemes against loopback servers, so neither needs the network.
2026-07-24 23:24:53 -05:00
Chris Tate 6345fabfcb Retag || on the truthy side instead of coercing the left
- tsc builds `u || d`'s result by DROPPING the left's falsy arms (`process.env.X || null` is `string | null`, `|| 3000` is `string | number`), so coercing the left into that result before the truthiness test retags an arm the test is about to rule out — and threw where Node yields the default.
- `orDefault` gains an optional `retag`: the truthy side hands the whole left box to a union→union helper whose stranded-arm throw is unreachable by construction, since truthiness has already ruled those arms out. Left evaluates once, right stays lazy, arm count is free.
- A ternary in logical-left position no longer adopts its contextual union over its own, for the same reason the eager coercion was wrong: tsc's assignability proof does not hold for that operand. Narrow to the union choice — contextual array element typing and the unmappable-own rescue are untouched.
- 2595 chained its two in-flight `fs.exists` stats: registering both after the awaited rejections orders them against the rejections, not against each other, and Node itself returns them reversed about one run in forty.
2026-07-24 21:15:53 -05:00
Chris Tate abdf858f5a Fence the CA store and record the two lanes' order baselines
- The CA-store surfaces (tlsca.get/root/set) demote the determinism attestation but no fence could deny them: three AMBIENT_SURFACE_FNS rows, one per Node spelling. Split rather than folded into a single "CA store" surface — an author who denies REPLACING the trust anchors is making a different decision from one who denies reading them, and rootCertificates is a value read with no call form to hang a table row on.
- The parity test's full-fence declaration set names the new node-builtin.tls. family; surface-manifest.json regenerated.
- Order-parity baselines for the seven fixtures the two lanes added (2556-2558, 2582-2585). Pure insertions: no recorded baseline moved.
2026-07-24 20:15:42 -05:00
Chris Tate 44d05d8e74 Route the compiler's dyn world onto the engine's own operations
- Island values held in `unknown` arm the routed operation set (SCR_DYN_JSVAL): keyed reads and writes, calls and method dispatch, Object statics, and `??` all run in the engine, so a wrapped value answers exactly what Node answers instead of meeting a fence.
- Scalars normalize at the wrap, composites stay engine values by reference, and the round trip preserves identity — a value that crosses into the checked-dynamic tree and back is the same engine value.
- deepStrictEqual over a mixed engine-vs-native pair fails with the reason stated rather than guessing at an answer.
- Corpus 2582–2585 and an npm routed-row fixture pin the behavior; the dyncheck expectations move with it.
- The retired "DOM" nickname is swept out of the sources and corpus in the same pass (29 comment sites) — the world is the checked-dynamic tree, its values are dyn values.
2026-07-24 19:53:10 -05:00
Chris Tate 27e7537cec Crypto introspection, the TLS CA store, and the http2/rejection tail
- The crypto introspection statics (getFips and the cipher/hash/curve name lists) bake at the call site, and the crypto constant table joins http2's under a generalized per-module baked-constants lowering.
- The CA-store introspection surface lands in its own unit (scr_tls_ca.c) behind its own link gate, so a getCACertificates-only binary never pulls mbedTLS: getCACertificates, rootCertificates, setDefaultCACertificates.
- http2.createSecureServer grows the eager request handler and the runtime options record, riding the same server-options walk as tls.createServer; string-typed 'data' listeners decode.
- process once/off for 'unhandledRejection' plus the sibling 'rejectionHandled' registry, removal by closure identity per the warning-registry stance.
- Merge resolution unions this lane with main's fs ladders, createRequire erasure, and dyn secure-context work; the runtime's retired "DOM" nickname is spelled "dyn" throughout.
2026-07-24 19:49:54 -05:00
Chris Tate ebba5fcea9 Regenerate options-record diagnostics snapshot
- Record the merged Agent lowering diagnostics exactly
2026-07-24 19:04:09 -05:00
Chris Tate 91770d59d1 Cross-target library conformance
- Include the Windows runtime unit in library archives
- Add opt-in library target-matrix conformance coverage
- Exercise both emission paths across supported desktop targets
2026-07-24 18:52:29 -05:00
Chris Tate 2c0f01ad93 HTTP Agent and dynamic-handle compatibility
- Add Agent connection accounting and HTTP/socket compatibility surfaces
- Support dynamic Buffer at and slice access
- Pin behavior with differential corpus coverage
2026-07-24 18:52:19 -05:00
Chris Tate 9ac1d1ea6b Cross-target conformance lane for library mode (SCRIPTC_CROSS=1)
- Every K-fixture library profile cross-builds through compileLibrary for aarch64-linux-gnu.2.36, x86_64-linux-gnu.2.36, x86_64-windows-gnu, and x86_64-macos, both emissions — 112 archives, ~2min warm, which plus the hard zig requirement is why the lane is env-gated like its linux/windows siblings
- Per archive on the host: K1 symbol exactness against the profile's declared set (Apple's nm is llvm-nm and reads ELF/COFF/Mach-O alike; Mach-O's underscore is the only decoration), the K8 ambient audit in bare and COFF-dllimport spellings, and probe LINKABILITY against the target's libc plus the documented win32 embedder libs
- K2 execution probes ride the existing infrastructure gates: SCRIPTC_LINUX=1 runs the scalar round-trip per linux triple in the bookworm container, SCRIPTC_WIN=1 ships it to the box over scp and folds the mingw CRT's text-mode CRLF back on that one leg
- x86_64-macos stays build-only by contract; the probe runs as a bonus when Rosetta is detected
- README documents the fifth lane beside the linux/windows differentials
2026-07-24 18:22:45 -05:00
Chris Tate b3752bb181 Integer attestations keep their declared class; model-slot writes enter the boundary check
- integer_slots records u64 as u64: the wire flattening narrows to the frozen TypeRef spellings where it belongs
- Declaring any integer slot force-lowers the designated init, update, and subscription exports, so every model-field write proves or refuses like an export slot; declared field reads seed their class shapes
- Export integer classes stay attested by the emitted C signature under the same gate — the sidecar list is the document-side complement, and its refusal message now says so
2026-07-24 18:00:49 -05:00
Chris Tate 5e5d5bf8a9 Record declared u64 classes in the sidecar attestation and prove model/msg slot writes
- integer_slots now records each slot's DECLARED class ({i64, u64}); the i64 flattening narrows to the frozen format-1 TypeRef/descriptor spellings where unsigned-ness genuinely has no vocabulary, and the V1 self-check accepts both classes
- library builds declaring sidecar integer slots force-lower the designated init/update/subscriptions exports and every model-first contract helper, so record-field and msg-arm writes enter the prove-or-refuse boundary check instead of attesting from dead-stripped vacuity
- declared record-field reads seed their class shape (whole, class range), the assumption side of the slot contract: an unguarded counter increment now refuses RANGE with the teaching triple rather than a spurious may-be-NaN wholeness complaint
- profile-export param/return classes stay out of integer_slots by design — the attestation mirrors the document's own i64-spelled slots (the V10 bijection; abi.exports carries no TypeRefs) while an export's class is attested by the artifact's C signature under the same gate; the unconsumed-path refusal teaches this
- regressions added: u64 attests u64 while the TypeRef spells i64, unproven update writes into a declared model field refuse SC4022/SC4023 by slot path, and guarded writes prove and attest
2026-07-24 17:56:59 -05:00
Chris Tate d1192f3785 2470's deferred fence is cured: the general for-of lowering claims its table loop 2026-07-24 17:56:17 -05:00
Chris Tate 6c4430e0de Bare 'module' resolves the builtin like node:module
- Node serves the builtin for both spellings, so both key the same lowering tables; the stale prefix-only caution predated the createRequire erasure
2026-07-24 17:18:36 -05:00
Chris Tate de37b09716 Trap-claim carve-outs restore two over-narrowed shapes; extending a poisoned base refuses at build time
- The written-binding decline yields when the declared type has no mapping or the write's RHS roots at an ambient-undefined name
- A class extending a collection-poisoned base flushes the base's diagnostics eagerly: the heritage evaluates at module init, so deferring the compiler's own fence manufactured a silent wrong output
2026-07-24 17:18:25 -05:00
Chris Tate 6388ffdd52 pipeline argument ladders throw Node's errors instead of escaping the internal marker
- Both pipeline lowerings catch the arg-type marker the finished paths already caught; provably-invalid stages throw Node's synchronous ERR_INVALID_ARG_TYPE in every position
- Accepted-but-unlowered sources fence naming what Node accepts; finished(null) joins the isNodeStream ladder
2026-07-24 17:17:15 -05:00
Chris Tate e947502af6 The long tail of engine-held values: iteration, promises crossing, and the driver through its plugin pipeline
- for-of, destructuring, and spread over engine-held dyn values ride the engine's own iterator protocol with V8's exact non-iterable spellings; for-of over dyn lowers generally
- Static promises cross into the engine as thenables; Promise.all over mixed and non-literal entries runs the engine's own combinator; engine-array fulfillments exit by reference
- The re-minted silent-wrong-answer path is closed: island-literal members whose values poison fence at the read with the captured diagnostic
- The checked-dynamic tree replaces the old nickname across comments and internal docs
2026-07-24 17:17:00 -05:00
Chris Tate ad3a7a830b Bare 'module' resolves the builtin like node:module
- Node serves the builtin for both spellings — a builtin wins over a same-named npm package for the bare specifier — so both key the same lowering tables
- The stale prefix-only caution predated the createRequire erasure; the hint's claim and the behavior now agree
2026-07-24 15:25:47 -05:00
Chris Tate a7cd284944 Trap claims survive writes storage cannot serve; extending a rejected base reports at compile time
- trapDeclRootOf's written-binding decline now requires a mappable declared type: ordinary storage only buys anything when it compiles — an unmappable recursive call shape traded the compiling no-storage trap for a guaranteed SC2009 on a value that never exists
- bindingEverWritten skips statement-position writes whose RHS chain roots at an ambient-undefined name: that statement IS the RHS root's throw (lowerExprStatement's first claim) and never touches the target's storage, so it cannot justify the decline
- A poisoned base a top-level class extends flushes its deferred diagnostics eagerly (collectClassShape): the heritage evaluates at module init and the base's fence is the compiler's own — Node defines the base fine — so the deferred trap compiled a binary that refused at startup where Node runs; leaf and derived-only poisoned classes keep the JS deferral
- Fixtures: corpus 2632 (unmappable written trap binding) and 2633 (ambient-rooted rewrite), diagnostics js-extends-poisoned-base (the eager report names the base's real blocker), errors.test pins for both deferral edges that must NOT report eagerly; order-parity baselines recorded for the new entries
2026-07-24 15:03:30 -05:00
Chris Tate 72ccd05c34 pipeline's stage ladder throws Node's body clause instead of crashing the compiler
- lowerStreamArg's arg-type marker escaped both pipeline lowerings uncaught (only finished caught it), so a compile-time non-stream stage — pipeline('', dst, cb) — crashed the CLI with a raw StreamArgTypeThrow; both pipeline paths now catch and answer it as the call's value, matching finished
- The ladder splits by API to match Node exactly: finished keeps the isNodeStream clause (null now included), while pipeline stages render makeAsyncIterable's "body" clause — the same text in source, middle, and destination positions — for numbers, booleans, null, and pair-less records
- Shapes Node accepts but scriptc can't lower yet never take a throw Node never throws: strings and arrays (iterables) and records carrying a readable/writable member (the duplex-pair form) keep the pointed fence, whose hint now names those inputs
- tests/corpus/2632-stream-pipeline-arg-ladders.cjs pins the ladder in all three positions plus finished(null) and a live pipe, byte-identical through both backends in the plain and sanitized lanes
2026-07-24 12:48:41 -05:00
Chris Tate 07c9a4128c node:stream/consumers compiles statically; createRequire erases to static requires
- text, json, and buffer settle real promises over the readable machinery with Node's settle timing and rejection set; arrayBuffer and blob fence with their representation reasons
- createRequire over this file's URL is compile-time plumbing: builtin specs become namespace imports, relative JSON bakes as validated documents, npm packages ride the require-condition graph, unresolvable names throw Node's catchable MODULE_NOT_FOUND
- module.builtinModules bakes as the compat target's exact list

# Conflicts:
#	packages/compiler/src/frontend/lowering/lower-modules.ts
#	packages/compiler/src/frontend/lowering/lowerer.ts
2026-07-24 12:13:08 -05:00
Chris Tate aac4f9390b Buffer views alias for real; stream ticks interleave with process.nextTick in Node's order
- Buffer slice and subarray become true aliasing views over the retained owner — mutating through a view was silently computing wrong bytes
- Each stream tick posts a one-to-one marker on the user tick queue, so stream emissions interleave with process.nextTick in enqueue order, Node's order by construction; the station remains for teardown
- Stream emitters model the pre-created event-key shape governing eventNames order; push honors defaultEncoding with Node's unknown-encoding errors

# Conflicts:
#	packages/compiler/test/ts7/baselines/order-parity.json
2026-07-24 12:11:31 -05:00
Chris Tate 794b35a26e Subclasses override emit in the forwarding shape, monomorphized per event
- The forwarding shape — emit(event, ...args) whose rest appears only as super.emit(event, ...args) — lowers per dispatching event as a real hierarchy method, vtable-participating
- error events keep the throw-when-unhandled path through overrides; super.emit resolves to the nearest override ancestor, JS's chain
- Receivers above every override route through interned instanceOf dispatch; other emitter members and stream-rooted classes keep their fences with reasons stated

# Conflicts:
#	packages/compiler/test/ts7/baselines/order-parity.json
2026-07-24 12:10:30 -05:00
Chris Tate 034195f588 Profile-declared integer boundary slots prove or refuse at compile time
- An interval-and-wholeness inference over the lowered IR proves integrality and range for every value reaching a declared i64/u64 slot, with loop-header widening precise enough that the bounded counter loop proves its exact range
- Refusals carry the slot path, the failed obligation with evidence, and the author's concrete fix as SC4021, SC4022, and SC4023
- Declared slots are both obligation and assumption: call sites check arguments, callee bodies assume their classes; integer returns emit exact machine-integer wrappers and inbound params trap through the structured host-contract family
- Math.trunc and Math.ceil compile statically

# Conflicts:
#	packages/compiler/src/library/profile.ts
2026-07-24 12:07:29 -05:00
Chris Tate 328ccffbc8 The fence taxonomy covers the attestation's ground; profile roots refuse unknown keys
- Twenty-four manifest ids project the Date, performance, and process ambient families, so full fences are declarable and the determinism invariant is structural
- Six scan corrections: live ambient reads the attestation missed now demote, with paired fenceable ids; a parity test enforces the pairing permanently
- Unknown profile root keys refuse; ask-5 keys at the root get the relocation message
2026-07-24 12:06:37 -05:00
Chris Tate 092220ec51 Collect-phase probes recover from poison; no-storage bindings claim statement declarators only
- The ambient-trap probe resolves as a side-effect-free probe: deferred collection diagnostics stay deferred, and the merged-namespace fence lands as a diagnostic instead of crashing the collect walk
- deadUnmappableBinding and the nullish family claim statement-position declarators only; for-init heads and catch bindings stay locals
- Trap classification declines written bindings; the seven 0.0.10 pass-to-fail fences restore byte-identical to 0.0.9 behavior
2026-07-24 12:06:37 -05:00
Chris Tate f4206bd464 Restore the seven 0.0.10 pass-to-fail regressions by narrowing the ambient/nullish recognition
- ambientUndefVarRootOf resolves as a side-effect-free PROBE (the collect-phase guard): bare resolution flushed reached declarations' deferred collection diagnostics onto the build — failing three JS programs at compile time where the JS-input design defers fences to runtime (checkJsFiles_noErrorLocation, multipleDeclarations, jsdocTemplateClass), fencing tsxDefaultImports' enum-carrying static field through an import alias, and double-reporting the checker-panic fixture — and threw the cross-block merged-namespace fence's PoisonError out of every probe site
- Trap classification declines WRITTEN bindings (trapDeclRootOf): the no-storage trap fenced later assignments ("assignment to 't1' (not a writable local or module global)", literalWideningWithCompoundLikeAssignments) where ordinary storage compiles them; the initializer read still lowers to the root's ReferenceError, so the writes never run either way
- The nullish no-storage family claims only the EMPTY interned record shape: a field-bearing record binding (`const value: { inner: number | string } = null as any`) keeps real storage — its comma-chain and call-argument reads have no no-storage lowering (narrowCommaOperatorNestedWithinLHS, varianceProblingAndZeroOrderIndexSignatureRelationsAlign)
- classFieldSuperAccessibleJs2 reverts with the shared mechanism to its 0.0.9 state: the build passes and the binary still refuses at runtime with the same SC1090 (the honest JS runtime fence, not silent wrong output)
- Fixtures: corpus 2609 (trap binding with later writes), 2610 (field-bearing nullish record), 2611 (JS deferred-collection probe), 2612 (enum static field through a default import); checker-panic-infinity snapshot returns to its single pre-0.0.10 report
2026-07-24 11:57:39 -05:00
Chris Tate 96ca45081d Drop an unused eslint directive in the ask-4 suite 2026-07-24 11:52:54 -05:00
Chris Tate 2c8e31b1ff Rendered snapshots for the integer-boundary refusal codes; dynamic-surface fixture re-based
- library-int suite snapshots SC4021/SC4022/SC4023 rendered end to end (slot path, evidence, span, fix) — the diagnostics-corpus discipline for codes the executable lane cannot reach
- dynamic-surface diagnostics fixture swaps Math.ceil for Math.sqrt (trunc/ceil compile statically now) and its snapshot regenerates
2026-07-24 11:52:12 -05:00
Chris Tate 01b47dd78b Promise.all over non-literal 'any[]' arguments runs engine-side; island values bridge into Promise-typed slots with the any[] settle payload
- The loadPlugins shape end-to-end: Promise.all(plugins.map((p) => loadPlugin(p))) — a NON-literal argument the checker spells any[] — lowers to the ENGINE's own Promise.all over the lifted array, and the INFERRED Promise<any[]> return coerces through the island→static promise bridge with the new SCR_ISLP_JSVAL_ARR settle payload: the fulfillment exits Array.isArray-gated BY REFERENCE at the settle, a lying fulfillment rejecting with the boundary TypeError (trust-but-verify at the settle).
- coerceToExpected's jsval branch gains the promise-slot arm generally: island values flowing into Promise<void>/Promise<any>/Promise<any[]>-typed slots bridge instead of fencing (the passing-a-package-promise-into-promise-typed-parameters fence retires for these inners); other inners keep the named fence.
- Corpus 2605 extended with the non-literal all + inferred-return rows, byte-identical to Node under both backends and SAN-clean; dyncheck/errors/island suites green.
2026-07-24 11:51:34 -05:00
Chris Tate a2c68beadb The ask-4 conformance corpus end to end, with the sidecar attestation and inbound-trap fixtures
- tests/harness/library-int.test.ts: all 16 reference-corpus cases as library fixtures on both emissions — send/sendU64 are profile-mapped exports with i64/u64 params, PROVE cases pin every crossed value against the Node oracle (the test process runs the same case source), the counter loop crosses 0..9 in order, REFUSE cases name obligation, slot path, and evidence
- int-returns fixture: i64/u64 returns cross as real int64_t/uint64_t (9007199254740991, -0 as 0, -7 % 3 as -1, ToUint32 max on a u64 slot)
- int-trap fixture: inbound integers past 2^53-1 deliver the structured SC4012 host-contract trap with profile teaching/remediation; in-range extremes convert exactly
- Sidecar slots: integer_slots attestation in declaration order, declared slots spelled i64 (V10 bijection validated), unproven writes refused by slot path (Msg.count, helpers.clampIdx.return), unresolvable and non-number declarations refused SC4009, teachings ride SC4022 as attributed notes
- Layer-1 differential: no Layer-1 representation exists (trivially unobservable); pinned consequence — f64-declared vs i64-declared builds cross byte-identical values
- Integer-declared helpers join libRoots so their attestation covers a compiled body, never a dead-stripped vacuity
2026-07-24 11:39:43 -05:00
Chris Tate 5950d3f12b Demote the live machine-state reads the attestation missed, each paired with a fenceable manifest id
- process.resourceUsage, cpuUsage/threadCpuUsage, constrainedMemory, and the stdio isTTY/columns reads are live ambient state the attestation attested past; their spellings now demote deterministic (flipped attestations are corrections), and each family projects a node-builtin.process.* manifest entry with a reach-witnessing detector, so the §4 invariant holds by construction.
- The dead process.memoryUsage prefix is gone from the scan table, replaced by a comment saying why nothing can match it (no lowering spells it) and what a future lowering owes the table and the projection.
- The parity test covers the new prefixes through the existing node-builtin.process. family fence; the resolve test pins the new ids in the family sweep, and a K14 case pins the teeth end to end: process.stdout.isTTY under the full-fence profile refuses SC4008 naming node-builtin.process.isTTY, both emissions.
- surface-manifest.json regenerated (6 new entries, 342 total).
2026-07-24 11:39:39 -05:00
Chris Tate 1c3324fb63 Fix both 0.0.10 crash sites: collect probes recover from poison, for-init declarators stay locals
- collectGlobals' trap/nullish/dead classification probes catch PoisonError per the per-probe recovery discipline: the cross-block merged-namespace SC1090 fence reached through the ambient-root walk recorded its diagnostic and then crashed the CLI mid-discovery (5 merged-namespace corpus tests, ice bucket)
- On a poisoned probe, JS files defer the recorded diagnostics to runtime fences (deferJsCollectionDiags) and the binding falls through to ordinary registration; the statement lowering re-fences at its own site
- The no-storage binding families (nullish, dead-unmappable) only claim statement-position declarators: an uninitialized for-init let (`for (let x; false;) {}`) was claimed as dead-unmappable, violating lowerVarDeclList's contract that a for-init declarator always lowers ("lowerer bug: for-init declarator resolved to a global", 2 corpus tests)
- Fixtures: corpus 2608 (for-init heads with the masking variants), diagnostics merged-namespace-collect-probe (the collection-reached fence stays an honest SC1090)
2026-07-24 11:38:39 -05:00
Chris Tate c1be329607 Static promises cross into the island as real engine thenables; Promise.all over mixed island/static entries runs the engine's own combinator
- jsvalIn (and the island-literal member path behind it) accepts STATIC promises whose fulfillment is in the reverse bridge's payload domain — void/number/boolean/string/'any', plus the NEW Promise<any[]> payload (SCR_ISLP_JSVAL_ARR: a native array of engine cells re-enters as a fresh engine array over the SAME engine values). scr_jsval_from_promise emits from jsMarshal in both backends; the IR validator admits the arm.
- Promise.all with MIXED entries where some entry is an island value (the withPlugins shape: Promise.all([loadBuiltinPlugins(), loadPlugins(plugins)])) lowers to the ENGINE's own Promise.all — island entries pass through, static promises bridge as thenables, and the combined result stays an island value the static side awaits through the existing island→static bridge. All-static tuples keep the typed fence hint.
- Corpus 2605 (unawaited static promise in an 'any' slot answers typeof "object" and awaits engine-side; the mixed-all + .flat() chain) is byte-identical to Node under both backends; SAN clean. Composite fulfillments (Promise<{...}[]>) stay fenced with the promise type named — the payload-domain residue.
2026-07-24 11:32:57 -05:00
Chris Tate 10696c70f8 Profile-declared i64/u64 integer slots: surface, wiring, wrappers, host-contract trap
- LIB_PARAM_CLASSES/LIB_RETURN_CLASSES grow i64/u64 (the prove-or-refuse pair); u8/u32/i32 stay param-only with the message updated to point at the landed machinery
- sidecar.integer_slots declares contract slots by sidecar path (Msg.count, Point.x, helpers.f.params[0], helpers.f.return); the projection spells each declared slot i64 (the frozen format-1 vocabulary — u64 is the stricter compile-time obligation over the same wire spelling), refuses non-number or unresolvable paths, and emits integer_slots as the resolved-decision attestation in declaration order
- compileLibrary runs the integer-boundary inference over export-map and sidecar-declared slots and refuses SC4021 (representability) / SC4022 (wholeness) / SC4023 (range), each carrying slot path, failed obligation with evidence, and the author's fix; u8/u32/i32 plumbing classes seed parameter shapes for free precision
- Both emitters grow i64/u64 wrappers: inbound params range-check through scr_library_i64_in/u64_in (the SC4012 host-contract trap — silent rounding past 2^53 is a coercion the author never wrote), returns convert exactly under the discharged proof
- Profile-loader suite pins the new surface; the pre-ask-4 pins updated
2026-07-24 11:29:30 -05:00
Chris Tate fe40a0f904 Refuse unknown profile root keys: a fences array pasted at the root was silently inert
- The ask-5 keys (fences/teachings/remediations) at the profile root refuse SC4001 with a pointer to their determinism.* home; every other unknown root key refuses with the standard unknown-field wording.
- The root goes strict everywhere, not just for the three ask-5 names: profiles pin per compiler release, so an unknown root key is a typo or a misplaced section (a misspelled sidecar would silently drop the contract), never forward-compat surface. All fixture and harness profiles load unchanged under the strict root.
- The check runs after the profile_format gate so a future format still refuses as the wrong format, and the interior of determinism keeps its reserved-and-ignored surface beyond the three ask-5 keys, both pinned by tests.
2026-07-24 11:26:34 -05:00