@ai-ecoverse/slicc-kernel 1.93.0 → 1.93.1
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 -1
- package/dist/kernel-worker.js +25 -7
- package/dist/kernel-worker.js.map +3 -3
- package/dist/node-process-worker.js +1 -1
- package/dist/node.js +25 -7
- package/dist/node.js.map +3 -3
- package/dist/process-worker.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -161,6 +161,8 @@ Page-only: neither is on an attached client (`attachKernel`, `connect()`), so no
|
|
|
161
161
|
- A change is a write, a truncate, a rename, a removal, or a change of mode, owner or times of the file or of any directory above it. A change to a parent directory's own metadata counts too, and creating or removing a sibling changes it when the change comes from another kernel.
|
|
162
162
|
- It sees changes made through any slicc kernel on the origin, in this tab or another one: the kernels tell each other which files are watched and report writes to those. `watch` resolves once every other live kernel on the origin has the watch (a kernel that doesn't answer within 500 ms is not waited for), so a write made after it resolves is reported. A kernel that ends with watches still on is forgotten (by its Web Lock) at the next reported write or unanswered announcement. This needs the shared metadata (the default): with `metadata: false` a kernel sees only its own changes. It doesn't see writes made with the OPFS API outside a kernel, such as a page script or an installer writing the root directly. After such a write the page should attest again itself (and may also attest on tab focus, as a safety net).
|
|
163
163
|
- The cost when no kernel on the origin watches anything is one empty-set check per write.
|
|
164
|
+
- **A kernel that starts late:** a kernel learns the other kernels' watched files only when they answer its greeting, one message round trip (usually milliseconds) after it starts. A write it makes before then isn't reported. A consumer that must not miss a change checks again (attests) after its first report.
|
|
165
|
+
- **Trust:** the kernels coordinate over a `BroadcastChannel`, which every same-origin context can post to. A script on the origin can fake an acknowledgement, so `watch` resolves before another kernel really has it, clear a kernel's watched files, or report changes that didn't happen. That is the same boundary as a direct OPFS write, which `watch` doesn't see either. Treat `watch` as an invalidation signal only, never as proof: attest again before each use that matters, as the vault and bios do.
|
|
164
166
|
|
|
165
167
|
### `attachKernel(port, options?) → Promise<KernelClient>`
|
|
166
168
|
|
|
@@ -618,7 +620,7 @@ Lowering a soft resource limit (`ulimit -S -n 64`) still fails with `EPERM` in E
|
|
|
618
620
|
Every process has credentials in the kernel, as on Linux: real, effective and saved user and group ids, and supplementary groups. A process gets them from the user it was started as (`run`, `openTerminal`, a client's `spawn`, or the client's own user; root by default) and keeps its parent's across fork, spawn and exec. Setuid and setgid bits are never honoured on exec. Files may have owners (see [File owners](#file-owners)), checked against the credentials with `users: 'enforce'` (see [Permissions](#permissions)); the credentials also decide who may signal whom, and what `/proc` and `ps` show.
|
|
619
621
|
|
|
620
622
|
- **The database:** `/etc/passwd` and `/etc/group` are real files. On first start the kernel writes them when they're missing, with `root` (uid 0, home `/root`, created `0700`) and `nobody` (65534), and the groups `root`, `sudo` (27), `users` (100) and `nogroup` (65534); files already there are kept as they are. The kernel reads them for every lookup, so an edit counts at once. [`kernel.users`](#kernelusers) adds and removes users.
|
|
621
|
-
- **Environment:** a process started as a user gets `HOME`, `USER`, `LOGNAME`, `PNPM_HOME`, `NPM_CONFIG_PREFIX` and `PATH`. A user's `PNPM_HOME` is `~/.local/share/pnpm` and its npm prefix `~/.local`; root's are `/usr/local/share/pnpm` (or the embedder's `env.PNPM_HOME`) and `/usr/local`. `PATH` is `$PNPM_HOME/bin:/usr/local/bin:/usr/bin:/bin`.
|
|
623
|
+
- **Environment:** a process started as a user gets `HOME`, `USER`, `LOGNAME`, `PNPM_HOME`, `NPM_CONFIG_PREFIX` and `PATH`. A user's `PNPM_HOME` is `~/.local/share/pnpm` and its npm prefix `~/.local`; root's are `/usr/local/share/pnpm` (or the embedder's `env.PNPM_HOME`) and `/usr/local`. `PATH` is `$PNPM_HOME/bin:/usr/local/bin:/usr/bin:/bin`. pnpm makes only `$PNPM_HOME/bin`, so the kernel makes root's `PNPM_HOME` when it is missing, just before a process starts: once at boot, and again after any mount or unmount, a removable medium inserted, a `hostfs` folder coming back, or a change at that directory or above it (removing it, say), and after a failed try (no medium yet). With owners on, the directories it makes there get root's owner and `0755`, as the boot layout does. A process already running when a medium arrives gets it at its next child launch. Writes inside it cost nothing extra.
|
|
622
624
|
- **Commands per user:** root's global packages (`pnpm add -g` as root) are commands every user finds in `/usr/bin`. A user's own global packages are commands for that user only: they show up in the user's `~/.local/share/pnpm/bin`, first on its `PATH`, and a program the user starts finds them by name before the system's; another user, root included, doesn't. A user's packages can map file suffixes (`binfmt`) for that user too. The kernel picks up an install, a removal and a new user as they happen.
|
|
623
625
|
- **Changing credentials:** POSIX `setresuid`/`setresgid` rules. Root (effective uid 0) may set any id and the group list; anyone else may only swap among their own real, effective and saved ids, and gets `EPERM` otherwise.
|
|
624
626
|
- **Signals:** a process may signal another if its effective uid is 0, or if its real or effective uid is the target's real or saved uid; otherwise `kill` fails with `EPERM`. A group kill signals the members it may, and fails with `EPERM` only when it may signal none.
|
package/dist/kernel-worker.js
CHANGED
|
@@ -11569,7 +11569,7 @@ function mountTable(mounts = []) {
|
|
|
11569
11569
|
}
|
|
11570
11570
|
|
|
11571
11571
|
// src/version.ts
|
|
11572
|
-
var KERNEL_VERSION = true ? "1.93.
|
|
11572
|
+
var KERNEL_VERSION = true ? "1.93.1" : "0.0.0-dev";
|
|
11573
11573
|
var OS_RELEASE = "6.0.0-slicc";
|
|
11574
11574
|
function procVersion() {
|
|
11575
11575
|
return `Linux version ${OS_RELEASE} (slicc-kernel ${KERNEL_VERSION}) #1 SMP PREEMPT_DYNAMIC
|
|
@@ -19249,6 +19249,9 @@ var Launcher = class {
|
|
|
19249
19249
|
hostname;
|
|
19250
19250
|
watchers = new FsWatchers();
|
|
19251
19251
|
pnpmHome;
|
|
19252
|
+
pnpmChain;
|
|
19253
|
+
pnpmMade;
|
|
19254
|
+
pnpmEpoch = 0;
|
|
19252
19255
|
mounts;
|
|
19253
19256
|
createDriverWorker;
|
|
19254
19257
|
media;
|
|
@@ -19299,7 +19302,10 @@ var Launcher = class {
|
|
|
19299
19302
|
this.mounts = new MountTable({
|
|
19300
19303
|
open: (type, spec) => this.driver(type, spec),
|
|
19301
19304
|
busy: (target) => [...this.openFiles].some((nodes) => nodes.holds(target)) || heldUnder(this.held, target),
|
|
19302
|
-
changed:
|
|
19305
|
+
changed: (...paths) => {
|
|
19306
|
+
if (paths.some((path) => this.pnpmChain.has(path))) this.pnpmStale();
|
|
19307
|
+
this.watchers.changed(...paths);
|
|
19308
|
+
},
|
|
19303
19309
|
owners: this.owners
|
|
19304
19310
|
});
|
|
19305
19311
|
this.mounted = this.mounts.wrap(options.fs);
|
|
@@ -19312,6 +19318,7 @@ var Launcher = class {
|
|
|
19312
19318
|
this.fstabRetries = options.fstabRetries ?? FSTAB_RETRIES;
|
|
19313
19319
|
this.processMounts = options.processMounts ?? true;
|
|
19314
19320
|
this.pnpmHome = options.env?.PNPM_HOME ?? SYSTEM_PNPM_HOME;
|
|
19321
|
+
this.pnpmChain = new Set(chain(normalizePath(this.pnpmHome)));
|
|
19315
19322
|
this.modulesDir = options.modules ?? "/node_modules";
|
|
19316
19323
|
this.appended = appendedRoots(options.commands);
|
|
19317
19324
|
this.cdp = new CdpHosts(options.cdp);
|
|
@@ -19918,6 +19925,7 @@ var Launcher = class {
|
|
|
19918
19925
|
delete env[TICKET_ENV];
|
|
19919
19926
|
env.HOSTNAME = this.hostname;
|
|
19920
19927
|
let program;
|
|
19928
|
+
await this.pnpmReady();
|
|
19921
19929
|
try {
|
|
19922
19930
|
const caller = { pid: req.ppid ?? 0, uid: req.cred.euid, tag: req.tag };
|
|
19923
19931
|
if (this.integrity) await this.checkedSources(planned, caller);
|
|
@@ -20562,8 +20570,7 @@ var Launcher = class {
|
|
|
20562
20570
|
this.fs
|
|
20563
20571
|
);
|
|
20564
20572
|
void this.unlinked.sweep(entry.target);
|
|
20565
|
-
|
|
20566
|
-
await this.provisionPnpmHome();
|
|
20573
|
+
this.pnpmStale();
|
|
20567
20574
|
return entry;
|
|
20568
20575
|
}
|
|
20569
20576
|
async ownTmp() {
|
|
@@ -20611,8 +20618,18 @@ var Launcher = class {
|
|
|
20611
20618
|
if (path === "/") return path;
|
|
20612
20619
|
return joinName(await realDir(this.base, parentOf4(path)), baseName(path));
|
|
20613
20620
|
}
|
|
20614
|
-
|
|
20615
|
-
|
|
20621
|
+
pnpmReady() {
|
|
20622
|
+
if (this.pnpmMade !== void 0) return this.pnpmMade;
|
|
20623
|
+
const epoch = this.pnpmEpoch;
|
|
20624
|
+
const made2 = this.base.mkdir(this.pnpmHome, { recursive: true }).then(() => this.owners ? this.stampLayout() : void 0).catch(() => {
|
|
20625
|
+
if (this.pnpmEpoch === epoch) this.pnpmMade = void 0;
|
|
20626
|
+
});
|
|
20627
|
+
this.pnpmMade = made2;
|
|
20628
|
+
return made2;
|
|
20629
|
+
}
|
|
20630
|
+
pnpmStale() {
|
|
20631
|
+
this.pnpmEpoch++;
|
|
20632
|
+
this.pnpmMade = void 0;
|
|
20616
20633
|
}
|
|
20617
20634
|
mountedBy(spec, cred) {
|
|
20618
20635
|
if (!this.owners || cred.euid === 0 && cred.egid === 0) return spec;
|
|
@@ -20646,6 +20663,7 @@ var Launcher = class {
|
|
|
20646
20663
|
umount(target, detach = false) {
|
|
20647
20664
|
const at = normalizePath(target);
|
|
20648
20665
|
this.mounts.umount(at, detach);
|
|
20666
|
+
this.pnpmStale();
|
|
20649
20667
|
if (!detach) return;
|
|
20650
20668
|
for (const nodes of this.openFiles) nodes.revoke(at);
|
|
20651
20669
|
for (const holds of this.held) holds.revoke(at);
|
|
@@ -20711,7 +20729,7 @@ var Launcher = class {
|
|
|
20711
20729
|
await this.resolvePrefixes();
|
|
20712
20730
|
for (const dir of SHARED_DIRS) await this.base.mkdir(dir, { recursive: true });
|
|
20713
20731
|
if (this.owners) await this.ownTmp();
|
|
20714
|
-
await this.
|
|
20732
|
+
await this.pnpmReady();
|
|
20715
20733
|
await this.users.ensure();
|
|
20716
20734
|
if (this.owners) await this.stampLayout();
|
|
20717
20735
|
if (this.owners) await this.sudoer.provision();
|