@ai-ecoverse/slicc-kernel 1.135.3 → 1.135.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/driver-worker.js +16 -4
- package/dist/driver-worker.js.map +2 -2
- package/dist/kernel-worker.js +1 -1
- package/dist/node-driver-worker.js +18 -9
- package/dist/node-driver-worker.js.map +2 -2
- package/dist/node-process-worker.js +19 -10
- package/dist/node-process-worker.js.map +2 -2
- package/dist/node.js +1 -1
- package/dist/process-worker.js +17 -5
- package/dist/process-worker.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -531,9 +531,9 @@ The module's default export (or its `main` export) is called with a context and
|
|
|
531
531
|
|
|
532
532
|
A program that throws, or leaves an error or a rejected promise unhandled with no listener for it, ends with status 1 and the message on stderr; one whose module cannot be loaded, or exports no function, ends with 126. A write to a pipe whose reader is gone ends the program with 141, unless it ignores or catches `SIGPIPE` (an ignore inherited from its parent counts), in which case the write fails with `EPIPE`. Errors carry a POSIX `code`. Reads and writes of pipes, terminals and sockets go through the kernel's asynchronous operations, so a program blocked reading stdin can still write and handle signals; other calls of one process are made one at a time. A JS program cannot `fork`, and threads it starts itself are not the kernel's.
|
|
533
533
|
|
|
534
|
-
The module has the trust of an Emscripten program's glue or a WASI program's imports module: it comes from a package that was installed, and it runs in the worker of its own process. The kernel withholds the worker's own ways out before it loads the module: `XMLHttpRequest`, `WebSocketStream`, `WebTransport`, `EventSource`, `
|
|
534
|
+
The module has the trust of an Emscripten program's glue or a WASI program's imports module: it comes from a package that was installed, and it runs in the worker of its own process. The kernel withholds the worker's own ways out before it loads the module: `XMLHttpRequest`, `WebSocketStream`, `WebTransport`, `EventSource`, `indexedDB`, `caches`, `cookieStore`, `SharedWorker`, `close`, Chrome's old file system API (`webkitRequestFileSystem`, `webkitRequestFileSystemSync`, `webkitResolveLocalFileSystemURL` and `webkitResolveLocalFileSystemSyncURL`, which reach the origin's OPFS), and `navigator.storage`, `navigator.storageBuckets`, `navigator.locks`, `navigator.serviceWorker`, `navigator.usb`, `navigator.hid` and `navigator.serial` are `undefined`, also through their prototypes, and a worker where one of them cannot be removed refuses to run the program (126). `fetch`, `WebSocket`, `BroadcastChannel`, `importScripts`, `Worker` and `postMessage` are `undefined` too, but stay writable and configurable, so a program can install its own over `ctx.fetch` and `ctx.websocket`, a `BroadcastChannel` within the program (as slicc-jsh does), or the globals napi-rs's wasm32-wasi worker template assigns (`Object.assign(globalThis, { self, require, Worker, importScripts, postMessage })`); the worker's own are gone before the program runs, so deleting the program's brings back `undefined`. `self` stays the global, but as an own writable slot of the scope, so a program can assign its own (the template does) without reaching the worker's. The platform's `BroadcastChannel`, which would reach the origin's other contexts around the kernel, is gone from the scope and its prototypes before the program runs, so deleting the program's own brings back `undefined`, not it; a worker where it can't be removed refuses to run the program (126), as for the others. A program's files are the kernel's, through the context; it reaches the kernel only through its own process's system calls, as the context makes them, and no other process's. This is a guard against programs going around the kernel, not a sandbox: `import()` of a URL is a request the kernel cannot withhold. In a browser, every process worker gets the same lockdown before any program code runs, so an Emscripten program's glue and a WASI program's imports module (any user can write either) see the same globals `undefined`, and a worker where one cannot be removed ends the process with 126. Under the Node entry, every process worker gets the same lockdown before any program code runs: an Emscripten program's glue, a WASI program's imports module and a package driver all see `require`, `process`, `module`, `__dirname` and every Node builtin `undefined` (`require`, `module`, `exports`, `__filename` and `__dirname` writable and configurable, as `process` is, so a program can define its own, never Node's), and `import` of a builtin or a non-`data:` URL fails with `ERR_ACCESS_DENIED`.
|
|
535
535
|
|
|
536
|
-
Under the Node entry, the kernel also withholds the host's Node from the program before its module loads ([#297](https://github.com/ai-ecoverse/slicc-kernel/issues/297)). `
|
|
536
|
+
Under the Node entry, the kernel also withholds the host's Node from the program before its module loads ([#297](https://github.com/ai-ecoverse/slicc-kernel/issues/297)). `localStorage` and `sessionStorage` are `undefined` for good. `require`, `module`, `exports`, `__filename`, `__dirname`, `process`, `global`, `setImmediate` and `clearImmediate` are `undefined` too, but stay writable and configurable, so a program can install its own (as slicc-jsh and napi-rs's wasi worker template do); Node's are gone before the program runs, so deleting the program's brings back `undefined`. `Buffer` stays Node's own, since Node's `Response`, `Request`, `Blob` and stream bodies read it when they run, and a program can replace it. Process workers share Node's memory allocator, so its `allocUnsafe` and `allocUnsafeSlow` zero-fill and its pool is off (`Buffer.poolSize` is 0): a program never sees memory another process freed. A host can also start Node with `--zero-fill-buffers`. Imports of Node's builtin modules (`node:fs`, `fs`, `node:worker_threads`, …) and of anything but a `data:` URL, `file:` included, fail with `ERR_ACCESS_DENIED`, whether static, dynamic or through `import.meta.resolve`. A process worker that exits or crashes on its own ends its process with 70. This is the same guard, not a sandbox: a host that runs code it does not trust, such as an agent's, needs its own isolation around the Node process as well.
|
|
537
537
|
|
|
538
538
|
## Network
|
|
539
539
|
|
|
@@ -1204,7 +1204,7 @@ Releases are cut by semantic-release on every push to `main`, in two jobs, and o
|
|
|
1204
1204
|
|
|
1205
1205
|
Every change is certified in its pull request, before it merges (`cert-review-pr.yml`, next section), and `cert-review` is a required check of the merge queue, so every commit on `main`, and every release built from it, was certified first. A release is then **verified on npm** (`release / verify on npm` in `release.yml`, `tools/cert-review/verify.mjs`), in code, for every tag the run made:
|
|
1206
1206
|
|
|
1207
|
-
- It waits up to an hour for npm to serve the version (an accepted publish can take a while to appear; 1.125.4 took 55 min). `release-recover`
|
|
1207
|
+
- It waits up to an hour for npm to serve the version (an accepted publish can take a while to appear; 1.125.4 took 55 min). `release-recover` logs `npm publish`'s own output every time, and says PASS for a version it published only once npm serves it (the tarball answers) with `dist.integrity` equal to the tarball it packed; a version npm took but doesn't serve so after 25 min is `release-recover: INCOMPLETE`, and the publish job fails (#1228: 1.134.2 was taken, never served, and still read as PASS). A version semantic-release itself just published is handed to this job instead. A version npm still doesn't serve after the hour, and doesn't list, while a newer one of ours is its `latest`, ends with `verify: SKIPPED <name>@<version>: never served by npm; superseded by <latest>` (the gate takes SKIPPED like PASS); only after the whole wait, since a slow version can appear late and must not go unverified. SKIPPED writes no certified line, so nothing downstream reads it as certified; if npm serves a skipped version later, the coordinator's merge watchdog notes it within 10 min (any version that appears below npm's `latest`), and the coordinator re-runs `release / verify on npm` in that version's Release run for the normal verdict, the certified line or the supply-chain alert. One npm still doesn't serve, with nothing newer or a version list it can't read, is a "not served yet, re-run" failure, never a supply-chain alert. It then downloads the tarball and checks `dist.integrity` (sha512), the SLSA v1 provenance (the tarball's sha512 is its subject; `release.yml` on `refs/heads/main`, a GitHub-hosted builder; `gitCommit` = `gitHead` = the tag, on `main`), and `npm audit signatures`. npm serves a version's attestations a little after the version itself, so a 404 from the attestations, a missing `dist.attestations`, an `npm view` or network error while looking for them, or `npm audit signatures`' E404 on them, is retried within the same hour: it's a supply-chain alert only once the version has been served for 30 min, its packument has stopped changing for 10, and the attestations still answer 404, or the hour has run out. Any other status, or attestations that don't match, fail at once. A version that `release-recover.mjs` skipped because npm's `latest` is newer (#837) has nothing to verify.
|
|
1208
1208
|
- It then writes `certified @ai-ecoverse/slicc-kernel@<v> sha256=<64 hex> (covers <first>–<v>; ci: <run>; pr-certified: <each merged pull request's cert-review at its merge>; known: <open known-issue issues>)` into the GitHub release's notes, between `<!-- cert-verify -->` markers. homescoop's ci reads exactly that prefix and re-hashes the npm tarball against it. `covers` starts after the last version npm serves, so a skipped version is covered by the next. Notes that already carry the identical line stay unchanged. A pull request's `cert-review` is the newest finished one (success, failure or error) on its head at or before its merge, or the newest pending one if none had finished. A re-review that a later `ready_for_review`, `reopened` or `cert-review-approved` event starts on the same head, still pending at the merge or ending after it, doesn't change what the merge queue saw, and a status posted after the merge can't change a release's line.
|
|
1209
1209
|
- A mismatch writes no line. The job is red with a `supply-chain alert`, and so is a line already in the notes with another sha256.
|
|
1210
1210
|
|
package/dist/driver-worker.js
CHANGED
|
@@ -1275,13 +1275,10 @@ var BLOCKED_GLOBALS = [
|
|
|
1275
1275
|
"WebSocketStream",
|
|
1276
1276
|
"WebTransport",
|
|
1277
1277
|
"EventSource",
|
|
1278
|
-
"importScripts",
|
|
1279
1278
|
"indexedDB",
|
|
1280
1279
|
"caches",
|
|
1281
1280
|
"cookieStore",
|
|
1282
|
-
"Worker",
|
|
1283
1281
|
"SharedWorker",
|
|
1284
|
-
"postMessage",
|
|
1285
1282
|
"close",
|
|
1286
1283
|
"webkitRequestFileSystem",
|
|
1287
1284
|
"webkitRequestFileSystemSync",
|
|
@@ -1297,7 +1294,14 @@ var BLOCKED_NAVIGATOR = [
|
|
|
1297
1294
|
"hid",
|
|
1298
1295
|
"serial"
|
|
1299
1296
|
];
|
|
1300
|
-
var OPEN_SLOTS = [
|
|
1297
|
+
var OPEN_SLOTS = [
|
|
1298
|
+
"fetch",
|
|
1299
|
+
"WebSocket",
|
|
1300
|
+
"BroadcastChannel",
|
|
1301
|
+
"importScripts",
|
|
1302
|
+
"Worker",
|
|
1303
|
+
"postMessage"
|
|
1304
|
+
];
|
|
1301
1305
|
function chain(target) {
|
|
1302
1306
|
const out = [];
|
|
1303
1307
|
for (let at = target; at && at !== Object.prototype; ) {
|
|
@@ -1349,6 +1353,14 @@ function vacate(target, names) {
|
|
|
1349
1353
|
function lockdown(scope = globalThis) {
|
|
1350
1354
|
hide(scope, BLOCKED_GLOBALS);
|
|
1351
1355
|
vacate(scope, OPEN_SLOTS);
|
|
1356
|
+
if ("self" in scope) {
|
|
1357
|
+
Reflect.defineProperty(scope, "self", {
|
|
1358
|
+
value: scope,
|
|
1359
|
+
writable: true,
|
|
1360
|
+
enumerable: false,
|
|
1361
|
+
configurable: true
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1352
1364
|
const navigator = scope.navigator;
|
|
1353
1365
|
if (navigator && typeof navigator === "object") hide(navigator, BLOCKED_NAVIGATOR);
|
|
1354
1366
|
}
|