Further MD Fixes

This commit is contained in:
Raven Scott
2026-04-25 23:04:56 -04:00
parent b07bc38708
commit b9d3a8b17f
143 changed files with 1861 additions and 1861 deletions
+9 -9
View File
@@ -1,13 +1,13 @@
# Bare OS agent — Markdown workspace
This tree follows the **agent** Markdown workspace convention: “soul” files under **`workspace/**` define personality, rules, and memory. `**/bin/agent**` loads them into the LLM **system prompt** on each session (after seeding from `**/share/agent-workspace/`** on the system drive if `~/.agent/workspace/SOUL.md` is missing).
This tree follows the **agent** Markdown workspace convention: “soul” files under **`workspace/`** define personality, rules, and memory. **`/bin/agent`** loads them into the LLM **system prompt** on each session (after seeding from **`/share/agent-workspace/`** on the system drive if `~/.agent/workspace/SOUL.md` is missing).
## Layout (personal Hyperdrive)
| Path | Role |
| --- | --- |
| **`~/.agent/workspace/`** | Agent brain — **git-trackable**, portable across peers |
| **`~/.agent/workspace/skills/**` | Modular **skills** — one folder per skill, each with `**SKILL.md`** (optional YAML frontmatter) |
| **`~/.agent/workspace/skills/`** | Modular **skills** — one folder per skill, each with **`SKILL.md`** (optional YAML frontmatter) |
| **`~/.agent/workspace/memory/`** | Daily append logs `YYYY-MM-DD.md` (optional) |
| **`~/.agent/skills/`** | Optional **global** skills (lower precedence than `workspace/skills/` when names collide) |
| **`~/.agent/config.json`** | API URL, key, model (existing agent config) |
@@ -17,24 +17,24 @@ This tree follows the **agent** Markdown workspace convention: “soul” files
## Skills
1. Add a directory under **`~/.agent/workspace/skills/<skill-id>/**` with a `**SKILL.md`** file.
2. Use YAML frontmatter for **`name**`, `**description**`, `**version`**, etc. The compact system prompt lists **id**, **name**, and a short **description** only.
1. Add a directory under **`~/.agent/workspace/skills/<skill-id>/`** with a **`SKILL.md`** file.
2. Use YAML frontmatter for **`name`**, **`description`**, **`version`**, etc. The compact system prompt lists **id**, **name**, and a short **description** only.
3. During a session, the model loads the full document with the **`read_skill`** tool (do not paste huge skills into the user channel unless asked).
4. Shared skills can live under **`~/.agent/skills/**`; keep `**workspace/skills/`** for machine-local or repo-specific behavior.
4. Shared skills can live under **`~/.agent/skills/`**; keep **`workspace/skills/`** for machine-local or repo-specific behavior.
Seeded examples in this repo (under **`skills/**`): `**p2p-os-status**`, `**bare-os-kernel-proc**`, `**bare-os-super-developer**`, `**holesail**` (managed `**state.json**`, `**seed**`/`**key**`, stock `**bare-www-***` / `**bare-ssh-***`), and `**hdms`** (Hyperdrive mounts and invite/pair).
Seeded examples in this repo (under **`skills/`**): **`p2p-os-status`**, **`bare-os-kernel-proc`**, **`bare-os-super-developer`**, **`holesail`** (managed **`state.json`**, **`seed`**/**`key`**, stock **`bare-www-*`** / **`bare-ssh-*`**), and **`hdms`** (Hyperdrive mounts and invite/pair).
After **`agent --config**` / `**--setup**` (or changing `**owner_name**` / `**agent_label**` via `**edit_agent_config**`), `**IDENTITY.md**` and `**USER.md**` are regenerated from `**config.json`** so the workspace matches the operator and agent label.
After **`agent --config**` / **`--setup`** (or changing **`owner_name`** / **`agent_label`** via **`edit_agent_config`**), **`IDENTITY.md`** and **`USER.md`** are regenerated from **`config.json`** so the workspace matches the operator and agent label.
## Editing
1. Change files under **`~/.agent/workspace/`** on your **personal** drive.
2. Restart **`agent`** or start a new session so the system message reloads.
3. Keep **`SOUL.md**` / `**AGENTS.md**` stable within a session if you follow the drift guard in `**AGENTS.md`**.
3. Keep **`SOUL.md`** / **`AGENTS.md`** stable within a session if you follow the drift guard in **`AGENTS.md`**.
## Defaults in this repository
Source templates: **`packages/bare-os-coreutils/share/agent-workspace/**` — copied to `**kernel/share/agent-workspace/**` during `**npm run build -w bare-os-coreutils`** for seeding into new homes.
Source templates: **`packages/bare-os-coreutils/share/agent-workspace/`** — copied to **`kernel/share/agent-workspace/`** during `**npm run build -w bare-os-coreutils`** for seeding into new homes.
## Compatibility
@@ -10,14 +10,14 @@ requires: [read_proc_file, vfs]
## When to use
Use when the user asks what kernel features are **on or off in this session**, what capabilities exist, or whether something (SSH, replication, metrics) is actually enabled. Do **not** infer live kernel state from **`read_man_page**` / `**apropos_man`** alone — those search documentation text.
Use when the user asks what kernel features are **on or off in this session**, what capabilities exist, or whether something (SSH, replication, metrics) is actually enabled. Do **not** infer live kernel state from **`read_man_page`** / **`apropos_man`** alone — those search documentation text.
## Execution steps
1. Call **`read_proc_file**` on `**/proc/bare_os/features**` or `**/proc/bare_os/features.json`** (same payload shape as documented in the static system prompt).
2. Call **`read_proc_file**` on `**/proc/bare_os/capabilities.json`** for structured capability bits.
3. Optionally read **`/proc/bare_os/metrics_live.json**` or related `**/proc/bare_os/*`** paths if the question is about live metrics (stay within tool allowlists).
4. Use **`get_system_info**` with `**want: capabilities**` or `**want: swarm**` only as a convenience when you already need bundled blobs; prefer `**read_proc_file`** for “what is enabled **now**?”.
1. Call **`read_proc_file`** on **`/proc/bare_os/features`** or **`/proc/bare_os/features.json`** (same payload shape as documented in the static system prompt).
2. Call **`read_proc_file`** on **`/proc/bare_os/capabilities.json`** for structured capability bits.
3. Optionally read **`/proc/bare_os/metrics_live.json`** or related **`/proc/bare_os/*`** paths if the question is about live metrics (stay within tool allowlists).
4. Use **`get_system_info`** with `**want: capabilities**` or `**want: swarm**` only as a convenience when you already need bundled blobs; prefer **`read_proc_file`** for “what is enabled **now**?”.
## Output format
@@ -10,22 +10,22 @@ requires: [read_file, read_proc_file, run_js_script]
## When to use
Use this skill when you (or the user) need to **author or debug** Bare OS **JavaScript** that runs **inside the guest** (kernel init, `/bin/*` utilities, `kernel.ext.d`, user `.mjs` run via **`run_js_script**`, or Pear/booter-hosted scripts). It complements repo docs: treat `**developer-guide/02-the-context-object.md**` and `**packages/bare-os-booter/lib/bare-os-ctx.d.ts`** as the canonical deep dives; this file is the **fast mental model**.
Use this skill when you (or the user) need to **author or debug** Bare OS **JavaScript** that runs **inside the guest** (kernel init, `/bin/*` utilities, `kernel.ext.d`, user `.mjs` run via **`run_js_script`**, or Pear/booter-hosted scripts). It complements repo docs: treat **`developer-guide/02-the-context-object.md`** and **`packages/bare-os-booter/lib/bare-os-ctx.d.ts`** as the canonical deep dives; this file is the **fast mental model**.
## Core model
1. **Entrypoints** — Kernel: **`async function start(ctx)`** in `/boot/init.js` (or your image). Commands: **`async function run(ctx, argv)**` where `**argv[0]`** is the invoked name (e.g. `agent`). You **must** set **`ctx.exitCode`** (number) before returning on failure paths.
2. **`ctx` is not Node** — There is no full **`process**`, no `**require('node:fs')**`. The booter assembles `**ctx**` as the narrow **syscall surface**: `**vfs**`, `**env**`, `**execLine**`, `**runBinCommand**`, optional `**httpFetch**`, `**bare`**, identity helpers, diagnostics, etc. See the mermaid overview in Chapter 2 of the developer guide.
3. **`/bin/agent` is special** — The agent bundle uses **`run_js_script**` for guest JS and a frozen tool surface; do not assume `**node**` exists. For **general** in-guest scripting, prefer `**ctx.vfs**` + `**ctx.execLine**` / `**ctx.runBinCommand**` and optional `**ctx.bare.*`** modules when enabled.
2. **`ctx` is not Node** — There is no full **`process`**, no `**require('node:fs')**`. The booter assembles **`ctx`** as the narrow **syscall surface**: **`vfs`**, **`env`**, **`execLine`**, **`runBinCommand`**, optional **`httpFetch`**, **`bare`**, identity helpers, diagnostics, etc. See the mermaid overview in Chapter 2 of the developer guide.
3. **`/bin/agent` is special** — The agent bundle uses **`run_js_script`** for guest JS and a frozen tool surface; do not assume **`node`** exists. For **general** in-guest scripting, prefer **`ctx.vfs`** + **`ctx.execLine`** / **`ctx.runBinCommand`** and optional **`ctx.bare.*`** modules when enabled.
## Writing scripts (`run(ctx, argv)`)
- **Argv** — `argv` is a string array; **`argv[0]`** is how you were invoked (symlink name matters for multi-call binaries).
- **Stdout** — Prefer **`ctx.console.log**` / `**ctx.console.error**` (session-aware). For binary or captured stdout, `**ctx.bareOsBinWrite`** may exist when the shell captures pipeline output.
- **Shell a subprocess** — **`await ctx.execLine('some shell line', { signal, timeoutMs })**` returns a string (see booter `**raceWithAbortAndTimeout**`). Heavy work: `**await ctx.runBinCommand(['/bin/grep', …], opts)`** for same resolution as the interactive shell.
- **Filesystem** — **`await ctx.vfs.readFile(path)**``**Uint8Array**`; `**await ctx.vfs.writeFile(path, buf, opts?)**`. Decode with `**ctx.b4a.toString(buf)**` or `**TextDecoder**`. Always use **absolute** paths under `**/home**`, `**/tmp**`, `**/mnt**`, `**/bin`**, etc., per policy.
- **Environment** — **`ctx.env**` is mutable shell state (also `**ctx.vfs.env**`). After `**execLine**`, `**ctx.env.BARE_OS_EXIT_STATUS`** reflects last exit code when the booter sets it.
- **Exit** — Set **`ctx.exitCode = 1**` (or other code) on error; `**0**` on success. `**ctx.requestBooterExit(code)**` ends the whole session from builtins like `**exit`**.
- **Stdout** — Prefer **`ctx.console.log`** / **`ctx.console.error`** (session-aware). For binary or captured stdout, **`ctx.bareOsBinWrite`** may exist when the shell captures pipeline output.
- **Shell a subprocess** — **`await ctx.execLine('some shell line', { signal, timeoutMs })**` returns a string (see booter **`raceWithAbortAndTimeout`**). Heavy work: `**await ctx.runBinCommand(['/bin/grep', …], opts)`** for same resolution as the interactive shell.
- **Filesystem** — **`await ctx.vfs.readFile(path)**`**`Uint8Array`**; `**await ctx.vfs.writeFile(path, buf, opts?)**`. Decode with `**ctx.b4a.toString(buf)**` or **`TextDecoder`**. Always use **absolute** paths under **`/home`**, **`/tmp`**, **`/mnt`**, **`/bin`**, etc., per policy.
- **Environment** — **`ctx.env`** is mutable shell state (also **`ctx.vfs.env`**). After **`execLine`**, **`ctx.env.BARE_OS_EXIT_STATUS`** reflects last exit code when the booter sets it.
- **Exit** — Set **`ctx.exitCode = 1**` (or other code) on error; **`0`** on success. `**ctx.requestBooterExit(code)**` ends the whole session from builtins like **`exit`**.
## Building “apps” (long-lived behaviour)
@@ -33,46 +33,46 @@ Think in layers the stock OS already uses:
| Layer | Mechanism | Notes |
| --- | --- | --- |
| **Init** | **`bareOsRegisterBootStepHook**`, initd units | Boot-order DAG (stock: `**bare-os-www**` before `**bare-holesail**` so `**bare-www-***` reaches loopback HTTP; `**bare-openssh**` + login stack ensure `**bare-ssh-***` in `**~/.holesail/state.json**`); pair `**registerKernelShutdownHook`** / initd disposers for teardown. |
| **Virtual files** | **`bareOsRegisterVirtualFile(name, reader, opts?)**` | Serves `**/run/bare-os/virtual/<name>`**; gated by runtime caps. |
| **IPC** | **`ctx.bareOsIpc**` when present | `**push`/`take**`, JSON helpers, fanout, duplex bridge — bounded; audit when `**BARE_OS_IPC_AUDIT=1`**. |
| **Kernel extensions** | **`bareOsRegisterKernelExtensionRecord**`, `**bareOsRunImageScript**` under `**/lib/bare-os/extensions/`** | Trusted image paths only. |
| **Sandboxed user JS** | **`bareOsSandboxRunScript(source, argv?, opts?)**` | Restricted `**ctx**`; disable with `**BARE_OS_SANDBOX_SCRIPT=0`**. |
| **Pear / host** | **`bareOsPearIpcEmit**`, `**bareOsPearIpcRequest**`, mirror/export hints | Host must cooperate; return `**{ ok, hint }`** patterns. |
| **Init** | **`bareOsRegisterBootStepHook`**, initd units | Boot-order DAG (stock: **`bare-os-www`** before **`bare-holesail`** so **`bare-www-*`** reaches loopback HTTP; **`bare-openssh`** + login stack ensure **`bare-ssh-*`** in **`~/.holesail/state.json`**); pair **`registerKernelShutdownHook`** / initd disposers for teardown. |
| **Virtual files** | **`bareOsRegisterVirtualFile(name, reader, opts?)**` | Serves **`/run/bare-os/virtual/<name>`**; gated by runtime caps. |
| **IPC** | **`ctx.bareOsIpc`** when present | `**push`/`take**`, JSON helpers, fanout, duplex bridge — bounded; audit when **`BARE_OS_IPC_AUDIT=1`**. |
| **Kernel extensions** | **`bareOsRegisterKernelExtensionRecord`**, **`bareOsRunImageScript`** under **`/lib/bare-os/extensions/`** | Trusted image paths only. |
| **Sandboxed user JS** | **`bareOsSandboxRunScript(source, argv?, opts?)**` | Restricted **`ctx`**; disable with **`BARE_OS_SANDBOX_SCRIPT=0`**. |
| **Pear / host** | **`bareOsPearIpcEmit`**, **`bareOsPearIpcRequest`**, mirror/export hints | Host must cooperate; return `**{ ok, hint }`** patterns. |
Before touching sensitive **`ctx**` methods in hardened images, call `**ctx.bareOsIsCtxMethodAllowed?.(name)**` when boot policy `**BARE_OS_BOOT_POLICY_ALLOWED_CTX_METHODS`** is set.
Before touching sensitive **`ctx`** methods in hardened images, call `**ctx.bareOsIsCtxMethodAllowed?.(name)**` when boot policy **`BARE_OS_BOOT_POLICY_ALLOWED_CTX_METHODS`** is set.
## `ctx` field map (cheat sheet)
**Always read live truth** for capability bits: **`read_proc_file**` on `**/proc/bare_os/features**` and `**/proc/bare_os/capabilities.json**` — do not infer from man pages alone (see `**bare-os-kernel-proc`** skill).
**Always read live truth** for capability bits: **`read_proc_file`** on **`/proc/bare_os/features`** and **`/proc/bare_os/capabilities.json`** — do not infer from man pages alone (see **`bare-os-kernel-proc`** skill).
### Files, drives, process
- **`ctx.vfs**``**readFile**`, `**writeFile**`, `**mkdir**`, `**readdir**`, `**stat`/`lstat**`, `**chmod**`, … Path routing: system vs **personal** Hyperdrive; `**ctx.drive**` vs `**ctx.personalDrive`** for advanced use.
- **`ctx.env**`, `**ctx.drive**`, `**ctx.personalDrive**`, `**ctx.disk`** — Session identity and mounts.
- **`ctx.execLine**`, `**ctx.runBinCommand`** — Shell and `/bin` execution with shared policy (timeouts, abort).
- **`ctx.vfs`** — **`readFile`**, **`writeFile`**, **`mkdir`**, **`readdir`**, `**stat`/`lstat**`, **`chmod`**, … Path routing: system vs **personal** Hyperdrive; **`ctx.drive`** vs **`ctx.personalDrive`** for advanced use.
- **`ctx.env`**, **`ctx.drive`**, **`ctx.personalDrive`**, **`ctx.disk`** — Session identity and mounts.
- **`ctx.execLine`**, **`ctx.runBinCommand`** — Shell and `/bin` execution with shared policy (timeouts, abort).
### Bytes, console, session
- **`ctx.b4a`** — Buffer/string helpers for Hyperdrive payloads.
- **`ctx.console**`, `**ctx.readLine**`, `**ctx.writeScreen**` — REPL session ( `**readLine`** may be Fish-backed when enabled).
- **`ctx.exitCode**`, `**ctx.requestBooterExit**`, `**ctx.registerKernelShutdownHook`**
- **`ctx.console`**, **`ctx.readLine`**, **`ctx.writeScreen`** — REPL session ( **`readLine`** may be Fish-backed when enabled).
- **`ctx.exitCode`**, **`ctx.requestBooterExit`**, **`ctx.registerKernelShutdownHook`**
### Bare OS introspection & policy
- **`ctx.bareOsCtxApiVersion**`, `**ctx.bareOsRuntimeCaps`** (frozen)
- **`ctx.bareOsAdvertisedKernelCapabilityWords**`, `**ctx.bareOsSeedKernelCapabilityWords**``**>>> 0`** when testing bits.
- **`ctx.bareOsGetResourceStatus**`, `**ctx.bareOsReadProcMetricsLive**`, `**ctx.bareOsReadBareTopSnapshot`**
- **`ctx.bareOsRegisterVirtualFile**`, `**ctx.bareOsInvalidateVirtualFile**`, `**ctx.bareOsUpdateVirtualFileMeta`**
- **`ctx.bareOsEmitIpcAudit**`, `**ctx.bareOsEvaluatePeerAdmission**`, `**ctx.bareOsEmitMirrorDriveHint`**
- **`ctx.bareOsCtxApiVersion`**, **`ctx.bareOsRuntimeCaps`** (frozen)
- **`ctx.bareOsAdvertisedKernelCapabilityWords`**, **`ctx.bareOsSeedKernelCapabilityWords`**`**>>> 0`** when testing bits.
- **`ctx.bareOsGetResourceStatus`**, **`ctx.bareOsReadProcMetricsLive`**, **`ctx.bareOsReadBareTopSnapshot`**
- **`ctx.bareOsRegisterVirtualFile`**, **`ctx.bareOsInvalidateVirtualFile`**, **`ctx.bareOsUpdateVirtualFileMeta`**
- **`ctx.bareOsEmitIpcAudit`**, **`ctx.bareOsEvaluatePeerAdmission`**, **`ctx.bareOsEmitMirrorDriveHint`**
### Optional / host-dependent
- **`ctx.httpFetch**` — Same allow/deny policy as `**curl**` / `**wget**`; every host for `**web_fetch`** must be allowlisted.
- **`ctx.bare**` — Frozen map of vendored modules (`**b4a**`, `**protomux**`, …) when `**BARE_OS_BARE_MODULES`** allows.
- **`ctx.bareOsHostStats**`, `**ctx.bareOsChat***`, `**ctx.bareOsPearIpc*`** — Present only when wired by the booter/host.
- **`ctx.httpFetch`** — Same allow/deny policy as **`curl`** / **`wget`**; every host for **`web_fetch`** must be allowlisted.
- **`ctx.bare`** — Frozen map of vendored modules (**`b4a`**, **`protomux`**, …) when **`BARE_OS_BARE_MODULES`** allows.
- **`ctx.bareOsHostStats`**, **`ctx.bareOsChat*`**, **`ctx.bareOsPearIpc*`** — Present only when wired by the booter/host.
For the **full** list and semantics, open **`developer-guide/02-the-context-object.md**` in the repo (or `**read_file`** on a mounted checkout).
For the **full** list and semantics, open **`developer-guide/02-the-context-object.md`** in the repo (or **`read_file`** on a mounted checkout).
## Minimal script template (guest)
@@ -103,22 +103,22 @@ export async function run(ctx, argv) {
}
```
Save under **`/home/.../my-tool.mjs**` and run by **absolute path** (or register under `**/bin**` on the image). **Do not** rely on `**node`** in the guest.
Save under **`/home/.../my-tool.mjs`** and run by **absolute path** (or register under **`/bin`** on the image). **Do not** rely on **`node`** in the guest.
## Agent-specific note
When helping **inside `/bin/agent`**, the model uses **tools** (`read_file`, `run_js_script`, …) backed by the **same** personal/system VFS as the rest of the guest. **`run_js_script**` writes a temp `**.mjs**` under `**~/.agent/**` and executes it like a `**/bin**` script — the script body should use the same `**ctx**` patterns above when the harness passes `**ctx`**.
When helping **inside `/bin/agent`**, the model uses **tools** (`read_file`, `run_js_script`, …) backed by the **same** personal/system VFS as the rest of the guest. **`run_js_script`** writes a temp **`.mjs`** under **`~/.agent/`** and executes it like a **`/bin`** script — the script body should use the same **`ctx`** patterns above when the harness passes **`ctx`**.
## Checklist before shipping
1. **`read_proc_file**` / `**get_system_info`** — confirm needed **features** and **caps** exist this session.
1. **`read_proc_file`** / **`get_system_info`** — confirm needed **features** and **caps** exist this session.
2. **Paths** — absolute, no **`..`** escape from allowed roots.
3. **Timeouts** — pass **`AbortSignal**` / `**timeoutMs**` to `**execLine**` / `**readLine`** for network or slow FS.
3. **Timeouts** — pass **`AbortSignal`** / **`timeoutMs`** to **`execLine`** / **`readLine`** for network or slow FS.
4. **Teardown** — unregister hooks, clear intervals, dispose IPC fanout subscribers.
5. **Secrets** — never log **`~/.agent/config.json**` or keys; redact in `**MEMORY.md`**.
5. **Secrets** — never log **`~/.agent/config.json`** or keys; redact in **`MEMORY.md`**.
## Output format (when this skill was used)
- **What you read** — which **`ctx**` fields or `**/proc`** files grounded the answer.
- **What you read** — which **`ctx`** fields or **`/proc`** files grounded the answer.
- **Plan** — file paths, entrypoint (`run` vs `start`), and exit semantics.
- **Risks** — policy gates, missing caps, host-only APIs.
@@ -10,40 +10,40 @@ requires: [read_man_page, read_file, vfs]
## When to use
Use when the user asks about **HDMS** (Hyperdrive Management): **`hdms**` CLI, `**/.bare/hdms/registry.json**`, `**/mnt/<label>**` mounts, **invite/pair** sharing, `**ctx.runHdms**`, `**ctx.bareOsSubscribeHdmsLifecycle**`, or how HDMS relates to `**login`** / guest mode.
Use when the user asks about **HDMS** (Hyperdrive Management): **`hdms`** CLI, **`/.bare/hdms/registry.json`**, **`/mnt/<label>`** mounts, **invite/pair** sharing, **`ctx.runHdms`**, **`ctx.bareOsSubscribeHdmsLifecycle`**, or how HDMS relates to **`login`** / guest mode.
## Prerequisites
- **HDMS activates after identity unlock.** Guest sessions can **list** mounts that are already open; **mutating** commands (**`create**`, `**add**`, registry edits, `**invite**`, `**pair**`, etc.) go through `**assertLoggedIn**`: require `**ctx.identity.state === 'unlocked'`** and an active HDMS controller.
- Implementation: **`packages/bare-os-booter/lib/hdms-manager.js**` (`**runHdmsCli**`, `**HdmsController**`), exposed as `**ctx.runHdms(argv)**` in `**packages/bare-os-booter/index.js`**.
- **HDMS activates after identity unlock.** Guest sessions can **list** mounts that are already open; **mutating** commands (**`create`**, **`add`**, registry edits, **`invite`**, **`pair`**, etc.) go through **`assertLoggedIn`**: require `**ctx.identity.state === 'unlocked'`** and an active HDMS controller.
- Implementation: **`packages/bare-os-booter/lib/hdms-manager.js`** (**`runHdmsCli`**, **`HdmsController`**), exposed as `**ctx.runHdms(argv)**` in **`packages/bare-os-booter/index.js`**.
## Registry and VFS
- **Registry path (constant):** **`/.bare/hdms/registry.json**` on the **personal** drive (`**HDMS_REGISTRY_PATH`**).
- **Registry path (constant):** **`/.bare/hdms/registry.json`** on the **personal** drive (**`HDMS_REGISTRY_PATH`**).
- **Writable mounts:** **`hdms create <label>`** — new Corestore namespace + Hyperdrive, replicate to swarm.
- **Read-only by key:** **`hdms add <label> <z32-key>`** — open an existing drive by key string.
- **VFS:** paths **`/mnt/<label>/…**`; writable mounts allow `**put`** on those routes.
- **`www` label:** A mount labeled **`www**` at `**/mnt/www**` also routes `**$HOME/.www**` and `**/home/<active>/.www**` in the VFS—the same docroot the stock `**bare-os-www**` initd serves by default. See `**handbook/05-identity-vault-and-hdms.md**` and `**handbook/04-the-booter-runtime.md`** § **bare-os-www**.
- **VFS:** paths **`/mnt/<label>/…**`; writable mounts allow **`put`** on those routes.
- **`www` label:** A mount labeled **`www`** at **`/mnt/www`** also routes **`$HOME/.www`** and **`/home/<active>/.www`** in the VFS—the same docroot the stock **`bare-os-www`** initd serves by default. See **`handbook/05-identity-vault-and-hdms.md`** and **`handbook/04-the-booter-runtime.md`** § **bare-os-www**.
## Invite and pair (Autopass / BlindPairing)
High-level behavior (details and caveats in **`handbook/05-identity-vault-and-hdms.md`**):
- **Invite with a drive:** **`hdms invite [--read-only] <label>**` stores a pending share for the peer. `**--rw**` uses a separate Autopass key (`**pending-share-rw**`) with `**signerKey**` + `**writerSecretHex**` so peers do not silently mount read-only when read/write was intended. **Anyone who can read the paired Autopass ledger can write the drive** — treat `**--rw`** as highly sensitive.
- **Invite with a drive:** **`hdms invite [--read-only] <label>**` stores a pending share for the peer. **`--rw`** uses a separate Autopass key (**`pending-share-rw`**) with **`signerKey`** + **`writerSecretHex`** so peers do not silently mount read-only when read/write was intended. **Anyone who can read the paired Autopass ledger can write the drive** — treat **`--rw`** as highly sensitive.
- **`hdms invite --read-only**` on a writable label sets the peers Autopass writer row read-only; **read-only Autobase writers are not append-capable**, so `**invite --read-only` + `pair` often fails** with “Not writable” / timeout — for normal HDMS pairing, omit **`--read-only`** unless you understand the limitation.
- **Pair:** **`hdms pair [--persist|--no-persist] <invite>**` — bounded waits (`**BARE_OS_HDMS_PAIR_WAIT_MS**`, `**BARE_OS_HDMS_PAIR_READY_MS**`, `**BARE_OS_HDMS_PAIR_SHARE_WAIT_MS**`, `**BARE_OS_HDMS_INVITE_CLEAR_MS**` — see env appendix / booter). Default persists to registry; `**--no-persist`** keeps the mount **ephemeral**. Inviter must stay **online** with matching **Hyperswarm bootstrap** or pairing stalls.
- **Invite without a label:** **`hdms invite**` (optional `**--read-only`**) only pairs Autopass; pending drive offers are cleared — **no automatic `/mnt` mount** for the peer.
- **Pair:** **`hdms pair [--persist|--no-persist] <invite>**` — bounded waits (**`BARE_OS_HDMS_PAIR_WAIT_MS`**, **`BARE_OS_HDMS_PAIR_READY_MS`**, **`BARE_OS_HDMS_PAIR_SHARE_WAIT_MS`**, **`BARE_OS_HDMS_INVITE_CLEAR_MS`** — see env appendix / booter). Default persists to registry; **`--no-persist`** keeps the mount **ephemeral**. Inviter must stay **online** with matching **Hyperswarm bootstrap** or pairing stalls.
- **Invite without a label:** **`hdms invite**` (optional **`--read-only`**) only pairs Autopass; pending drive offers are cleared — **no automatic `/mnt` mount** for the peer.
## Kernel hooks
- **`ctx.bareOsSubscribeHdmsLifecycle(fn)**` — callback with `**{ kind: 'afterActivate' | 'beforeDeactivate', labels?: string[] }**` so `**/boot/init.js`** can refresh mount-dependent state without forking HDMS.
- Stock booter also calls **`onAfterActivate**` on the `**hdms`** module export when present (see **developer-guide/11-kernel-pear-cookbook.md**).
- After **`applyUnlockedEnv**`, the booters `**onIdentityUnlocked**` path (`**packages/bare-os-booter/index.js**`) activates **Corestore**, **swarm**, the **personal** drive, and **HDMS** with the mount map. Custom `**/boot/init.js**` may assign `**ctx.onIdentityUnlocked**` for extra post-login hooks (see `**handbook/05-identity-vault-and-hdms.md`**).
- **`ctx.bareOsSubscribeHdmsLifecycle(fn)**` — callback with `**{ kind: 'afterActivate' | 'beforeDeactivate', labels?: string[] }**` so **`/boot/init.js`** can refresh mount-dependent state without forking HDMS.
- Stock booter also calls **`onAfterActivate`** on the **`hdms`** module export when present (see **developer-guide/11-kernel-pear-cookbook.md**).
- After **`applyUnlockedEnv`**, the booters **`onIdentityUnlocked`** path (**`packages/bare-os-booter/index.js`**) activates **Corestore**, **swarm**, the **personal** drive, and **HDMS** with the mount map. Custom **`/boot/init.js`** may assign **`ctx.onIdentityUnlocked`** for extra post-login hooks (see **`handbook/05-identity-vault-and-hdms.md`**).
## Execution steps (for the agent)
1. If the user is **guest**, explain that **mutations** require **`login**` / `**login --new**` first; `**hdms list`** may still work for existing mounts.
2. For **subcommands and flags**, prefer **`read_man_page hdms**` when available; otherwise cite `**handbook/05-identity-vault-and-hdms.md**` and `**packages/bare-os-booter/lib/hdms-manager.js`**.
1. If the user is **guest**, explain that **mutations** require **`login`** / `**login --new**` first; `**hdms list`** may still work for existing mounts.
2. For **subcommands and flags**, prefer **`read_man_page hdms**` when available; otherwise cite **`handbook/05-identity-vault-and-hdms.md`** and **`packages/bare-os-booter/lib/hdms-manager.js`**.
3. For **pairing failures**, check timeout env vars, bootstrap connectivity, and whether **`--read-only`** was used inappropriately on invites.
## Constraints
@@ -10,46 +10,46 @@ requires: [read_man_page, read_file, read_proc_file]
## When to use
Use when the user asks about **Holesail** in this repo: exposing TCP/UDP through Holepunch-style tunnels, **`/bin/holesail**` CLI, `**bare-holesail**` initd, `**BARE_OS_HOLESAIL_***` environment variables, `**ctx.bare.holesail**` from drive bundles, `**~/.holesail/state.json**` persistence (`**seed**` / `**key`**), or licensing (**upstream `holesail` is AGPL-3.0**).
Use when the user asks about **Holesail** in this repo: exposing TCP/UDP through Holepunch-style tunnels, **`/bin/holesail`** CLI, **`bare-holesail`** initd, **`BARE_OS_HOLESAIL_*`** environment variables, **`ctx.bare.holesail`** from drive bundles, **`~/.holesail/state.json`** persistence (**`seed`** / **`key`**), or licensing (**upstream `holesail` is AGPL-3.0**).
## Mental model
1. **Integration** lives in **`packages/bare-os-booter/lib/bare-holesail.js**` (initd + optional early “kernel-path” instance), `**bare-holesail-managed.js**` ( `**state.json**` rows, `**ensure**`, `**SyncPersistedServerKey**` ), `**holesail-cli.js**` (`**ctx.bareOsRunHolesailCli**` for `**/bin/holesail**`), `**bare-os-www-holesail.js**`, `**bare-os-ssh-holesail.js`**.
2. **Resolution order** under **`pear run**`: the booter prefers `**ctx.bare.holesail**` ( `**/lib/bare/bundles/holesail.js**` after drive merge), else host `**import.meta.resolve('holesail')**`, else eval of the drive IIFE bundle via `**ctx.vfs**``**/bin**` and `**/boot/init.js**` are **not** Node modules, so scripts must not `**require('holesail')`**.
3. **Stock default**: initd unit **`bare-holesail**` is **on** when `**BARE_OS_HOLESAIL_INITD**` and `**BARE_OS_HOLESAIL_MANAGED**` are left at defaults (`**1**` in stock `**shellEnv**` unless the host clears them). Disable with `**BARE_OS_HOLESAIL_INITD=0**` or `**systemctl disable bare-holesail**` (`**~/.config/bare-os/initd/disabled.txt`**).
4. **Stock auto-rows****`bare-www-<port>**` after `**bare-os-www**` listens (`**BARE_OS_WWW_HOLESAIL=0**` disables merge). `**bare-ssh-<port>**` after `**bare-openssh**` listens (`**BARE_OS_SSH_HOLESAIL=0**` disables). `**bare-user-session-stack**` re-ensures SSH tunnel after `**bare-holesail`** starts if sshd was already listening.
1. **Integration** lives in **`packages/bare-os-booter/lib/bare-holesail.js`** (initd + optional early “kernel-path” instance), **`bare-holesail-managed.js`** ( **`state.json`** rows, **`ensure`**, **`SyncPersistedServerKey`** ), **`holesail-cli.js`** (**`ctx.bareOsRunHolesailCli`** for **`/bin/holesail`**), **`bare-os-www-holesail.js`**, **`bare-os-ssh-holesail.js`**.
2. **Resolution order** under **`pear run**`: the booter prefers **`ctx.bare.holesail`** ( **`/lib/bare/bundles/holesail.js`** after drive merge), else host `**import.meta.resolve('holesail')**`, else eval of the drive IIFE bundle via **`ctx.vfs`** — **`/bin`** and **`/boot/init.js`** are **not** Node modules, so scripts must not `**require('holesail')`**.
3. **Stock default**: initd unit **`bare-holesail`** is **on** when **`BARE_OS_HOLESAIL_INITD`** and **`BARE_OS_HOLESAIL_MANAGED`** are left at defaults (**`1`** in stock **`shellEnv`** unless the host clears them). Disable with **`BARE_OS_HOLESAIL_INITD=0`** or `**systemctl disable bare-holesail**` (**`~/.config/bare-os/initd/disabled.txt`**).
4. **Stock auto-rows****`bare-www-<port>`** after **`bare-os-www`** listens (**`BARE_OS_WWW_HOLESAIL=0`** disables merge). **`bare-ssh-<port>`** after **`bare-openssh`** listens (**`BARE_OS_SSH_HOLESAIL=0`** disables). **`bare-user-session-stack`** re-ensures SSH tunnel after **`bare-holesail`** starts if sshd was already listening.
## Managed state (`state.json`)
- **Default path** — **`BARE_OS_HOLESAIL_STATE**` unset → `**~/.holesail/state.json**` (logical, under `**$HOME`**). Override env for a different logical path.
- **Legacy merge** — If the primary file is empty/missing: **`/.bare/holesail/state.json**`, `**/.bare/holesail/guest/state.json**`, `**/home/guest/.holesail/state.json`** are merged once.
- **`seed**` — Stable ctor secret: **64-char hex**, or valid **z32** suffix (migrated from legacy `**hs://…**`-only rows). Never replace `**seed`** with only the URL suffix written as ctor input.
- **`key**` — Full shareable `**hs://…**` URL; written/updated after `**ready()**` (`**bareHolesailManagedSyncPersistedServerKey**`). `**holesail list`** shows live URL when tunnel runs.
- **Daemon** — First **`startManagedConnectionsFromDisk**` pass starts all rows; **yield** one tick; **second pass** uses `**onlyNew**` so `**bare-os-www**` / `**bare-openssh`** can append rows without tearing down tunnels already started.
- **Default path** — **`BARE_OS_HOLESAIL_STATE`** unset → **`~/.holesail/state.json`** (logical, under **`$HOME`**). Override env for a different logical path.
- **Legacy merge** — If the primary file is empty/missing: **`/.bare/holesail/state.json`**, **`/.bare/holesail/guest/state.json`**, **`/home/guest/.holesail/state.json`** are merged once.
- **`seed`** — Stable ctor secret: **64-char hex**, or valid **z32** suffix (migrated from legacy `**hs://…**`-only rows). Never replace **`seed`** with only the URL suffix written as ctor input.
- **`key`** — Full shareable `**hs://…**` URL; written/updated after `**ready()**` (**`bareHolesailManagedSyncPersistedServerKey`**). `**holesail list`** shows live URL when tunnel runs.
- **Daemon** — First **`startManagedConnectionsFromDisk`** pass starts all rows; **yield** one tick; **second pass** uses **`onlyNew`** so **`bare-os-www`** / **`bare-openssh`** can append rows without tearing down tunnels already started.
## Managed vs single-tunnel mode
- **Managed (default)** — **`BARE_OS_HOLESAIL_MANAGED=1**`. Operator CLI: `**holesail list**`, `**add**`, `**remove**`, `**start**`, `**stop**`, `**restart**`, `**enable**`, `**disable**`, `**path**`, `**help`**.
- **Single tunnel** — **`BARE_OS_HOLESAIL_MANAGED=0**`, then exactly one of `**BARE_OS_HOLESAIL_SERVER=1**` or `**BARE_OS_HOLESAIL_CLIENT=1**`, and in client mode `**BARE_OS_HOLESAIL_KEY=…**`. Optional: `**BARE_OS_HOLESAIL_SECURE**`, `**PORT**`, `**HOST**`, `**UDP**`, `**LOG`**.
- **Managed (default)** — **`BARE_OS_HOLESAIL_MANAGED=1`**. Operator CLI: `**holesail list**`, **`add`**, **`remove`**, **`start`**, **`stop`**, **`restart`**, **`enable`**, **`disable`**, **`path`**, **`help`**.
- **Single tunnel** — **`BARE_OS_HOLESAIL_MANAGED=0`**, then exactly one of **`BARE_OS_HOLESAIL_SERVER=1`** or **`BARE_OS_HOLESAIL_CLIENT=1`**, and in client mode `**BARE_OS_HOLESAIL_KEY=…**`. Optional: **`BARE_OS_HOLESAIL_SECURE`**, **`PORT`**, **`HOST`**, **`UDP`**, **`LOG`**.
## Early booter (“kernel-path”) instance
Separate from initd: enable with **`BARE_OS_HOLESAIL_KERNEL=1**` and the `**BARE_OS_HOLESAIL_KERNEL_***` mirror env vars. Starts after the `**repl**` boot phase and before `**startBareInitd**`; teardown uses `**registerKernelShutdownHook**`. `**hs.pause()` / `hs.resume()`** tie into mobile suspend/resume.
Separate from initd: enable with **`BARE_OS_HOLESAIL_KERNEL=1`** and the **`BARE_OS_HOLESAIL_KERNEL_*`** mirror env vars. Starts after the **`repl`** boot phase and before **`startBareInitd`**; teardown uses **`registerKernelShutdownHook`**. `**hs.pause()` / `hs.resume()`** tie into mobile suspend/resume.
## Operator CLI quick reference
From **`holesail-cli.js`** help text:
- **`holesail add ID --server|--client**` with optional `**--key**`, bare `**hs://…**` token (no `**--key**` prefix), `**--port**`, `**--host**`, `**--udp**`, `**--secure` / `--no-secure**`, `**--log`**.
- **`holesail add ID --server|--client**` with optional **`--key`**, bare `**hs://…**` token (no **`--key`** prefix), **`--port`**, **`--host`**, **`--udp`**, `**--secure` / `--no-secure**`, **`--log`**.
- **`holesail remove ID**`, `**start|stop|restart ID**`, `**enable|disable ID`**.
Managed **`bare-holesail**` starts after `**kernel-logger**` and `**bare-os-www**` by default. Logs: `**/var/log/bare-os/holesail.log**`. Example unit drop-in: `**/etc/bare-os/units/bare-holesail.unit.example`**.
Managed **`bare-holesail`** starts after **`kernel-logger`** and **`bare-os-www`** by default. Logs: **`/var/log/bare-os/holesail.log`**. Example unit drop-in: **`/etc/bare-os/units/bare-holesail.unit.example`**.
## Debugging and safety
- **`BARE_OS_HOLESAIL_DEBUG=1`** — extra console lines (**URLs only**; keys are not logged in full).
- Do **not** paste full connection secrets into chat or commit logs; redact **`hs://`** payloads when summarizing.
- **`read_man_page holesail**` (after a coreutils/man build); `**handbook/04-the-booter-runtime.md`** § **bare-holesail**, § **bare-os-www**, § **bare-openssh** — prose source of truth.
- **`read_man_page holesail**` (after a coreutils/man build); **`handbook/04-the-booter-runtime.md`** § **bare-holesail**, § **bare-os-www**, § **bare-openssh** — prose source of truth.
## Execution steps (for the agent)
@@ -60,4 +60,4 @@ Managed **`bare-holesail**` starts after `**kernel-logger**` and `**bare-os-www*
## Constraints
- Read-only unless the user explicitly authorizes changing env, initd disables, or **`holesail add`** state.
- Do not assume **`holesail**` is `**import()**`-able from `**pear:**` without `**ctx.bare`** or the drive bundle.
- Do not assume **`holesail`** is `**import()**`-able from **`pear:`** without **`ctx.bare`** or the drive bundle.
@@ -14,11 +14,11 @@ Use this skill whenever the user asks for system status, peer count, drive healt
## Execution steps
1. Use **`list_directory**` / `**read_file**` on relevant `**/home/...`** paths (personal vs system) when the question is about files on Hyperdrive.
2. Call **`get_swarm_peers**` (and `**get_system_info`** as needed) for swarm / session context when exposed by the booter.
3. Use **`read_proc_file**` on `**/proc/bare_os/*`** mirrors when the user cares about kernel/session metrics (see the **bare-os-kernel-proc** skill for feature/capability JSON).
4. Check SSH/kernel narrative only when **`read_proc_file**` or `**read_man_page**` confirms how this image exposes `**sshd**` (do not assume `**node`** exists).
5. When a **personal static site** matters, after **`login**` check `**~/.www**` (and optional `**curl -I http://127.0.0.1:8088/**`, or the port from `**BARE_OS_WWW_PORT**` in env); initd logs append to `**/var/log/bare-os/www.log`**.
1. Use **`list_directory`** / **`read_file`** on relevant **`/home/...`** paths (personal vs system) when the question is about files on Hyperdrive.
2. Call **`get_swarm_peers`** (and **`get_system_info`** as needed) for swarm / session context when exposed by the booter.
3. Use **`read_proc_file`** on **`/proc/bare_os/*`** mirrors when the user cares about kernel/session metrics (see the **bare-os-kernel-proc** skill for feature/capability JSON).
4. Check SSH/kernel narrative only when **`read_proc_file`** or **`read_man_page`** confirms how this image exposes **`sshd`** (do not assume **`node`** exists).
5. When a **personal static site** matters, after **`login`** check **`~/.www`** (and optional `**curl -I http://127.0.0.1:8088/**`, or the port from **`BARE_OS_WWW_PORT`** in env); initd logs append to **`/var/log/bare-os/www.log`**.
6. Summarize in clear bullet points:
- Drive sync status