@ai-ecoverse/slicc-bios 1.20.0 → 1.21.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 CHANGED
@@ -172,7 +172,7 @@ The Files panel lists `/opt/grammars/node_modules` but doesn't scan it.
172
172
 
173
173
  #### Optional packages
174
174
 
175
- Below the system rows, Install / Update offers **Optional packages** (spectrum ≥ 1.42.0): tools that seven doesn't preinstall, each at the version the homescoop coordinator certified. The catalog is [`src/packages/optional/`](src/packages/optional/): `package.json` pins each package exactly, `package-lock.json` (made with `npm install --package-lock-only --ignore-scripts`, never installed) holds its integrity, and `catalog.json` gives its id, label, description, commands, tarball size and `requires`. A test keeps the three in step. 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, dig, websocat, GnuPG and fnox.
175
+ Below the system rows, Install / Update offers **Optional packages** (spectrum ≥ 1.42.0): tools that seven doesn't preinstall, each at the version the homescoop coordinator certified. The catalog is [`src/packages/optional/`](src/packages/optional/): `package.json` pins each package exactly, `package-lock.json` (made with `npm install --package-lock-only --ignore-scripts`, never installed) holds its integrity, and `catalog.json` gives its id, label, description, commands, tarball size and `requires`. A test keeps the three in step. 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, dig, websocat, ntfy, GnuPG and fnox.
176
176
 
177
177
  - **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`: every package in it, the one added and each dependency, must be a version in the catalog's lockfile or the base set's, with that integrity. homescoop pins `@ai-ecoverse/*` dependencies exactly (uv → Python, git → bash), so the catalog's lockfile names them all. Anything else, a dependency pnpm resolved to another version included, removes the package again and fails the row with *This version doesn't match the tested build*. 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. `/opt/user` (Your packages) isn't affected: its bins are not on `PATH`. 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.
178
178
  - **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 the catalog's offers **Update**, which adds the catalog's version; one at or above it offers **Remove**. bios never downgrades.
@@ -186,6 +186,7 @@ Below the system rows, Install / Update offers **Optional packages** (spectrum
186
186
  - **How Python finds it:** bios writes `/opt/slicc/python/slicc-pydata.pth`, which lists each package's site-packages (from its `slicc.python.sitePackages`), next to a `sitecustomize.py` that adds that folder as a site directory. The page's kernel puts `/opt/slicc/python` on every process's `PYTHONPATH`, so `python3` imports the packages from any shell or agent, as any user. Python's own discovery only looks in its own project, so the `.pth` stays. A `.pth` that an earlier version wrote to `/root/.local` is moved there the next time the optional packages are listed. The kernel's environment reaches every process, whichever client or user starts it, `sudo` included. `python -I` and `python -E` ignore `PYTHONPATH`, so they don't see the data tools; that's a known gap.
187
187
  - **State and Remove:** a receipt in `var/lib/slicc/optional/pydata/` records the installed version. **Remove** deletes the project, the `.pth` and the receipt. A project that `retired.json` lists still shows while it's installed, with only **Remove**.
188
188
  - **Without Python:** if Python is removed while the data tools stay installed, the row warns that it needs Python (`warnings`, spectrum ≥ 1.49.1).
189
+ - **ntfy** (`@ai-ecoverse/wasi-ntfy`, homescoop#1003) is seven's webhook receiver. A webhook, a phone or another agent publishes to a topic, and `ntfy sub <topic> '<command>'` runs the command once per message, in order, with `$NTFY_MESSAGE`, `$NTFY_TITLE`, `$NTFY_ID` and `$NTFY_RAW` (the message's JSON line, `attachment.url` included). For example, `ntfy sub https://ntfy.sliccy.ai/github 'agent send cone --lick=webhook --source github "$NTFY_RAW"'` turns each message into one `webhook` lick, and a replay with `--since` delivers it once. The connection is outbound only, through the page's fetch, so a quiet stream relies on the 120 s body window ([Network](#network)) to outlast ntfy's 45 s keepalive. Keep the gateway's `tk_` token in the vault and pass it as `NTFY_TOKEN` or `--token`. The command runs as the user who started `ntfy sub`, with that user's privileges, and everything in a message (`$NTFY_*`) is untrusted input chosen by whoever can publish to the topic or post to its hook URL: quote it (`"$NTFY_MESSAGE"`) and never `eval` it. A command that runs `ntfy pub` again should `unset ${!NTFY_*}` first, or it publishes to the incoming message's topic. `ntfy.test.mjs` tests it against a local fake ntfy server, not ntfy.sh.
189
190
  - **Login shells:** bios writes `/etc/profile.d/slicc.sh` at every boot, which puts `~/.local/share/gem/ruby/3.4.0/bin` on `PATH`, so a command from `gem install` runs by name in a login shell. It also makes sure `/etc/profile` runs `/etc/profile.d/*.sh`: it writes one if there's none, and adds that loop once, after the lines already there, to an `/etc/profile` that doesn't mention `/etc/profile.d/`.
190
191
  - **The agent** reads the same catalog: bios writes it to `/etc/slicc/optional.json` at every boot (id, package, version, label, description, commands, requires).
191
192
 
@@ -485,7 +486,7 @@ Limits:
485
486
  [`.github/workflows/canary.yml`](.github/workflows/canary.yml) answers "is bios main green with these candidate versions?" before anyone asks for a pin. It never pushes, pins or opens a PR: it reports.
486
487
 
487
488
  - **Triggers:** `workflow_dispatch` and `workflow_call` with `overrides`, a JSON list of `name@version` (`["@ai-ecoverse/slicc-kernel@1.81.0"]`), and optionally `runner`, `shards` (names from [`scripts/canary/shards.json`](scripts/canary/shards.json); `follow-chat`, `remote-pydata`, `users-agent-ui`, `packages-update-cdp`, `guard`, `guard-set-extension-prompt`, `guard-set-extension-lagging`, `guard-set-proxy-prompt`, `guard-set-proxy-lagging`, `k4-link`, `user-packages-keys-favicon` and `rest` by default; a shard's `env` in that file, such as `GUARD_VARIANTS`, is set for its tests, or `sweep` for just the base-set sweep and the certs check), `expect` and `bios-ref` (any branch or sha of slicc-bios: the shard jobs check it out and lay this ref's `scripts/canary`, and `sweep.test.mjs` if it has none, over it; a ref whose `pins.test.mjs` has no canary mode gets the candidates in its working copy of `certs.json` instead, and the report still lists them as candidates). A proof in `proofs.json` can name its own `ref` the same way. An hourly `schedule` checks npm's `latest` of every kernel, jsh, cdp, agent, `wasm-*`, `wasi-*`, `wasix-*` and `py-*` package that a `src/packages/**/package.json` pins, and runs once with every newer one as the overrides, only when that list differs from the last scheduled canary's (its inputs are kept in the Actions cache). A `pull_request` trigger, filtered to the canary's own files, runs the proof in [`scripts/canary/proofs.json`](scripts/canary/proofs.json) from one plan job, cancelling a superseded run: kernel 1.78.0 on the `sweep` shard must regress grep, sed, jq, xz, findutils, diffutils and patch with exit 70 (kernel #483). A second proof packs `@ai-ecoverse/slicc-cdp@1.26.2` with `npm pack`, uploads it from the plan job, and runs it as a candidate artifact on `packages-update-cdp` and `guard` with `repeat: 3`.
488
- - **A candidate from another repo's run:** `candidate-package` (the package it replaces, `@ai-ecoverse/slicc-cdp`), `candidate-artifact` (an artifact holding one `npm pack` tarball of it), `candidate-run` (the run that uploaded it), `candidate-sha256` (the tarball's) and optionally `candidate-repo` (the caller's repository by default). Each shard job downloads the artifact with `github.token`, which under `workflow_call` is the caller's, so the caller's job needs `actions: read`. [`override-pins.mjs`](scripts/canary/override-pins.mjs) checks the tarball's sha256 before it reads anything and refuses a mismatch, then checks the tarball is that package with an exact version. It seeds the harness download cache with the bytes at the npm URL of that version, and rewrites the pins and locks through a local registry that serves npm's packuments with that version added, so an unpublished `x.y.z-pr.N.M` locks like a published one (npm's lock gets the registry URL back). Everything else stays a registry version. The report lists it as `candidate (artifact <run>/<name>, sha256 …)`.
489
+ - **A candidate from another repo's run:** `candidate-package` (the package it replaces, `@ai-ecoverse/slicc-cdp`), `candidate-artifact` (an artifact holding one `npm pack` tarball of it), `candidate-run` (the run that uploaded it), `candidate-sha256` (the tarball's) and optionally `candidate-repo` (the caller's repository by default). Each shard job downloads the artifact with `github.token`, which under `workflow_call` is the caller's, so the caller's job needs `actions: read`. [`override-pins.mjs`](scripts/canary/override-pins.mjs) checks the tarball's sha256 before it reads anything and refuses a mismatch, then checks the tarball is that package with an exact version. It seeds the harness download cache with the bytes at the npm URL of that version, and rewrites the pins and locks through a local registry that serves npm's packuments with that version added, so an unpublished `x.y.z-pr.N.M` locks like a published one (npm's lock gets the registry URL back). The tests get the same packument (#599): each test process of a candidate run imports [`packuments.mjs`](scripts/canary/packuments.mjs), which checks the seeded tarball against `pins.json`'s sha256 and integrity again (refusing a mismatch, so no test runs) and, whenever the harness fetches that package's packument from npm, adds the version with the manifest from the tarball's own `package.json`, `dist.tarball` at the seeded npm URL and `dist.integrity` the tarball's sha512. The `dist-tags` stay npm's, so the candidate never becomes `latest`, and every other request passes through unchanged. Seven's in-kernel pnpm, installing the optional catalog's `slicc` say, then resolves the candidate like a published version. Everything else stays a registry version. The report lists it as `candidate (artifact <run>/<name>, sha256 …)`.
489
490
  - **Binding the candidate to its upload:** a call that names a candidate also passes `candidate-artifact-id` and `candidate-artifact-digest`, the `artifact-id` and `artifact-digest` outputs of the step that uploaded it (the digest is the zip's SHA-256, not the tarball's `candidate-sha256`; a `sha256:` prefix is allowed). `candidate-binding` is `strict` by default, and the plan refuses a candidate without both values. Only an explicit `candidate-binding: legacy` takes a candidate by name, as before; runs that name no candidate, such as the schedule and the PR proofs, don't set it. Before anything from the tested ref runs, [`scripts/canary/bind.mjs`](scripts/canary/bind.mjs) reads `GET /repos/{repo}/actions/artifacts/{id}` and `GET /repos/{repo}` and refuses the artifact unless its id, name, `workflow_run.id`, `workflow_run.repository_id` and digest are the bound ones and it hasn't expired. The shard then downloads it by `artifact-ids` with `digest-mismatch: error`, and the tarball's sha256 check stays. The PR proof's tarball is bound the same way, to the plan job's upload step.
490
491
  - **The canary's own scripts:** every checkout of its tools (the plan and report jobs, and the `scripts/canary` laid over the tested ref) is `job.workflow_sha`, the commit of the `canary.yml` that defines the job. Under `workflow_call` that is the called workflow's commit, not the caller's (`github.workflow_sha`), so a caller pinned to `canary.yml@<sha>` runs that commit's scripts, whatever `main` holds. The plan job prints `canary tools: PASS|FAIL` and fails unless it checked out that commit. `bios-ref` only picks the tested tree, and an empty one is that same commit.
491
492
  - **Callers pinned before the bindings (#523):** a `canary.yml` from before it checks out `main`'s scripts and passes no `CANDIDATE_BINDING`, `CANDIDATE_ARTIFACT_ID` or `CANDIDATE_ARTIFACT_DIGEST` at all, so main's plan takes its candidate by name, as `legacy`, and prints `canary plan: legacy binding, the calling canary.yml passes no candidate-binding`. Its report passes `--prefix <label>-` instead of `--bindings` and `--download`: the report then reads only the planned `<label>-canary-shard-<run>-<shard>` directories of that call's download, and refuses any other directory. The current `canary.yml` always passes `candidate-binding`, so a call through it without an id and a digest stays strict, even with an empty `candidate-binding`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-bios",
3
- "version": "1.20.0",
3
+ "version": "1.21.1",
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",
@@ -42,12 +42,12 @@
42
42
  "format": "biome check --write ."
43
43
  },
44
44
  "devDependencies": {
45
- "@ai-ecoverse/slicc": "1.44.6",
45
+ "@ai-ecoverse/slicc": "1.44.7",
46
46
  "@ai-ecoverse/slicc-browsers": "1.8.5",
47
47
  "@ai-ecoverse/slicc-node": "2.5.1",
48
48
  "@ai-ecoverse/slicc-shared-web": "1.24.2",
49
49
  "@ai-ecoverse/slicc-spectrum": "1.86.4",
50
- "@ai-ecoverse/slicc-vault": "1.10.1",
50
+ "@ai-ecoverse/slicc-vault": "1.12.0",
51
51
  "@biomejs/biome": "2.5.15",
52
52
  "es-module-lexer": "3.0.3",
53
53
  "fake-indexeddb": "6.2.5",
@@ -344,6 +344,10 @@
344
344
  "sha256": "134acd4ccc67ba48e98102e5a6b4ee995a21eb87b628e2b683b750437319a631",
345
345
  "exception": "unverifiable build (homescoop#864): kept because gh is core; bump when its reproduce check or a CI-built gh is certified"
346
346
  },
347
+ "@ai-ecoverse/wasi-ntfy@2.32.0-2": {
348
+ "integrity": "sha512-gPaK5pptREyvSsfnog3PqxDYAiZ9Qeo3S0llnB5UVzOeQTLT222SecJ5Xm7d6ldB2//3iILp3wxqV24TItpwMg==",
349
+ "sha256": "12267d1463082fd86f7315a41c3f1c905ba320496ae5078cc56487246f884a05"
350
+ },
347
351
  "@ai-ecoverse/wasi-pnpm@12.9.1-8": {
348
352
  "integrity": "sha512-/3LRssC7T2t9HovusS9neuDg5+FNMhf90MkECauL1vZI/6BsQSadLyopnzn3ifYvY0LDC+Q8Src22oGCE+x1QA==",
349
353
  "sha256": "08136a9292ec7a04ebda5bc23fa7b84f85a635f13b19c9512f6ad83ddde60766"
@@ -135,6 +135,13 @@
135
135
  "commands": ["websocat"],
136
136
  "size": 1266828
137
137
  },
138
+ "@ai-ecoverse/wasi-ntfy": {
139
+ "id": "ntfy",
140
+ "label": "ntfy",
141
+ "description": "Publishes and subscribes to notifications, and runs a command for every message: ntfy sub <topic> '<command>', with the message in $NTFY_MESSAGE and $NTFY_RAW. Works with ntfy.sh, any ntfy server and the tray's webhook gateway, ntfy.sliccy.ai.",
142
+ "commands": ["ntfy"],
143
+ "size": 4751117
144
+ },
138
145
  "@ai-ecoverse/wasi-fnox": {
139
146
  "id": "fnox",
140
147
  "label": "fnox",
@@ -12,6 +12,7 @@
12
12
  "@ai-ecoverse/wasi-dig": "0.1.0-2",
13
13
  "@ai-ecoverse/wasi-fnox": "1.39.0-2",
14
14
  "@ai-ecoverse/wasi-gh": "2.102.0-1",
15
+ "@ai-ecoverse/wasi-ntfy": "2.32.0-2",
15
16
  "@ai-ecoverse/wasi-slicc": "1.41.0",
16
17
  "@ai-ecoverse/wasix-gnupg": "2.4.9-11",
17
18
  "@ai-ecoverse/wasix-openssh": "10.6.0-6",
@@ -95,6 +96,15 @@
95
96
  "slicc-kernel": ">=1.30.0"
96
97
  }
97
98
  },
99
+ "node_modules/@ai-ecoverse/wasi-ntfy": {
100
+ "version": "2.32.0-2",
101
+ "resolved": "https://registry.npmjs.org/@ai-ecoverse/wasi-ntfy/-/wasi-ntfy-2.32.0-2.tgz",
102
+ "integrity": "sha512-gPaK5pptREyvSsfnog3PqxDYAiZ9Qeo3S0llnB5UVzOeQTLT222SecJ5Xm7d6ldB2//3iILp3wxqV24TItpwMg==",
103
+ "license": "Apache-2.0 OR GPL-2.0-only",
104
+ "engines": {
105
+ "slicc-kernel": ">=1.125.4"
106
+ }
107
+ },
98
108
  "node_modules/@ai-ecoverse/wasi-slicc": {
99
109
  "version": "1.41.0",
100
110
  "resolved": "https://registry.npmjs.org/@ai-ecoverse/wasi-slicc/-/wasi-slicc-1.41.0.tgz",
@@ -9,6 +9,7 @@
9
9
  "@ai-ecoverse/wasi-dig": "0.1.0-2",
10
10
  "@ai-ecoverse/wasi-fnox": "1.39.0-2",
11
11
  "@ai-ecoverse/wasi-gh": "2.102.0-1",
12
+ "@ai-ecoverse/wasi-ntfy": "2.32.0-2",
12
13
  "@ai-ecoverse/wasi-slicc": "1.41.0",
13
14
  "@ai-ecoverse/wasix-gnupg": "2.4.9-11",
14
15
  "@ai-ecoverse/wasix-openssh": "10.6.0-6",