@ai-ecoverse/slicc-kernel 1.99.1 → 1.99.2
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 +29 -0
- package/dist/kernel-worker.js +17 -10
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +17 -10
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -885,6 +885,35 @@ The Biome, TypeScript, lefthook, Renovate and CI configuration comes from [slicc
|
|
|
885
885
|
|
|
886
886
|
Releases are cut by semantic-release on every push to `main`, in two jobs, and only on `main`. The first job runs on the bench pool, so it starts within a minute of the push, before `main` has moved on. It computes the version, tags the commit and creates the GitHub release, with `npmPublish: false`. A run that starts after `main` has moved skips; the run for the newer commit releases it. The second job runs on a GitHub-hosted runner, because npm's trusted publishing and provenance accept no self-hosted runner. It publishes the tagged commit with `tools/release-recover.mjs`. However long it waits for a runner, it publishes exactly the commit the run started on, so the provenance, the tag and the package's `gitHead` agree. For any version tagged at HEAD, `tools/release-recover.mjs` pushes the tag if origin lacks it, publishes the version if npm lacks it (with retries), and creates its GitHub release if that is missing too. So a failure after the version is tagged (a rejected push, a failed `npm publish`) doesn't strand it, and re-running the Release workflow completes it the same way.
|
|
887
887
|
|
|
888
|
+
### Certification (`cert-review`)
|
|
889
|
+
|
|
890
|
+
`.github/workflows/cert-review.yml` certifies every release from CI. It runs when the Release workflow succeeds on `main`. The version is the tag on the released commit. The delta is read from the newest earlier release whose `cert-review` status is `success` or `pending`, skipping failed and unreviewed ones (or `base.json`'s release, or the tag before), so a release whose review was cancelled or failed is covered by the next one, and the line says `covers <first>–<last>`. It also runs on `workflow_dispatch` with a `version`, optionally with `prev` and `base`, or with `planted` (a branch) and `pr` for proofs. A dispatch off `main`, or a planted one, is a dry run. Each release (its commit) has its own concurrency group, so no pending review is cancelled by a newer one. The tools are in `tools/cert-review/`:
|
|
891
|
+
|
|
892
|
+
- **plan:** works out the version, the previous tag, the commit and the base (`base.mjs`). The base is the newest earlier release whose `cert-review` commit status is `success`, or, until there is one, the release `base.json` names (the cert lane's last line). CI never reads the npm `certified` dist-tag.
|
|
893
|
+
- **delta** (`delta.mjs`): lists the pull requests merged between the two tags (their merge commits, plus `pr` for a planted branch). Each gets its conventional-commit kind (`fix`, `feat`, `perf` and `revert` are behaviour changes) and the integration test files and titles it adds or changes. The titles are read from the pull request's patch: the added `test(…)` lines and the hunk headers git puts above changed lines. Escapes are decoded as JavaScript does, and a title git cut short, or a template literal, matches as a prefix.
|
|
894
|
+
- **suite** (`suite.mjs`, `reporter.mjs`) runs on the bench pool, without secrets. It takes the tag's tree with its own dependencies and Chromium, and replaces `dist/` with the **published npm tarball** (for a planted branch, its own `npm pack`).
|
|
895
|
+
- The release job runs the release's whole `test/integration/` suite, then the delta's test files again on the **previous release's dist** (the NEGATIVE).
|
|
896
|
+
- The base job runs the base release's own suite on its own published dist.
|
|
897
|
+
- Each run uses the tree's own `npm test` command, with a reporter that records every test and subtest with its status and error.
|
|
898
|
+
- **kernel-compat** (`compat.mjs`) supplies the base-set and catalog evidence: homescoop's kernel-compat run for the release.
|
|
899
|
+
- Release runs share one group and intermediate ones are cancelled. When there is no finished run for the release commit, it dispatches `kernel-compat.yml` for that version (whose run is named `Kernel compat v<version>`) and waits up to 150 minutes.
|
|
900
|
+
- It reads the run's report artifact, and **re-runs every regressing package once** (a dispatch with that `set`).
|
|
901
|
+
- A regression that doesn't reproduce is a `compat-flake`; one that does is a `compat-regression`. A crash that reproduces and doesn't happen on the reference kernel is a `compat-crash`, which record FAILs in code.
|
|
902
|
+
- **review:** `findings.mjs` decides in code, per pull request:
|
|
903
|
+
- `negative` (a fix's test fails on the previous dist and passes on the release) or `passes` (a feature's test passes);
|
|
904
|
+
- otherwise a finding: `no-test`, `no-negative`, `fails-on-release`, `not-run`, `prev-not-run` or `no-titles`.
|
|
905
|
+
|
|
906
|
+
It also diffs the two suites test by test (`regressed`, `newFailing`, `fixed`, `stillFailing`, `removed`), flags a suite run that didn't finish (`suite-incomplete`), and adds the kernel-compat findings. Claude, on Bedrock with the key only in that step, then reads those artifacts and `instructions.txt` (which has the roll-forward FAIL list verbatim) and writes `verdict.json` and `comment.md`. Its tools are reading files, `gh pr view`, and `gh issue list`/`view`. `gh issue create` is allowed only for a release on `main`; otherwise, and for an issue in another repository, it lists the issue under `elsewhere` for the cert lane to file.
|
|
907
|
+
- **record** (`record.mjs`), in code, with read-only permissions:
|
|
908
|
+
- It re-downloads the tarball and checks `dist.integrity` (sha512) and the sha256, the SLSA v1 provenance (the tarball is its subject; `release.yml`, `refs/heads/main`, a GitHub-hosted builder; commit = `gitHead` = the tag), `npm audit signatures`, and that the commit is on `main`. A problem there, a `compat-crash`, or a planted build is a FAIL whatever the review says.
|
|
909
|
+
- It adds the **known issues as of the release**: every issue labelled `known-issue` (open or closed) and every one in `known.json`, unless it was fixed before the release. That holds when `known.json`'s `fixedIn` names an earlier or equal version, or the merged pull request that closed it is an ancestor of the tag, or it was closed (with no closing pull request) before the release commit. An issue closed as not planned or as a duplicate is dropped.
|
|
910
|
+
- The line is `certified @ai-ecoverse/slicc-kernel@<v> sha256=<…> (ci: <run>; known: …)`. Any test gaps from the findings (`no-test`, `no-negative`, `prev-not-run`, `no-titles`, `not-run`) are appended in code as `test gaps: #<pr> <kind>`, so a fix without a NEGATIVE is never certified silently.
|
|
911
|
+
- **publish** runs only for a release on `main`, never for a dry run. It puts the line into a `cert-review` commit status on the tag's commit and into the GitHub release's notes, between `<!-- cert-review -->` markers.
|
|
912
|
+
|
|
913
|
+
Moving the `certified` dist-tag stays manual. Automating it needs an npm token that may change dist-tags, in a step that re-hashes the tarball and tags only on a `certified` line.
|
|
914
|
+
|
|
915
|
+
Not part of the run yet: bios's real setup (the base-set sweep in bios, the upgrade boot, the sudo rows under `enforce`). It would plug in as one more job before review that runs slicc-bios's `npm run test:cert` with `CERT_COMMANDS` and the release's tarball, and leaves its results next to the others.
|
|
916
|
+
|
|
888
917
|
## Test fixtures
|
|
889
918
|
|
|
890
919
|
The WASIX fixtures of `test/integration/epoll.test.mjs` (#674), under `test/integration/fixtures/`, are committed with their sources, build scripts and built wasm.
|
package/dist/kernel-worker.js
CHANGED
|
@@ -9305,12 +9305,18 @@ var DriverConnection = class _DriverConnection {
|
|
|
9305
9305
|
timeoutMs;
|
|
9306
9306
|
nextId = 0;
|
|
9307
9307
|
onFail;
|
|
9308
|
-
|
|
9308
|
+
idle;
|
|
9309
|
+
constructor(port, capabilities, waiting, timeoutMs, options) {
|
|
9309
9310
|
this.port = port;
|
|
9310
9311
|
this.capabilities = capabilities;
|
|
9311
9312
|
this.waiting = waiting;
|
|
9312
9313
|
this.timeoutMs = timeoutMs;
|
|
9313
|
-
this.onFail = onFail;
|
|
9314
|
+
this.onFail = options.onFail;
|
|
9315
|
+
this.idle = options.idle === true;
|
|
9316
|
+
if (this.idle) port.unref?.();
|
|
9317
|
+
}
|
|
9318
|
+
settled() {
|
|
9319
|
+
if (this.idle && this.waiting.size === 0) this.port.unref?.();
|
|
9314
9320
|
}
|
|
9315
9321
|
static async open(port, mount, options = {}) {
|
|
9316
9322
|
const timeoutMs = options.timeoutMs ?? DRIVER_TIMEOUT_MS;
|
|
@@ -9326,6 +9332,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
9326
9332
|
clearTimeout(call.timer);
|
|
9327
9333
|
if (data.errno) call.reject(errnoError(data.errno, data.message ?? data.errno));
|
|
9328
9334
|
else call.resolve(data.result);
|
|
9335
|
+
if (options.idle && waiting.size === 0) port.unref?.();
|
|
9329
9336
|
});
|
|
9330
9337
|
port.start?.();
|
|
9331
9338
|
port.postMessage({ hello: { protocol: DRIVER_PROTOCOL, mount } });
|
|
@@ -9344,7 +9351,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
9344
9351
|
const refused2 = driverVersionError(hello.protocol);
|
|
9345
9352
|
if (refused2) throw errnoError("EPROTO", refused2);
|
|
9346
9353
|
if (hello.error) throw errnoError(hello.errno ?? "EIO", hello.error);
|
|
9347
|
-
return new _DriverConnection(port, hello.capabilities ?? {}, waiting, timeoutMs, options
|
|
9354
|
+
return new _DriverConnection(port, hello.capabilities ?? {}, waiting, timeoutMs, options);
|
|
9348
9355
|
}
|
|
9349
9356
|
call(call, transfer = []) {
|
|
9350
9357
|
if (this.failure) return Promise.reject(this.failure);
|
|
@@ -9353,6 +9360,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
9353
9360
|
const timer = unref(
|
|
9354
9361
|
setTimeout(() => {
|
|
9355
9362
|
this.waiting.delete(id2);
|
|
9363
|
+
this.settled();
|
|
9356
9364
|
const error = errnoError(
|
|
9357
9365
|
"EIO",
|
|
9358
9366
|
`the driver did not answer ${call.op} within ${this.timeoutMs} ms`
|
|
@@ -9362,6 +9370,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
9362
9370
|
this.onFail?.(error);
|
|
9363
9371
|
}, this.timeoutMs)
|
|
9364
9372
|
);
|
|
9373
|
+
if (this.idle && this.waiting.size === 0) this.port.ref?.();
|
|
9365
9374
|
this.waiting.set(id2, { resolve: resolve2, reject, timer });
|
|
9366
9375
|
this.port.postMessage({ ...call, id: id2 }, transfer);
|
|
9367
9376
|
});
|
|
@@ -9374,6 +9383,7 @@ var DriverConnection = class _DriverConnection {
|
|
|
9374
9383
|
call.reject(error);
|
|
9375
9384
|
}
|
|
9376
9385
|
this.waiting.clear();
|
|
9386
|
+
this.settled();
|
|
9377
9387
|
}
|
|
9378
9388
|
close() {
|
|
9379
9389
|
this.fail(errnoError("EIO", "the file system is unmounted"));
|
|
@@ -9728,6 +9738,7 @@ var MountTable = class {
|
|
|
9728
9738
|
{ source: spec.source, options },
|
|
9729
9739
|
{
|
|
9730
9740
|
...this.deps.timeoutMs ? { timeoutMs: this.deps.timeoutMs } : {},
|
|
9741
|
+
...opened2.idle ? { idle: true } : {},
|
|
9731
9742
|
onInvalidate: (paths) => this.invalidated(target, paths),
|
|
9732
9743
|
onFail: (error) => {
|
|
9733
9744
|
if (mounted) this.crashed(mounted, error);
|
|
@@ -12096,7 +12107,7 @@ var PATH_OPS = new Set(SYNC_FS_OPS);
|
|
|
12096
12107
|
var EARLY_WHOLE_FILE = 64 * 1024;
|
|
12097
12108
|
|
|
12098
12109
|
// src/version.ts
|
|
12099
|
-
var KERNEL_VERSION = true ? "1.99.
|
|
12110
|
+
var KERNEL_VERSION = true ? "1.99.2" : "0.0.0-dev";
|
|
12100
12111
|
var OS_RELEASE = "6.0.0-slicc";
|
|
12101
12112
|
function procVersion() {
|
|
12102
12113
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -20558,9 +20569,6 @@ var NOT_EXECUTABLE = 126;
|
|
|
20558
20569
|
var DECIDE_MS = 100;
|
|
20559
20570
|
var INIT_PID = 1;
|
|
20560
20571
|
var SHARED_DIRS = ["/tmp", "/home"];
|
|
20561
|
-
function unref2(port) {
|
|
20562
|
-
port.unref?.();
|
|
20563
|
-
}
|
|
20564
20572
|
var LAYOUT = [
|
|
20565
20573
|
["/", 493],
|
|
20566
20574
|
["/root", 448],
|
|
@@ -20771,7 +20779,6 @@ var Launcher = class {
|
|
|
20771
20779
|
pnpmMade;
|
|
20772
20780
|
pnpmEpoch = 0;
|
|
20773
20781
|
mounts;
|
|
20774
|
-
shmPorts = [];
|
|
20775
20782
|
createDriverWorker;
|
|
20776
20783
|
media;
|
|
20777
20784
|
onMountPending;
|
|
@@ -22036,9 +22043,10 @@ var Launcher = class {
|
|
|
22036
22043
|
},
|
|
22037
22044
|
{ owned: true }
|
|
22038
22045
|
);
|
|
22039
|
-
if (spec.target === SHM)
|
|
22046
|
+
if (spec.target === SHM) port2.unref?.();
|
|
22040
22047
|
return {
|
|
22041
22048
|
port: port1,
|
|
22049
|
+
...spec.target === SHM ? { idle: true } : {},
|
|
22042
22050
|
dispose: () => {
|
|
22043
22051
|
port1.close();
|
|
22044
22052
|
port2.close();
|
|
@@ -22142,7 +22150,6 @@ var Launcher = class {
|
|
|
22142
22150
|
async mountShm() {
|
|
22143
22151
|
await this.base.mkdir(SHM, { recursive: true });
|
|
22144
22152
|
await this.mounts.mountSystem({ type: "tmpfs", source: "shm", target: SHM }, this.fs);
|
|
22145
|
-
for (const port of this.shmPorts) unref2(port);
|
|
22146
22153
|
await this.fs.chmod(SHM, 1023);
|
|
22147
22154
|
}
|
|
22148
22155
|
async ownTmp() {
|