Skip to content

Node parity: compile the apps the island scorecard refused - #3052

Merged
ctate merged 4 commits into
mainfrom
ctate/node-parity-compile-edf187
Nov 7, 2026
Merged

ctate merged 4 commits into
mainfrom
ctate/node-parity-compile-edf187

Conversation

@ctate

@ctate ctate commented Nov 5, 2026

Copy link
Copy Markdown
Collaborator
  • A refused package only a Node island imports (mocha, hapi, express, koa, and every app whose islands pulled in refused helpers): the island report decided every package with a reason was an island, even where native code never reached it, so a refused dependency of a package that already runs in an island got an island of its own and dragged its own dependencies with it. The report now decides from the packages native code reaches and carries the rest inside the island that loads them.
  • Values crossing an island boundary typed by a declaration package (ws, express, hapi): a value whose type comes from an @types package or from a payload union of copyable and native shapes crosses as a handle at the type the program observes, instead of being attributed to a package with no implementation or refused as non-copyable.
  • node_modules/.prisma (prisma): a dotted package directory is a package directory. Node's LOOKUP_PACKAGE_SCOPE stops at node_modules, growth resolves the directory the way require() does, a CJS barrel's export expression is a dependency edge, surplus arguments to a JavaScript-implemented callee evaluate and go unused, and a method call a class does not declare is a checked-dynamic read and call.

A checked conversion accepts an island handle. A record reads each field
through the handle, as Node reads a property; an array, tuple or
index-signature record takes a native view of the value, with the view
released at every exit. JSON.stringify, Object.keys and object spread and
rest read the island object's own enumerable properties in Node, so a
toJSON method, an accessor and a function-valued member keep their
meaning. A program without islands emits the same code as before.
@vercel

vercel Bot commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scriptc Ready Ready Preview, v0 Nov 7, 2026 6:43pm UTC

Comment thread packages/runtime/src/scr_json.c Resolved
@ctate
ctate merged commit d24d1d0 into main Nov 7, 2026
26 of 33 checks passed
@ctate
ctate deleted the ctate/node-parity-compile-edf187 branch November 7, 2026 18:46
cramforce added a commit that referenced this pull request Nov 7, 2026
No conflict.

Co-Authored-By: Claude Code <noreply@anthropic.com>
cramforce added a commit that referenced this pull request Nov 7, 2026
Main gained #3363 (the lifted-function guard's fix) and #3052. No conflict.

Co-Authored-By: Claude Code <noreply@anthropic.com>
cramforce added a commit that referenced this pull request Nov 7, 2026
…nd lists as main behaves

Main's island conformance list and value matrix were stale since #3052; #3367
regenerates both on main 293036c. The train merges its head (the same
commits) and takes both files as #3367 has them. The train's own entries
follow in the next commit.

Co-Authored-By: Claude Code <noreply@anthropic.com>
espetro pushed a commit to espetro/scriptc that referenced this pull request Nov 8, 2026
Main since the last merge: vercel-labs#3363 (the lifted-function index guard's fix)
and vercel-labs#3052. No conflict.

Co-Authored-By: Claude Code <noreply@anthropic.com>
espetro pushed a commit to espetro/scriptc that referenced this pull request Nov 8, 2026
No conflict. ScrNiDynOps follows main's order, with main's new is_array
(vercel-labs#3052) where main has it; the train's entries stay at the end.

Co-Authored-By: Claude Code <noreply@anthropic.com>
espetro pushed a commit to espetro/scriptc that referenced this pull request Nov 8, 2026
… main

Both lists were stale on main since vercel-labs#3052 (JSON.stringify walks island objects
and arrays; an object or array an island made converts into a native slot):
22 conformance entries and 111 of 239 matrix cells failed on plain main.

Regenerated on main 8dcab7f by each list's update mode, then both run in
check mode against the result (conformance 424 passed, 70 skipped; matrix 239
of 239).

Conformance, 84 entries to 68: 17 programs match Node now, 5 fail differently
(npm/zod4-record with zod in an island now prints a wrong line silently),
1 is new (npm/hidden-key-boundary, added by vercel-labs#3235 without its island way).
Matrix, per observation: 1,055 moved to a match, 326 moved to 'wrong' (286 of
them matched Node before). The PR lists them.

Co-Authored-By: Claude Code <noreply@anthropic.com>
espetro pushed a commit to espetro/scriptc that referenced this pull request Nov 8, 2026
… into train/islands-1

Main's island conformance list and value matrix as regenerated on main
293036c (stale since vercel-labs#3052; vercel-labs#3219 moved the matrix again). Both files are
taken as that branch has them; the train's own entries are regenerated on
top in the next commit. This brings main up to 293036c into the train.

Co-Authored-By: Claude Code <noreply@anthropic.com>
yowainwright pushed a commit to yowainwright/scriptc that referenced this pull request Nov 8, 2026
…SC6007)

Since vercel-labs#3052 a checked conversion accepts an object or array a Node island
made and builds a native value from its members; before, it threw
"expected array at $, got Object from a Node island". The copy is silent:
under Node the value is the island's own object, so the island's later
changes show through it, the program's writes reach the island and it is
=== to the island's object. The island value matrix has 299 such facts in
166 entries (identity lost, a write on either side not seen by the other,
members the target type does not declare dropped).

The divergence scan now reports each conversion the compiler can see as
SC6007, "island value crosses as a copy" (the code PR vercel-labs#3252 uses for island
arrays; the title is the general one the code registry names):

- an assertion whose operand is an island read or call, awaited or not, or
  a const of one, typed any, unknown or by the island (`make() as Item[]`);
- a typed binding of such a value (`const xs: number[] = anyList()`);
- a typed parameter of a callback passed to an island call, when the
  callback writes through the parameter or compares it;
- an island call declared to return a Map or Set whose key, value or
  element type is a native array or record (the collection stays the
  island's; each member read from it is converted).

A target that stays checked-dynamic (unknown, a record of unknown members,
a live view) keeps the island's object and reports nothing, as does a copy
the program writes (`structuredClone(value) as T`) and a value no island
made. The scan reads the syntax tree after lowering and adds no lowerer
state; no generated code changes.

Of the 299 facts, 298 are in a program that now gets the warning at the
conversion they sit behind; the one left is the identity of a nested
element read inside a callback. 44 sites in 20 of the matrix's 239
programs; none in a control program.

Co-Authored-By: Claude Code <noreply@anthropic.com>
yowainwright pushed a commit to yowainwright/scriptc that referenced this pull request Nov 9, 2026
Main's build fix for the stream source peel helper (vercel-labs#3364), vercel-labs#3363 and
vercel-labs#3052. Main at fffd053 did not build.

Co-Authored-By: Claude Code <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview — 6d0adf36 Deployed Nov 7, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant