@ai-ecoverse/slicc-bios 1.41.4 → 1.41.6

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.
Files changed (2) hide show
  1. package/README.md +5 -5
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -200,7 +200,7 @@ The Files panel lists `/opt/grammars/node_modules` but doesn't scan it.
200
200
 
201
201
  **Release notes (slicc-spectrum#458):** each update check also gives the Kernel, UI, Agent and Tailscale rows a `releases` list from their GitHub repositories (`slicc-kernel`, `slicc-spectrum`, `slicc-agent`, `wasm-tailscale`), and each optional package one from the repository its npm version document names, when that is on GitHub ([`os/releases.js`](src/seed/releases.js)). A row gets the release it has installed and every newer one up to the version it offers, newest first, at most 30. Each release has its `version` (the tag without the `v`, or without the package's name in a shared repository such as homescoop), its `url` and its `notes`, the release body unchanged (the `<!-- cert-verify -->` block included, which spectrum turns into a Certified badge) up to 64 KB. Spectrum renders the notes; bios only fetches them. bios asks GitHub's unauthenticated API (`/repos/<repo>/releases?per_page=100`, page by page down to the installed version, at most 5 pages), without credentials, a referrer or any header but `Accept` and `If-None-Match`. It keeps each list in IndexedDB (`slicc-releases`) for a day and revalidates it with its ETag at every check, and GitHub doesn't count a 304 against its 60 requests an hour. A 403 or 429 backs off until `Retry-After`, the rate limit's reset or 15 minutes, and leaves `releases` out, so the row looks as it does without notes, with no error. The page sets no `connect-src`, so these requests need no change to its CSP.
202
202
 
203
- Below the system rows, Install / Update offers **Optional packages** (spectrum ≥ 1.42.0): tools that seven doesn't preinstall. Seven pins only what UI boot and the agent install need (Lars, 2026-10-21), so every catalog package comes at npm's `latest`, behind [the gate](#optional-packages). A release passes when npm's provenance shows its publisher's release workflow built it on `main`. homescoop publishes its packages (`wasm-*`, `wasi-*`, `wasix-*`) through its ladder. The other publishers are slicc-jsh, mcpcat, slicc-cli (wasi-slicc) and slicc-cdp (sliccy-browser), and the catalog names each one's repository and workflow in its `source`. The catalog, [`src/packages/optional/catalog.json`](src/packages/optional/catalog.json), lists each package by its npm name, with only what npm can't tell: its `id` and `label`, and optionally `requires` (other ids), `notes` (bios's own caveats, one line each, shown next to npm's description), `helpers` (commands to leave out of the list until homescoop marks them `helper: true`), `range` and `abi` (Python's, below), `source` (a publisher other than homescoop: its `repo` and release `workflow`, and optionally `since`, the first version it certifies, and `deny`, versions it never certifies, each with a reason) and `kind: "project"`. A project keeps its `description`, `commands` and `size`, since npm doesn't know it.
203
+ Below the system rows, Install / Update offers **Optional packages** (spectrum ≥ 1.42.0): tools that seven doesn't preinstall. Seven pins only what UI boot and the agent install need (Lars, 2026-10-21), so every catalog package comes at npm's `latest`, behind [the gate](#optional-packages). A release passes when npm's provenance shows its publisher's release workflow built it on `main`. homescoop publishes its packages (`wasm-*`, `wasi-*`, `wasix-*`) through its ladder. The other publishers are slicc-jsh, mcpcat, slicc-cli (wasi-slicc) and slicc-cdp (sliccy-browser), and the catalog names each one's repository and workflow in its `source`. The catalog, [`src/packages/optional/catalog.json`](src/packages/optional/catalog.json), lists each package by its npm name, with only what npm can't tell: its `id` and `label`, and optionally `requires` (other ids), `notes` (bios's own caveats, one line each, shown next to npm's description), `helpers` (commands to leave out of the list until homescoop marks them `helper: true`), `range` and `abi` (Python's, below), `source` (a publisher other than homescoop: its `repo` and the list of release `workflow`s it accepts) and `kind: "project"`. A project keeps its `description`, `commands` and `size`, since npm doesn't know it.
204
204
 
205
205
  - **What npm tells (`os/packages.js`):** at boot, and at an update check at most every ten minutes, bios fetches each entry's version doc from the registry from the page (`https://registry.npmjs.org/<name>/latest`, which sends CORS `*`; the kernel's network path isn't needed), all in parallel and each with a 15-second timeout. It takes `version` (the row's `offered`), `description` (npm's text, verbatim), the commands (the keys of `slicc.commands`, without one marked `helper: true` or listed in `helpers`, and only names a shell can run), `dist.unpackedSize` (the row's `size`, now what the package unpacks to on disk, its own files only, so git reads 56 MB where the old tarball-based size read 19 MB; the row says `unpacked: true`) and `dist.integrity`. An entry with a `range` (Python's is `3.15.0`) takes the highest version in range from the abbreviated packument instead, where the range is matched against the upstream X.Y.Z with homescoop's `-N` build ignored, so `3.15.0` offers 3.15.0-3 but never a 3.15.1 or 3.16 (pydata's builds are for one Python ABI: homescoop keeps the ABI within one X.Y.Z, and its py-* ranges stop at the next patch). With `abi`, a version whose `slicc.python.abi` differs isn't offered.
206
206
  - **Cache:** the last good answer for each entry is kept in `var/lib/slicc/optional/npm.json`, so the panel works offline and shows at once at boot; a later fetch replaces it, an entry that fails keeps its cached answer, and holds only what the rows show. A passing provenance verdict is remembered only in the tab's memory, for the listing (never a refusal, never in OPFS, which kernel processes can write, and never for an install, which always asks npm again).
@@ -208,19 +208,19 @@ Below the system rows, Install / Update offers **Optional packages** (spectrum
208
208
  - **The gate** (one function, `gate()` in `os/packages.js`, for the panel's Install and Update, a user's Update and [Your packages](#your-packages)) checks every package in the lock pnpm made. Each must be one of:
209
209
  - an exact `name@version` with that integrity in the base set's lockfile (`src/packages/package-lock.json`) or `src/packages/certs.json`; or
210
210
  - an `@ai-ecoverse/*` package whose locked integrity equals the registry's `dist.integrity` for that exact version, and that npm's stored SLSA v1 provenance (`dist.attestations`, which bios trusts as npm stores it) binds to that integrity (its subject's sha512) and to its publisher's repository and release workflow at `refs/heads/main`. The publisher is bios's own, never read from npm:
211
- - a catalog entry's `source`: slicc-jsh's, mcpcat's and slicc-cli's (for wasi-slicc) own `release.yml`, or their `ci.yml` since they moved onto slicc-shared-web's pipeline, and slicc-cdp's `publish-sliccy-browser.yml` for sliccy-browser;
211
+ - a catalog entry's `source`: slicc-jsh's, mcpcat's and slicc-cli's (for wasi-slicc) own `release.yml`, or their `ci.yml` since they moved onto slicc-shared-web's pipeline, and slicc-cdp's `publish-sliccy-browser.yml` or `ci.yml` for sliccy-browser;
212
212
  - otherwise homescoop's `ladder-build.yml` or `publish.yml` for the `wasm-*`, `wasi-*`, `wasix-*` and `py-*` packages;
213
- - and [`sources.json`](src/packages/optional/sources.json) for a dependency-only publisher: slicc-cdp, under sliccy-browser, whose rule is `certified: "tag"`, its npm dist-tag `certified` (from the abbreviated packument), since its main released versions its cert-review didn't pass.
213
+ - and [`sources.json`](src/packages/optional/sources.json) for a dependency-only publisher: slicc-cdp, under sliccy-browser, by its own `release.yml` or `ci.yml`. No npm dist-tag is read: a `certified` tag neither admits nor refuses a release.
214
214
 
215
215
  A release from another repository, another workflow or another ref (a maintenance branch, a tag) is refused, and so is a package with no publisher there.
216
- - A source's `deny` and `since` refuse those versions, exact matches included: wasi-slicc 1.44.4 and everything before 1.44.1.
216
+ - A release npm marks deprecated is refused, with npm's message ("… is deprecated on npm: …"). An owner who wants a version refused deprecates it. That covers a `certs.json` exact match too, unless the base set's lockfile ships that version: bios asks npm for it, and refuses it when npm deprecates it or doesn't have it. wasi-slicc 1.44.4 and everything before 1.44.1 are refused this way.
217
217
  - Whatever matched, homescoop's certification exceptions then apply, exact matches included: a `fail` verdict refuses that version, and a `requires` verdict refuses it unless every pin of what it requires, in the lock and the base set's lockfile (never `certs.json`'s history), is in range. bios bundles `certification-exceptions.json` at the homescoop commit `pins.test.mjs` pins ([`exceptions.json`](src/packages/optional/exceptions.json); `pins.test` keeps it byte for byte that file) and unions it with homescoop main's (`raw.githubusercontent.com`, CORS `*`), which can only deny or constrain, never grant: a tampered or missing live file is at worst a denial, and the bundled copy decides alone when it can't be fetched. Finally a package whose `engines['slicc-kernel']` or kernel peer range the base set's kernel doesn't meet is refused.
218
218
  - Anything that isn't `@ai-ecoverse/*` and isn't in the base set is refused; homescoop packages have no third-party dependencies.
219
219
  - **Listing:** each entry's latest goes through the same rules (with its exact `dependencies`) when it's fetched. If latest fails, bios walks back through older versions (in range, not deprecated, at most five; a version whose doc is broken is skipped) and offers the newest that passes, with `newer: { version, reason }` naming latest's blocker. If none passes, the row is `withheld` with that reason, offers no Install or Update, and an installed copy keeps Remove.
220
220
 
221
221
  Today it offers git, the GitHub CLI, OpenSSH, `slicc` (see [Sevens this kernel follows](#network)), Python, the Python data tools (numpy, pandas and matplotlib), Node.js (slicc-jsh's `node` and `jsh`), `sliccy:browser` for `.jsh` scripts, Ruby, Perl, Biome, the PDF tools (poppler), qpdf, rsync, screen, SQLite, the BIND tools (`dig`, `host` and `nslookup`), websocat, ntfy, GnuPG, fnox, mcpcat (an MCP client), zip (Info-ZIP's `zip`, `unzip` and `zipinfo`), xxd (vim's hex dump, with `xxd -r`) and ImageMagick. zip's `unzip` refuses an entry whose name isn't UTF-8 (an old Latin-1 or CP437 archive without a Unicode path): it says `cannot create <name>` / `Illegal byte sequence`, extracts the other entries and exits 50, and `unzip -l` still lists the entry. It never extracts it under a changed name, and `unzip -p` still streams its bytes ([homescoop#1174](https://github.com/ai-ecoverse/homescoop/issues/1174)). ImageMagick is homescoop's HEIF build (`wasm-imagemagick-heif`, a superset of the plain build, which isn't offered), with `magick`, `convert`, `mogrify`, `identify` and `magick-open`, and it reads HEIC and AVIF. A failed write leaves an existing target as it was. Its known issues: writing over another user's 0666 file in a sticky directory such as `/tmp` fails with `Operation not permitted`, though writing your own files works ([homescoop#1258](https://github.com/ai-ecoverse/homescoop/issues/1258)); `.mpc` writes fail with `cache resources exhausted` ([homescoop#1208](https://github.com/ai-ecoverse/homescoop/issues/1208)); and the cert's coverage gaps, among them the no-encoder fallback and MPC's two-file write ([homescoop#1209](https://github.com/ai-ecoverse/homescoop/issues/1209)). sudo for `magick`, `convert` or `mogrify` is offered once, never always, since they write files. No two entries' npm `latest` provide the same command, so an install never shadows another entry's; `packages.test` checks that against npm's current `latest`.
222
222
 
223
- - **Install** runs `pnpm add -g <package>@<version>` in the page's kernel, as a user would, under the Web Lock `slicc-optional`, so the commands work at once in every open shell. pnpm 12 gives each global add its own project under `$PNPM_HOME/global/v11/`; bios reads `PNPM_HOME` from the kernel's environment. Afterwards `os/packages.js` reads that project's `pnpm-lock.yaml`, and every package in it, the one added and each dependency, must pass [the gate](#optional-packages). A locked integrity that isn't the registry's for that version (drift) removes the package again and fails the row with *This version doesn't match the tested build*; any other refusal fails it with *Not offered: <reason>.* An Update that fails puts the version it had back (*… stays.*), and an install that fails removes the package, so nothing unchecked stays installed. A row with no version from npm installs nothing, and Install and Update ask npm for the offer again first, so they never act on the OPFS cache's version. An entry's `requires` (uv needs Python) are installed first. A package's kernel command always wins over the same package's Node `bin`. After each install and update, for every name that a package declares both in `slicc.commands` and in `bin`, bios removes the link that pnpm made in `$PNPM_HOME/bin`, but only when that link points into this package, so `mcpcat` runs `/usr/bin/mcpcat`, not a `#!/usr/bin/env node` script with no Node to run it. Another package's bins are never touched, and a package with only a `bin` keeps it. A `pnpm add -g` typed in a shell gets the same pass: bios watches only the `bin` and `global` folders of root's `$PNPM_HOME` (`/usr/local/share/pnpm`) and of each user's `~/.local/share/pnpm`, and `/etc/passwd`, to add a user's when the user appears; about 50 ms after pnpm writes there, it runs that pass over the global's packages, as that user for a user's own global (bios#715). `/opt/user` (Your packages) isn't affected: its bins are not on `PATH`. A certified catalog package's agent skills reach every cone the same way. After the install or update, for each folder its `package.json` lists in `pi.skills`, bios links each skill in it into `/usr/share/skills/<name>`, through the kernel and as root, so no cone can change what the agent loads. The folder has to resolve inside the package; the skill's folder name has to match `^[a-z0-9][a-z0-9-]*$` and equal its `SKILL.md` `name`; and it mustn't collide with a built-in or with an entry it didn't make. The skill files are made readable by everyone (`a+rX`). bios records its links in `var/lib/slicc/optional/<id>/skills`, removes the ones an update drops, and removes all of them on Remove. A skipped skill is logged and never fails the install. The agent's rule stands: it doesn't scan root's global pnpm, so a user's `pnpm add -g` can't add skills. A project entry also **updates** a required package that's older than the catalog's before it installs, since it runs on the catalog's version: the data tools override their own Python away, and their builds need the catalog's Python. A global add brings its own pinned dependencies, so it leaves an older required package as it is.
223
+ - **Install** runs `pnpm add -g <package>@<version>` in the page's kernel, as a user would, under the Web Lock `slicc-optional`, so the commands work at once in every open shell. pnpm 12 gives each global add its own project under `$PNPM_HOME/global/v11/`; bios reads `PNPM_HOME` from the kernel's environment. Afterwards `os/packages.js` reads that project's `pnpm-lock.yaml`, and every package in it, the one added and each dependency, must pass [the gate](#optional-packages). A locked integrity that isn't the registry's for that version (drift) removes the package again and fails the row with *This version doesn't match the tested build*; any other refusal fails it with *Not offered: <reason>.* An Update that fails puts the version it had back (*… stays.*), and an install that fails removes the package, so nothing unchecked stays installed. A row with no version from npm installs nothing, and Install and Update ask npm for the offer again first, so they never act on the OPFS cache's version. An entry's `requires` (uv needs Python) are installed first. A package's kernel command always wins over the same package's Node `bin`. After each install and update, for every name that a package declares both in `slicc.commands` and in `bin`, bios replaces the link that pnpm made in root's `$PNPM_HOME/bin` with a symlink to `/usr/bin/<name>`, and removes it from a user's own `~/.local/share/pnpm/bin`, where the kernel then serves the user's own kernel command at that same path, but only when that link points into this package, so `mcpcat` runs `/usr/bin/mcpcat`, not a `#!/usr/bin/env node` script with no Node to run it, and a shell that already looked up `$PNPM_HOME/bin/mcpcat` keeps running the kernel command. Once the kernel command is gone (`pnpm remove -g`), the next pass removes such a symlink. **Known limit:** a command chained right after the install in the same shell (`pnpm add -g mcpcat && mcpcat`) can run before the pass, about 50 ms after pnpm's last write, and hit the Node link once with `bad interpreter`; the next call, through the same hashed path, runs the kernel command. Closing that window needs the kernel to run such a `#!/usr/bin/env node` link as the package's own kernel command, which is asked of slicc-kernel. Another package's bins are never touched, and a package with only a `bin` keeps it. A `pnpm add -g` typed in a shell gets the same pass: bios watches only the `bin` and `global` folders of root's `$PNPM_HOME` (`/usr/local/share/pnpm`) and of each user's `~/.local/share/pnpm`, and `/etc/passwd`, to add a user's when the user appears; about 50 ms after pnpm writes there, it runs that pass over the global's packages, as that user for a user's own global (bios#715). `/opt/user` (Your packages) isn't affected: its bins are not on `PATH`. A certified catalog package's agent skills reach every cone the same way. After the install or update, for each folder its `package.json` lists in `pi.skills`, bios links each skill in it into `/usr/share/skills/<name>`, through the kernel and as root, so no cone can change what the agent loads. The folder has to resolve inside the package; the skill's folder name has to match `^[a-z0-9][a-z0-9-]*$` and equal its `SKILL.md` `name`; and it mustn't collide with a built-in or with an entry it didn't make. The skill files are made readable by everyone (`a+rX`). bios records its links in `var/lib/slicc/optional/<id>/skills`, removes the ones an update drops, and removes all of them on Remove. A skipped skill is logged and never fails the install. The agent's rule stands: it doesn't scan root's global pnpm, so a user's `pnpm add -g` can't add skills. A project entry also **updates** a required package that's older than the catalog's before it installs, since it runs on the catalog's version: the data tools override their own Python away, and their builds need the catalog's Python. A global add brings its own pinned dependencies, so it leaves an older required package as it is.
224
224
  - **Progress:** a row shows pnpm's package counts once pnpm counts more than one package. Before that, a single package, such as Python, still shows its download in bytes, from pnpm's `Downloading` lines (see [Agent](#agent)). Without either the bar is indeterminate.
225
225
  - **State** comes from pnpm's global projects, not from a list of bios's own, so a package installed by hand shows as installed with its version. One older than npm's offered version offers **Update**, which adds that version; one at or above it offers **Remove**. bios never downgrades.
226
226
  - **A user's own installs:** bios also reads each user's own pnpm global (`/home/<user>/.local/share/pnpm/global/v11`, a `pnpm add -g` as `cone`), as root and read-only, straight from the files: it runs no pnpm as the user for that, and with kernel users off it reads none. Each row lists its installs (`installs`, slicc-spectrum#475): the panel's copy as `{ version, where: '/usr/local/share/pnpm', manager: 'panel' }` and each user's as `{ version, where: '/home/<user>/.local/share/pnpm', user, manager: 'pnpm' }`. The version and state follow the panel's copy, or else the user's newest. A row with any install never offers **Install**, and only a panel copy offers **Remove**; a row with only user installs offers **Update** when it's older than npm's offered version, and nothing otherwise. That **Update** runs `pnpm add -g` as each user whose copy is older, with their uid, gid, `HOME`, `PNPM_HOME` and `PATH` in their home, with `--ignore-scripts`, `--ignore-pnpmfile`, the store's integrity check and no release-age wait (the catalog's version is certified), never as root and never with the system's environment, so the files stay theirs and no system copy appears. Their lockfile then passes the same check as a panel install; if it doesn't, bios puts the user's version back and the row says so. bios never touches a user's own bins. A requirement counts only in its own scope: the panel's copy for a panel install or a project, so one only a user has is installed for the system first, and that user's own global, or the panel's, for that user's copy (*Needs …*). The Remove question counts every copy that needs it, a user's included, and the move from the old root global moves a system copy even when a user has the package. The panel's own Install, Update and Remove work on its copy as before, whatever a user has.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-bios",
3
- "version": "1.41.4",
3
+ "version": "1.41.6",
4
4
  "description": "Slim loader that boots SLICC into OPFS and serves the UI from there",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",