@ai-ecoverse/slicc 1.33.1 → 1.35.0

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 +82 -11
  2. package/package.json +9 -8
package/README.md CHANGED
@@ -140,7 +140,7 @@ A profile that doesn't exist is an error (`SLICC six's Chrome profile doesn't ex
140
140
  Put the binary and the release's `SHA256SUMS` in one folder, then check:
141
141
  - **Checksum on macOS and Linux:** `shasum -a 256 -c SHA256SUMS --ignore-missing`. On Linux `sha256sum -c SHA256SUMS --ignore-missing` does the same.
142
142
  - **Checksum on Windows (PowerShell):** `(Get-FileHash slicc-windows-amd64.exe -Algorithm SHA256).Hash.ToLower()` must equal the hash on that file's line in `SHA256SUMS` (`Select-String slicc-windows-amd64.exe SHA256SUMS`).
143
- - **Provenance:** `gh attestation verify <file> --repo ai-ecoverse/slicc-cli` checks the GitHub build-provenance attestation (Sigstore) that the release workflow made for that exact file.
143
+ - **Provenance:** `gh attestation verify <file> --repo ai-ecoverse/slicc-cli` checks the GitHub build-provenance attestation (Sigstore) that the release workflow made for that exact file. `slicc update` checks the same attestation itself (see [Attestations](#attestations)).
144
144
 
145
145
  Signing:
146
146
  - **macOS:** the binaries are signed with a Developer ID, with the hardened runtime, and notarized. A bare binary can't carry a stapled ticket (only apps, disk images and installer packages can), so Gatekeeper checks the notarization online the first time it runs. Inside Sliccstart.app the binary is stapled with the app.
@@ -153,17 +153,47 @@ slicc works with two tools that run on this machine: slicc-jerk (`jerk`), which
153
153
  **With npm.** `@ai-ecoverse/slicc` and `sliccy` list `@ai-ecoverse/slicc-jerk` and `@ai-ecoverse/fnox` as `optionalDependencies` (`^` the latest release), but only those that are on the registry when the release is staged (`npm-stage.mjs --companions`); the others are left out with a notice. The publish check that waits for the platform packages doesn't wait for them. The launcher puts the `node_modules/.bin` of each installed companion package first on `PATH` for the binary, so `jerk` and `fnox` resolve for slicc and its children.
154
154
 
155
155
  **`slicc install jerk|fnox`** installs one into the data folder's `bin`:
156
- - `jerk` from the latest release of `ai-ecoverse/slicc-jerk`, `fnox` from the latest release of `ai-ecoverse/fnox-build`;
157
- - **the release contract** (the same as slicc-cli's own): a plain binary `<name>-<os>-<arch>` (`.exe` on Windows; `darwin`, `linux`, `windows` × `amd64`, `arm64`), and `SHA256SUMS` with a line for it, both attested by the repo's `release.yml`;
158
- - slicc checks the download against `SHA256SUMS`, then installs it only once its `--version` names the release's version, through a rename next to the old one (as `slicc update` does);
159
- - it says `installed <name> <version> at <path>; its SHA-256 matches the release's SHA256SUMS (the attestation isn't checked yet)`, or `<name> <version> is already installed at <path>`;
156
+ - `jerk` from the latest release of `ai-ecoverse/slicc-jerk` (0.3.0 or later; an older latest release is refused with `… predates the release layout slicc installs from`), `fnox` from the latest release of `ai-ecoverse/fnox-build`;
157
+ - **the release contract** (the same as slicc-cli's own): a plain binary `<name>-<os>-<arch>` (`.exe` on Windows; `darwin`, `linux`, `windows` × `amd64`, `arm64`), and `SHA256SUMS` with a line for it, with a build provenance attestation by the repo's `release.yml` over the binary or over `SHA256SUMS`;
158
+ - slicc checks the download against `SHA256SUMS` and verifies its attestation (see [Attestations](#attestations)), then installs it only once its `--version` names the release's version, through a rename next to the old one (as `slicc update` does);
159
+ - it says `installed <name> <version> at <path> (SHA256SUMS and the build provenance attestation by <identity>)`, or `<name> <version> is already installed at <path>`;
160
+ - `--checksum-only` skips the attestation, with a warning, and says `SHA256SUMS only; the attestation wasn't checked`;
160
161
  - the GitHub API base follows `SLICC_UPDATE_API_BASE`, as for `update`.
161
162
 
162
163
  Only a user runs `slicc install`. Nothing on a link starts an install.
163
164
 
165
+ ## Attestations
166
+
167
+ `slicc update` and `slicc install` verify the GitHub build provenance attestation of every binary they download, after its `SHA256SUMS` check, and refuse it when that fails. A release without an attestation fails too. `--checksum-only` is the only way around it, and it warns.
168
+
169
+ **Where the attestation comes from.** `GET /repos/<repo>/attestations/sha256:<digest>` on the GitHub API, first for the binary's digest. When the binary has none, slicc looks up the digest of the release's `SHA256SUMS` instead: an attestation over `SHA256SUMS` covers the binary through its line there, which slicc has already checked. slicc accepts the binary when one of the bundles verifies.
170
+
171
+ **What is verified** (`internal/attest`, standard library only), for a Sigstore bundle v0.3 with one DSSE envelope, one Fulcio certificate and one Rekor (v1) entry:
172
+ 1. the envelope is an in-toto statement whose predicate type is `https://slsa.dev/provenance/v1`, with a subject whose SHA-256 is the file's;
173
+ 2. its single DSSE signature verifies with the certificate's key (ECDSA P-256 or P-384) over the DSSE pre-authentication encoding;
174
+ 3. the certificate chains, as a code-signing certificate, to a Fulcio root in the trusted root that is valid at the entry's integrated time, and the certificate itself was valid then;
175
+ 4. one of the certificate's embedded SCTs (`1.3.6.1.4.1.11129.2.4.2`) verifies with a certificate transparency log key in the trusted root, valid at the SCT's time, over the precertificate (the certificate body without its SCT list) and its issuer's key hash (RFC 6962);
176
+ 5. the certificate's identity: issuer (Fulcio extension `1.3.6.1.4.1.57264.1.8`) `https://token.actions.githubusercontent.com`, and exactly one subject alternative name, the URI `https://github.com/<repo>/.github/workflows/release.yml@refs/heads/main`, pinned per repo: `ai-ecoverse/slicc-cli` for `update`, `ai-ecoverse/slicc-jerk` and `ai-ecoverse/fnox-build` for `install`;
177
+ 6. the Rekor entry is a `dsse` 0.0.1 entry whose payload hash, signature and verifier are the envelope's and the certificate's;
178
+ 7. its signed entry timestamp verifies with the key of a Rekor log in the trusted root, valid at the integrated time;
179
+ 8. its inclusion proof leads from the entry to the proof's root hash (RFC 6962), and the checkpoint carries that tree size and root hash and is signed by the same log.
180
+
181
+ Errors name the step that failed (`attestation identity: …`). A bundle from a Rekor v2 log, or any other shape, fails closed.
182
+
183
+ **Unsupported: Rekor v2.** Bundles from Rekor v2 logs (Ed25519 log keys, `dsse` 0.0.2 entries, RFC 3161 timestamps instead of signed entry timestamps) aren't supported. They fail closed, so `update` and `install` refuse such a release until the verifier learns them; `--checksum-only` is the way around it meanwhile.
184
+
185
+ **The trusted root.** `internal/attest/trusted_root.json` is Sigstore's public-good trusted root (Fulcio CAs, Rekor and CT log keys) (the `trusted_root.json` target of `https://tuf-repo-cdn.sigstore.dev`), embedded in the binary. `SLICC_SIGSTORE_TRUSTED_ROOT` replaces it, for tests.
186
+
187
+ **Rotating the trusted root.** The *Sigstore* workflow runs daily. Its `trusted-root` job runs `node scripts/sigstore-root.mjs`, which follows the TUF repository's `timestamp.json`, snapshot and targets to the current `trusted_root.json` and compares its SHA-256 with the embedded file; when they differ, it opens an issue. To rotate:
188
+ 1. run `node scripts/sigstore-root.mjs --write`, which downloads the new file and checks it against the targets hash;
189
+ 2. review the diff (new Fulcio certificates or Rekor keys, `validFor` ranges) against Sigstore's announcement; the script doesn't check TUF signatures, so this review is the trust decision;
190
+ 3. open a `fix:` PR, so a release ships it. Binaries released before it keep the old root, and fail closed on attestations that need the new one until they update with `--checksum-only` or by hand.
191
+
192
+ **Parity.** The workflow's `parity` job runs `TestAttestParityWithGH`: for the latest release, `gh attestation verify --repo ai-ecoverse/slicc-cli --signer-workflow …/release.yml` and slicc's verifier must both accept the binary, and both refuse it after one byte is appended.
193
+
164
194
  ## Updates
165
195
 
166
- `slicc update` replaces the running binary (symlinks resolved) with the latest GitHub release of `ai-ecoverse/slicc-cli`. It downloads the asset for this OS and CPU and checks it against the release's `SHA256SUMS`. The new binary has to answer `--version` with the release's version before anything is replaced. The swap is a rename next to the old binary; on Windows the running binary is first moved aside to `<name>.old`, which the next run deletes. `slicc update --check` only reports.
196
+ `slicc update [--check] [--checksum-only]` replaces the running binary (symlinks resolved) with the latest GitHub release of `ai-ecoverse/slicc-cli`. It downloads the asset for this OS and CPU, checks it against the release's `SHA256SUMS`, and verifies its build provenance attestation (see [Attestations](#attestations)); `--checksum-only` skips the attestation, with a warning. The new binary has to answer `--version` with the release's version before anything is replaced. The swap is a rename next to the old binary; on Windows the running binary is first moved aside to `<name>.old`, which the next run deletes. `slicc update --check` only reports.
167
197
 
168
198
  **The version.** A release build has its version linked in (`-X main.version=<version>`). Without one, `slicc` reads its Go build info: a binary built by `go install …@<version>` (or `go run`) from a downloaded module, with a checksum in the build info, reports that module version without the leading `v`. Anything else built from a checkout reports `dev`.
169
199
 
@@ -191,7 +221,8 @@ Release builds (a plain `X.Y.Z` version, linked in or, for `go install`, from th
191
221
  | --- | --- |
192
222
  | `SLICC_NO_TELEMETRY=1` | send no telemetry |
193
223
  | `SLICC_NO_UPDATE_CHECK=1` | no update notice and no background check |
194
- | `SLICC_UPDATE_API_BASE` | GitHub API base for `update` and the notice (default `https://api.github.com`), for mirrors and tests |
224
+ | `SLICC_UPDATE_API_BASE` | GitHub API base for `update`, `install` and the notice (default `https://api.github.com`), for mirrors and tests |
225
+ | `SLICC_SIGSTORE_TRUSTED_ROOT` | a Sigstore `trusted_root.json` to verify attestations against instead of the embedded one, for tests (see [Attestations](#attestations)) |
195
226
  | `SLICC_TELEMETRY_URL` | telemetry collector base (default `https://rum.hlx.page/`) |
196
227
  | `OPTEL_RATE`, `OPTEL_DEBUG` | go-optel's sampling rate and beacon logging |
197
228
  | `SLICC_LAUNCHER` | set to `npm` by the npm launcher; removed from the environment that `slicc` passes on |
@@ -226,7 +257,7 @@ The cdp list follows the browsers: an extra that stops answering is taken off th
226
257
  - `--browser <id>`: an id from `slicc browsers` (an installed id such as `chrome`, or `cdp:<host>:<port>`), or a name, case-insensitively. Repeatable: the first hosts seven, the others are extras. Without it, the best match that can host seven. An endpoint in SLICC six's profile is refused (`<id> is SLICC six's Chrome; only --profile six uses it`).
227
258
  - `--cdp <url>`: also consider this CDP endpoint, as `slicc browsers --cdp`.
228
259
  - `--page <url>`: the seven page, default `https://seven.sliccy.ai/`. It must be `http` or `https`, and its origin is accepted as a seven origin.
229
- - `--origin`, `--name`, `--allow`, `--deny`, `--kernel-port`, `--no-kernel`, `--mount`, and the compute flags `--runner`, `--shell`, `--eval`, `--eval-quiet`, `--sftp`, `--no-sftp`: as for `slicc attach`. Without `--runner` there is no `ssh`.
260
+ - `--origin`, `--name`, `--allow`, `--deny`, `--kernel-port`, `--no-kernel`, `--no-jerk`, `--mount`, and the compute flags `--runner`, `--shell`, `--eval`, `--eval-quiet`, `--sftp`, `--no-sftp`: as for `slicc attach`. Without `--runner` there is no `ssh`.
230
261
  - `--profile <name>`: the SLICC profile for a launched browser that hosts seven. `--profile six` and `--profile six:<port>` use SLICC six's own Chrome profile instead, without the picker (see [Using SLICC six's Chrome profile](#using-slicc-sixs-chrome-profile)).
231
262
  - `--headless`: launch browsers without a window.
232
263
  - `--yes`, `--plain`: no picker. `--json`: NDJSON events, below.
@@ -400,6 +431,7 @@ slicc attach --cdp <url> [--cdp-extra <url>]... [--origin <origin>]... [--signal
400
431
  - `--mount <path>[:<name>][:ro]`: share this folder with seven's kernel (cap `fs`, repeatable); see [Host folders](#host-folders).
401
432
  - `--kernel-port`: the local port for [kernel services](#kernel-services) (1–65535, default `80`).
402
433
  - `--no-kernel`: no kernel services; nothing listens.
434
+ - `--no-jerk`: don't offer this machine's slicc-jerk (caps `jerk` and `jerk-seal`, see [`jerk`](#jerk-slicc-jerk-over-the-link)).
403
435
 
404
436
  **Setup over CDP.**
405
437
  1. slicc picks the first page tab whose URL has an allowed origin. Until there is one it says `waiting for a seven tab` and watches for new tabs.
@@ -418,6 +450,7 @@ slicc attach --cdp <url> [--cdp-extra <url>]... [--origin <origin>]... [--signal
418
450
  - Each offer starts a new link and replaces the current one.
419
451
  - A navigation or reload ends the link, and the next allowed context starts the setup again with a new nonce.
420
452
  - A closed tab ends the link, and slicc waits for another seven tab.
453
+ - A tab that closes while slicc attaches to it doesn't stop slicc: each setup call has 10 s, and when the tab is gone slicc looks for another seven tab.
421
454
 
422
455
  **Setup over stdio** (`--signal stdio`), for a test harness that owns CDP itself:
423
456
  - The same messages go as NDJSON: slicc writes `hello`, `answer`, `candidate` and `bye` lines to stdout, and reads `offer`, `candidate` and `bye` lines from stdin. Messages with another nonce are ignored.
@@ -442,7 +475,7 @@ One WebRTC peer connection. seven offers and the node answers. The node:
442
475
  - **Resets with `EOPNOTSUPP`:** an OPEN for a kind it doesn't serve.
443
476
  - **Closes the link:** an unknown frame type, a short or malformed frame (END with a payload, CREDIT that isn't 4 bytes), stream id 0, a reused id, an id with the wrong parity (page streams are odd, node streams even), or a second OPEN on a stream channel.
444
477
 
445
- HELLO from `attach`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "local", "node", "caps": ["net", "http", "credentialed", "cdp"], "routes": { "prefixes": [], "exit": true }, "policy": { "allow", "deny", "summary" }, "browsers": [ … ] }`. `cdp` and `browsers` are there when at least one browser is listed (see [`cdp`](#cdp-browser-control)). With `--runner`, `caps` adds `"ssh"` and HELLO adds `"sshHostKey": "ssh-ed25519 AAAA…"`, the host key in `authorized_keys` form, so the page can write `<host>.slicc.internal <key>` into the kernel's `known_hosts`. With `--mount`, `caps` adds `"fs"` and HELLO adds `"mounts"` (see [Host folders](#host-folders)).
478
+ HELLO from `attach`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "local", "node", "caps": ["net", "http", "credentialed", "cdp"], "routes": { "prefixes": [], "exit": true }, "policy": { "allow", "deny", "summary" }, "browsers": [ … ] }`. `cdp` and `browsers` are there when at least one browser is listed (see [`cdp`](#cdp-browser-control)). With `--runner`, `caps` adds `"ssh"` and HELLO adds `"sshHostKey": "ssh-ed25519 AAAA…"`, the host key in `authorized_keys` form, so the page can write `<host>.slicc.internal <key>` into the kernel's `known_hosts`. With `--mount`, `caps` adds `"fs"` and HELLO adds `"mounts"` (see [Host folders](#host-folders)). With host jerk, `caps` adds `"jerk"` and `"jerk-seal"` and HELLO adds `"jerk": { "version" }` (see [`jerk`](#jerk-slicc-jerk-over-the-link)).
446
479
 
447
480
  **`ssh`** (cap `ssh`), page → node, with `--runner` only:
448
481
  - OPEN `{ "kind": "ssh" }`, OPENED `{}` at once. The stream's bytes are one SSH connection to the node's SSH server.
@@ -488,6 +521,43 @@ Any value of `credentialed` other than `false` or `null` counts as true, so a ma
488
521
  - OPEN `{ "kind": "kernel", "port" }`, sent only to a page whose HELLO lists `kernel-in`. The page dials that kernel port and answers OPENED or RESET (`ECONNREFUSED` when nothing listens). See [Kernel services](#kernel-services).
489
522
  - Then raw bytes both ways: the node's first DATA is everything it has read from the browser's connection so far, request head included. END half-closes, as for `tcp`.
490
523
 
524
+ ### `jerk`: slicc-jerk over the link
525
+
526
+ Link spec §5.14 (J1). slicc-jerk (`jerk`, [Companion tools](#companion-tools)) gets tokens on this machine. Over the link seven can ask it for status, start sign-ins a human completes, and seal a lease into its vault. No token crosses the link except in `seal`'s `lease` event, which only seven's link layer reads and hands to the vault.
527
+
528
+ **Offered** when host jerk is found: the first `jerk` on `PATH`, else `jerk` in the data folder's `bin`, whose `jerk --version` names 0.3.0 or later.
529
+ - `slicc` and `slicc attach`: caps `jerk` and `jerk-seal`, unless `--no-jerk`.
530
+ - `follow`: only with `--jerk` (cap `jerk`) or `--jerk-seal` (both).
531
+ - `prompt`, `watch` and `abort`: never.
532
+ - slicc says `jerk: offering slicc-jerk <version> (jerk, jerk-seal)`, and HELLO adds `"jerk": { "version" }`. Without the cap an OPEN gets `EOPNOTSUPP`.
533
+
534
+ **OPEN** `{ "kind": "jerk", "op", "provider"?, "scope"?, "lease_id"?, "duration"?, "params"? }`. The page sends END right after it. slicc runs jerk as the user, with no terminal and its stderr dropped:
535
+
536
+ | op | cap | runs |
537
+ | --- | --- | --- |
538
+ | `list` | `jerk` | `jerk list --json` |
539
+ | `status` | `jerk` | `jerk <provider> get --json` (never `--reveal`) |
540
+ | `accounts` | `jerk` | `jerk <provider> list --json` |
541
+ | `create` | `jerk` | `jerk <provider> create --via-link [--seven-origin <origin>] [--scope S] [-p k=v]…` |
542
+ | `seal` | `jerk-seal` | `FNOX_LEASE_DURATION=<duration> jerk <provider> lease --via-link` (`duration` 1 to 86 400 whole seconds, default 3600) |
543
+ | `unseal` | `jerk-seal` | `FNOX_LEASE_ID=<lease_id> jerk <provider> drop --lease --via-link` |
544
+
545
+ - `--seven-origin` is the origin of the seven tab slicc set up with over CDP. A link set up over stdio or the tray hub has none, and `create` runs without it.
546
+ - **OPENED `{}`** once jerk has started. Then NDJSON events, then END:
547
+ - `{ "event": "progress", "message" }` for `create`, from each `{"event":"progress","message"}` line jerk writes;
548
+ - `{ "event": "lease", "credentials", "expires_at", "lease_id" }`, once, for `seal`, only when jerk exited 0 with string credentials and an RFC 3339 `expires_at`; otherwise the result is exit 1, `jerk gave no lease with an expiry`;
549
+ - exactly one `{ "event": "result", "exit", "provider"?, "user"?, "scopes"?, "expires_at"?, "env"?, "message", "items"? }`. `items` holds the rows of `list` and `accounts`. Results and rows keep only these status fields: `provider`, `name`, `source`, `requires`, `cli`, `user`, `scopes`, `expires_at`, `env` and `id`, as strings, booleans or string lists. Anything else jerk prints (a masked token, say) is dropped.
550
+ - jerk's exits 0 to 5 are results. slicc never logs a lease or a result's contents, only `jerk: <op> <provider>: exit <n>`.
551
+
552
+ **RESETs:**
553
+ - `EPROTO`: an unknown op, a missing or malformed `provider` (`^[a-z0-9][a-z0-9-]{0,63}$`) or `lease_id`, a `duration` out of range, a `scope` that isn't printable words, or a `param` whose key isn't `^[a-z][a-z0-9_]{0,31}$` or whose value isn't printable (at most 16, 256 bytes each). Host jerk checks the keys against the provider's own `params` and exits 2 for unknown ones.
554
+ - `EACCES`: `drop` (there's no such op; `unseal` drops what jerk minted), and `seal` or `unseal` without `jerk-seal`.
555
+ - `EBUSY`: a second `create` on a link while one runs.
556
+ - `ETIMEDOUT`: a `create` still running after 2 min 30 s, which is then killed. Other ops get 60 s and then answer exit 1, `jerk timed out`.
557
+ - `ECONNRESET`: jerk couldn't start, died of a signal, or exited with a code above 5.
558
+
559
+ A page RESET or a closed link kills the jerk it started.
560
+
491
561
  ### `cdp` (browser control)
492
562
 
493
563
  > **Warning:** a seven with the `cdp` capability has full control of every listed browser: its tabs, cookies, stored passwords and logged-in sessions, files it can download, and anything a page in it can reach. That includes the browser seven runs in (`seven: true`), whether slicc launched it or not: with `slicc` or `slicc attach` on your everyday browser, seven can drive all of that browser, without a further prompt. List only browsers you would let that seven use as you. For `follow` that is a seven on another machine. The one exception is seven's own origin, which the node keeps out of reach (see below).
@@ -781,7 +851,7 @@ A command that can't start exits 127 with the reason on stderr.
781
851
  ```
782
852
  slicc <join-url> follow [--exit] [--allow <rule>]... [--deny <rule>]... [--name <name>] [--cdp <url>]...
783
853
  [--runner <argv…> [--]] [--shell <argv…> [--]] [--eval <argv…> [--]] [--eval-quiet <dur>] [--sftp | --no-sftp]
784
- [--mount <path>[:<name>][:ro]]...
854
+ [--mount <path>[:<name>][:ro]]... [--jerk] [--jerk-seal]
785
855
  ```
786
856
 
787
857
  `follow` links this machine to a seven on another machine through the tray hub (see [Tray hub signaling](#tray-hub-signaling-remote-setup)). It serves the link until interrupted (`SIGINT`, `SIGTERM`) and reconnects when the link drops. Status lines go to stderr, and `SLICC_DEBUG=1` adds diagnostics. The join URL is never printed.
@@ -793,8 +863,9 @@ slicc <join-url> follow [--exit] [--allow <rule>]... [--deny <rule>]... [--name
793
863
  - `--runner`, `--shell`, `--eval`, `--eval-quiet`, `--sftp`, `--no-sftp`: compute over SSH (cap `ssh`), exactly as for `attach`. `direct-tcpip` forwarding goes through the remote policy, so it reaches public addresses only unless `--allow` says otherwise. `--runner` works with or without `--exit`.
794
864
  - `--cdp <url>`: let seven drive this browser over the link (repeatable, in any form `slicc browsers --cdp` takes; each must answer when `follow` starts). See [`cdp`](#cdp-browser-control), and its warning: the seven on the other machine gets full control of every browser listed. No browser is `seven: true`. Without `--cdp`, `follow` doesn't offer `cdp`, and a `cdp` OPEN is refused with `EOPNOTSUPP`. Each browser's debugging port and its own endpoint addresses are [denied](#network-policy) to `tcp`, `http` and `ssh` forwarding.
795
865
  - `--mount <path>[:<name>][:ro]`: share this folder with the seven on the other machine (cap `fs`, repeatable); see [Host folders](#host-folders). It can read the folder, and change it unless `:ro`.
866
+ - `--jerk`: offer this machine's slicc-jerk for status and sign-ins (cap `jerk`). `--jerk-seal` also lets the seven on the other machine seal this machine's tokens into its vault (cap `jerk-seal`) and implies `--jerk`. Without host jerk, `follow` says `jerk: no slicc-jerk 0.3.0 or later on PATH or in slicc's data folder; not offering it` and runs on without it. See [`jerk`](#jerk-slicc-jerk-over-the-link).
796
867
 
797
- HELLO from `follow`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "remote", "node", "caps", "routes": { "prefixes": [], "exit" }, "policy" }`. `caps` holds `net` and `http` with `--exit`, `ssh` with `--runner` (plus `sshHostKey`), `cdp` (and HELLO `browsers`) with `--cdp`, `fs` (and HELLO `mounts`) with `--mount`, and always `join`.
868
+ HELLO from `follow`: `{ "v": 1, "role": "node", "name", "host", "version", "mode": "remote", "node", "caps", "routes": { "prefixes": [], "exit" }, "policy" }`. `caps` holds `net` and `http` with `--exit`, `ssh` with `--runner` (plus `sshHostKey`), `cdp` (and HELLO `browsers`) with `--cdp`, `fs` (and HELLO `mounts`) with `--mount`, `jerk` (and HELLO `jerk`) with `--jerk`, `jerk-seal` with `--jerk-seal`, and always `join`.
798
869
 
799
870
  **Identity.** The device is its DTLS certificate. `follow` keeps one ECDSA P-256 certificate per hub origin (`scheme://host:port`), valid for 20 years, in `<config>/slicc/tray-certs.json` (mode `0600`). Every link to that hub uses it, so the fingerprint stays the same across reconnects, restarts and updates. The first run on a hub mints it and says `new device, fingerprint sha-256 …`; later runs say `device, fingerprint …`. Every dial attaches with a fresh `controllerId`, which is only a routing handle.
800
871
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc",
3
- "version": "1.33.1",
3
+ "version": "1.35.0",
4
4
  "description": "SLICC's command line for seven: links a machine's network, compute and browsers to seven over WebRTC",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -18,12 +18,13 @@
18
18
  "node": ">=18"
19
19
  },
20
20
  "optionalDependencies": {
21
- "@ai-ecoverse/slicc-darwin-arm64": "1.33.1",
22
- "@ai-ecoverse/slicc-darwin-amd64": "1.33.1",
23
- "@ai-ecoverse/slicc-linux-arm64": "1.33.1",
24
- "@ai-ecoverse/slicc-linux-amd64": "1.33.1",
25
- "@ai-ecoverse/slicc-windows-arm64": "1.33.1",
26
- "@ai-ecoverse/slicc-windows-amd64": "1.33.1",
27
- "@ai-ecoverse/slicc-jerk": "^0.3.0"
21
+ "@ai-ecoverse/slicc-darwin-arm64": "1.35.0",
22
+ "@ai-ecoverse/slicc-darwin-amd64": "1.35.0",
23
+ "@ai-ecoverse/slicc-linux-arm64": "1.35.0",
24
+ "@ai-ecoverse/slicc-linux-amd64": "1.35.0",
25
+ "@ai-ecoverse/slicc-windows-arm64": "1.35.0",
26
+ "@ai-ecoverse/slicc-windows-amd64": "1.35.0",
27
+ "@ai-ecoverse/slicc-jerk": "^0.6.0",
28
+ "@ai-ecoverse/fnox": "^0.0.0"
28
29
  }
29
30
  }