Add article
This commit is contained in:
@@ -0,0 +1,302 @@
|
|||||||
|
<!-- lead -->
|
||||||
|
Deep Dive: Bare Operating System, a P2P Replicated Hyperdrive Image
|
||||||
|
|
||||||
|
## <center>Repo: https://git.ssh.surf/snxraven/bare-operating-system</center><BR>
|
||||||
|
|
||||||
|
<video
|
||||||
|
autoplay
|
||||||
|
muted
|
||||||
|
playsinline
|
||||||
|
controls
|
||||||
|
width="100%"
|
||||||
|
preload="none"
|
||||||
|
style="max-width:960px; display:block; margin:0 auto;">
|
||||||
|
<source src="https://www.x64.world/2026-04-05-04-33-58.av1.mp4" type="video/mp4">
|
||||||
|
Your browser does not support the video tag.
|
||||||
|
</video>
|
||||||
|
|
||||||
|
Most “operating systems” assume a single publisher pushes a monolithic image through HTTP, package managers, or physical media. **Bare OS** inverts part of that assumption on purpose. The project treats the stock system tree as a **Hyperdrive** artifact that **Hyperswarm** peers discover and replicate, with **Protomux** carrying a typed control plane alongside replication. The canonical repository lives on Gitea as [snxraven/bare-operating-system](https://git.ssh.surf/snxraven/bare-operating-system). The [README](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/README.md) is explicit: this is **experimental research software**, not a production OS. That caution matters because the design touches **peers**, **keys**, **vault material**, and **network exposure** in ways that resemble cryptocurrency wallets and P2P apps more than a traditional desktop distribution.
|
||||||
|
|
||||||
|
The motivating vision is nonetheless sharp. If you believe that **self hosting** and **decentralized distribution** should be first class, then the artifact you boot should be the same replicated structure your friends, colleagues, or fleet operators can obtain without a single CDN choke point. Bare OS is a **P2P first** “system image” in that sense: a **seeder** stages the kernel tree into a system Hyperdrive and publishes a tiny **512 byte MBR** as block zero; a **booter** joins the swarm, reads the MBR, opens the system drive, attaches a separate **personal** Hyperdrive for mutable state, constructs a rich **`ctx`** object, and executes **`/boot/init.js`**. The stack is intentionally aligned with **Holepunch** style runtimes (**Bare** and **Pear**), so the same ecosystem that already thinks in terms of **Hypercore**, **Hyperdrive**, and encrypted streams can reason about an “OS shaped” guest without pretending the guest is Linux.
|
||||||
|
|
||||||
|
This article walks the architecture end to end using [the repository tree](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/) as the source of truth: [README](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/README.md), [handbook](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/), [developer guide](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/developer-guide/), [user manual](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/users-manual/), [docs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/), [`kernel/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/), and [`packages/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/). The goal is a developer grade map of what exists today, why the pieces are split the way they are, and where the hard edges live.
|
||||||
|
|
||||||
|
## Why P2P first, and why a fully replicated OS image matters
|
||||||
|
|
||||||
|
A replicated OS image is not merely a convenience for offline installs. In Bare OS it is the **contract** between publishers and consumers. The handbook’s protocol chapter ([Chapter 3 — Protocol, MBR, and SwarmDisk](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/03-protocol-and-disk.md)) stresses a design choice that surprises newcomers: the booter **does not** silently fall back to your git checkout’s `kernel/` when the network fails. It always tries to obtain block zero through the swarm backed **`SwarmDisk`**. If nobody seeds, you do not boot. That sounds harsh until you treat **availability** as a first class input to your operator model: replication forces you to confront who is online, which discovery keys you trust, and how you observe stalled replication.
|
||||||
|
|
||||||
|
Splitting **system** bytes from **personal** bytes is the other half of the story. If the entire world lived on one writable drive, every OS update would risk clobbering user state, and every user backup would fork the “canonical” tree. Bare OS instead separates:
|
||||||
|
|
||||||
|
* a **system** Hyperdrive that holds the read mostly stock tree (`/boot`, `/bin`, `/etc`, `man` JSON, optional `/lib/bare` bundles)
|
||||||
|
* a **personal** Hyperdrive that holds **`$HOME`**, **`/.bare`**, logs, crontab, and anything that must survive across boots but must **not** be overwritten when the system image advances
|
||||||
|
|
||||||
|
That split is documented as a concept page and encoded as ADR [docs/adr/0001-two-drive-p2p-model.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/adr/0001-two-drive-p2p-model.md), with implementation anchors in [packages/bare-os-booter/lib/vfs.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/vfs.js) and [packages/bare-os-booter/lib/swarm-disk.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/swarm-disk.js). The payoff is operational: you can replicate a **shared** OS image across many machines while each machine (or identity) keeps its own mutable namespace, including encrypted vault snapshots and HDMS mount registries.
|
||||||
|
|
||||||
|
## High level architecture: seeder, booter, and the stock kernel
|
||||||
|
|
||||||
|
At the highest level, Bare OS is almost always a **two process** dev workflow: run a **seeder** in one terminal and a **booter** in another. The repository’s [README.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/README.md) recommends Pear based entry points:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://git.ssh.surf/snxraven/bare-operating-system.git
|
||||||
|
cd bare-operating-system
|
||||||
|
npm ci
|
||||||
|
```
|
||||||
|
|
||||||
|
Terminal A:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run os:seeder
|
||||||
|
```
|
||||||
|
|
||||||
|
Terminal B:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run os:booter
|
||||||
|
```
|
||||||
|
|
||||||
|
Those scripts run **`pear run --dev`** after linking hoisted workspace dependencies, matching the “real host” story in [docs/PEAR-RUN.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/PEAR-RUN.md) and the [bare-os-seeder README](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-seeder/README.md).
|
||||||
|
|
||||||
|
The **seeder** ([`packages/bare-os-seeder/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-seeder/)) owns the canonical **system** Hyperdrive. It resolves a kernel root (`BARE_OS_KERNEL_ROOT` or the vendored `kernel/` tree), runs **`stageKernelTree`** to map host paths into drive paths (`init.js` becomes `/boot/init.js`, `bin/*` becomes `/bin/*`, `etc/*` becomes `/etc/*`, and the README at the kernel root is skipped so you do not accidentally install `/README.md`), builds the MBR with `buildMbr(drive.key)`, joins Hyperswarm on `topicKey()` derived from the string `bare-os-v1`, and on each connection sets up **Protomux** with `setupSeedChannel` so peers can read RAM backed block indices (index `0` is the MBR) and attach `drive.replicate(stream)`.
|
||||||
|
|
||||||
|
The **booter** ([`packages/bare-os-booter/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/)) mirrors that behavior from the consumer side. **`SwarmDisk`** implements **`read(index)`** by broadcasting message `0` to peers when local RAM does not satisfy the read, then awaiting message `1`. **`addPeer`** opens the channel and replicates the **system** drive (and later the **personal** drive) on the mux stream. After replication succeeds and `/boot/init.js` exists, the booter runs **`executeKernel`**, which is the long pipeline described in [handbook Chapter 4 — The booter runtime](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/04-the-booter-runtime.md): construct shell environment defaults, build IPC and VFS, merge optional **`ctx.bare`** modules, wire identity hooks, start **bare initd**, then call **`runKernelFromSource`** on the kernel text.
|
||||||
|
|
||||||
|
The **stock kernel** is not a microkernel. It is JavaScript on the system drive at `/boot/init.js`, executed as described in [developer-guide/03-kernel-boot-init.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/developer-guide/03-kernel-boot-init.md). The committed [kernel/init.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/init.js) is a **bundle**: sorted fragments under [`kernel/lib/boot/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/boot/) and [`kernel/lib/init/fragments/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/init/fragments/) plus [kernel/lib/init/init-main.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/init/init-main.js). Maintainers run `npm run bundle:kernel` after edits; CI verifies parity. The kernel’s job is to orchestrate boot snippets (`/etc/bare-os/rc`, `rc.d`, `kernel.d`, optional extension lists), print banners, and enter the interactive loop that calls `ctx.readLine` and `ctx.execLine`.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
subgraph seederSide [Seeder]
|
||||||
|
K[kernelTreeOnDisk]
|
||||||
|
D[systemHyperdrive]
|
||||||
|
M[mbrBlock0]
|
||||||
|
end
|
||||||
|
subgraph swarmSide [HyperswarmTopic]
|
||||||
|
T[encryptedSessions]
|
||||||
|
end
|
||||||
|
subgraph booterSide [Booter]
|
||||||
|
S[SwarmDisk]
|
||||||
|
P[personalHyperdrive]
|
||||||
|
C[ctxAndVfs]
|
||||||
|
Init["/boot/init.js"]
|
||||||
|
end
|
||||||
|
K --> D
|
||||||
|
D --> M
|
||||||
|
M --> T
|
||||||
|
T --> S
|
||||||
|
S --> D
|
||||||
|
S --> P
|
||||||
|
D --> C
|
||||||
|
P --> C
|
||||||
|
C --> Init
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kernel source layout and bundling
|
||||||
|
|
||||||
|
You should never edit [kernel/init.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/init.js) by hand in a long lived branch. The developer guide points contributors at [kernel/lib/init/STRUCTURE.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/init/STRUCTURE.md), which explains how sorted fragments under [`kernel/lib/boot/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/boot/) and [`kernel/lib/init/fragments/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/init/fragments/) concatenate ahead of [kernel/lib/init/init-main.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/init/init-main.js). That layout keeps boot policy, extension loaders, and the REPL loop separated for review and testing while still shipping a **single** guest visible file at `/boot/init.js`. After changes, run:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run bundle:kernel
|
||||||
|
```
|
||||||
|
|
||||||
|
Then use `npm run verify:init-bundle` or rely on root `pretest` to prove the bundle matches what CI expects. The same discipline applies to seeder parity: [`packages/bare-os-seeder/kernel/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-seeder/kernel/) must remain **byte identical** to [`kernel/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/), enforced by [scripts/verify-kernel-seeder-parity.mjs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/scripts/verify-kernel-seeder-parity.mjs) during `pretest`.
|
||||||
|
|
||||||
|
## The two drive model and the virtual filesystem
|
||||||
|
|
||||||
|
ADR 0001 names the mental model that every utility author must internalize: **which drive owns this path?** The VFS in [packages/bare-os-booter/lib/vfs.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/vfs.js) mounts both Hyperdrives into one logical POSIX shaped tree.
|
||||||
|
|
||||||
|
* Paths under **`$HOME`** resolve to the personal Hyperdrive under **`/.bare-os/home/<HOME-basename>/…`**
|
||||||
|
* Writable **`/var/log`** maps to **`/.bare-os/var/log/<basename>/…`**
|
||||||
|
* Writable **`/tmp`** maps to **`/.bare-os/tmp/<basename>/…`** (session isolated scratch)
|
||||||
|
* Optional **`BARE_OS_PERSONAL_ACCT_PREFIX=1`** nests those subtrees under **`/.bare-os/acct/<id>/…`** for multi account experiments documented in [docs/design/multi-account-personal-subvolumes.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/design/multi-account-personal-subvolumes.md)
|
||||||
|
* Most other absolute paths hit the **system** drive
|
||||||
|
|
||||||
|
Guest versus unlocked identity affects **`/.bare`**. In **guest** mode, sensitive names such as **`/.bare/account`** and **`/.bare/vault/**`** are hidden or denied unless **`BARE_OS_GUEST_BARE_READ_ALL=1`**. **`login`** and **`logout`** clear warm caches and reset simulated shell jobs so sessions do not leak across principals.
|
||||||
|
|
||||||
|
Synthetic namespaces make scripts feel familiar without pretending to be Linux:
|
||||||
|
|
||||||
|
* **`/proc`** exposes JSON and text probes such as **`/proc/bare_os_features`**, **`/proc/bare_os/syscalls.json`**, replication hints, initd graphs, metrics, and session stats
|
||||||
|
* **`/sys`** includes small stubs like **`class/net/lo`** whose text reflects swarm peer counts in stock configurations
|
||||||
|
* **`/run/bare-os/`** holds boot profile lines, session UUIDs, initd journals, and optional virtual files registered by the kernel
|
||||||
|
* **`/dev/null`**, **`/dev/zero`**, and **`/dev/shm`** provide minimal device semantics for tests and scripts
|
||||||
|
|
||||||
|
The handbook is honest about **non goals**: there are no real host PIDs, no faithful **`meminfo`**, and no guarantee of path parity with Linux. What you get is a coherent **inspection surface** and stable hooks for operators.
|
||||||
|
|
||||||
|
Operators who want a second logical mount point into the **same** read only system image can set **`BARE_OS_VFS_SYSTEM_RO_ALIAS`** to an absolute prefix (for example `/snapshot/system`). The VFS routes that prefix to the system Hyperdrive with writes denied, and the path shows up in `/proc/mounts` as `bare-os-system-ro-alias`. That pattern helps documentation and scripts that expect a distinct versioned root without opening another Hyperdrive handle.
|
||||||
|
|
||||||
|
## Boot protocol: MBR, Hyperswarm, Protomux, and `bare-os-v1`
|
||||||
|
|
||||||
|
Wire level truth lives in [`packages/bare-os-protocol/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-protocol/) and [docs/reference/package-bare-os-protocol.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/package-bare-os-protocol.md). The exported constants tell the whole headline story:
|
||||||
|
|
||||||
|
* **`TOPIC_STRING`** is `bare-os-v1`, hashed by **`topicKey()`** into a 32 byte Hyperswarm topic
|
||||||
|
* **`PROTOCOL_NAME`** is also `bare-os-v1`, naming the **Protomux** channel
|
||||||
|
* **`BLOCK_SIZE`** is `512` for the MBR
|
||||||
|
* **`MBR_MAGIC`** is the ASCII bytes `BIOS` at offset zero
|
||||||
|
* **`buildMbr(primaryKey, failoverKeys?)`** writes the primary 32 byte system drive key at offset **8**, with optional failover keys at offsets **40** and **72**
|
||||||
|
* **`parseMbr`** validates length, magic, and returns an array of non zero 32 byte key slots
|
||||||
|
|
||||||
|
On the channel, compact encoded messages implement boot critical reads plus operator features (full message ID table in [Chapter 3](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/03-protocol-and-disk.md#message-ids--what-each-is-for)):
|
||||||
|
|
||||||
|
* **0 / 1** fetch RAM blocks by index (block zero is the MBR) when the booter has no local copy, then return bytes
|
||||||
|
* **2** carries a capability gossip stub bitfield (250 bytes; see [kernel feature bits](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/kernel-extensions.md))
|
||||||
|
* **3 / 4** implement manifest search requests and responses
|
||||||
|
* **5 / 6** implement **`bare_os.*`** RPC requests and responses (version, health, kernel info, capabilities, replication status, and related methods documented in the handbook)
|
||||||
|
|
||||||
|
Hyperdrive replication rides the **same** encrypted stream once the channel is up. Optional **`bare-os-app-v1`** can be enabled with **`BARE_OS_PROTOMUX_APP_CHANNEL`** for namespaced application RPC alongside the OS control plane.
|
||||||
|
|
||||||
|
The booter’s happy path, repeated in [docs/concepts/boot-and-init-timeline.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/concepts/boot-and-init-timeline.md), is:
|
||||||
|
|
||||||
|
1. Join the swarm topic and wait for peers (subject to **`BARE_OS_BOOT_TIMEOUT_MS`**, default `60000` ms)
|
||||||
|
2. Read block `0`, **`parseMbr`**, try each key until a Hyperdrive opens and replicates until **`/boot/init.js`** exists
|
||||||
|
3. Initialize the **personal** drive and join its **discovery key** so **`$HOME`** can replicate across **your** devices when peers share that key
|
||||||
|
4. **`executeKernel`**: build **`ctx`**, run **`start(ctx)`** from `/boot/init.js`
|
||||||
|
|
||||||
|
**Personal replication** is orthogonal to the MBR: `SwarmDisk.initPersonalDrive` creates a separate Hyperdrive in a stable Corestore namespace and joins `swarm.join(personalDrive.discoveryKey)`. Multi device sync for your home directory only happens when another device joins the **same** personal discovery key. There is no hosted cloud account in the stock design, only P2P semantics and operator discipline about backups.
|
||||||
|
|
||||||
|
For lab setups where the swarm is intentionally unavailable, [docs/reference/compatibility-matrix.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/compatibility-matrix.md) documents an **offline last known good** path: when **`BARE_OS_OFFLINE_LKG_BOOT=1`** and **`BARE_OS_LKG_SYSTEM_KEY_HEX`** are set, a booter can skip the peer wait while still requiring that the system drive already contains `/boot/init.js` in Corestore. That is a sharp tool for CI and air gapped experiments, not a replacement for understanding replication.
|
||||||
|
|
||||||
|
## `executeKernel`, `ctx`, and the line shell
|
||||||
|
|
||||||
|
[Handbook Chapter 4](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/04-the-booter-runtime.md) is the map of the simulated machine. **`ctx`** is the single handle passed into `/boot/init.js` and every `/bin` utility. Major fields include:
|
||||||
|
|
||||||
|
* **`ctx.vfs`**: `readFile`, `writeFile`, `stat`, `chdir`, and related operations across both drives
|
||||||
|
* **`ctx.console`**: `log` / `error` wired to the session console
|
||||||
|
* **`ctx.execLine`** / **`ctx.readLine`**: the **line shell** and prompt input
|
||||||
|
* **`ctx.runBinCommand`**: run `/bin` commands with an argv array (no shell parsing)
|
||||||
|
* **Identity hooks** for guest versus unlocked sessions
|
||||||
|
* Optional **`ctx.bare`**: merged Bare module map when host imports and drive bundles are enabled
|
||||||
|
* Policy surfaces: **`ctx.bareOsRuntimeCaps`**, optional **`httpFetch`** for delegated **`curl` / `wget`**, IPC FIFOs, audit flags, Pear reload requests, and many environment driven toggles documented in [docs/reference/environment-and-posix-appendix.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/environment-and-posix-appendix.md)
|
||||||
|
|
||||||
|
**`execShellLine`** ([packages/bare-os-booter/lib/shell.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/shell.js)) implements tokenization, pipelines, redirections, a curated builtin set (`cd`, `export`, `login`, `logout`, job control stubs, bounded `if` / `while` / `for` / optional `case`), and external commands via **`runBinCommand`**. Pipelines are **simulated** captures rather than OS level pipes, which is a fundamental POSIX stance choice documented in [docs/architecture/POSIX_DECLARED_PROFILE.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/architecture/POSIX_DECLARED_PROFILE.md) and ADR [docs/adr/0003-posix-facade-no-fork.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/adr/0003-posix-facade-no-fork.md).
|
||||||
|
|
||||||
|
**`runBinCommand`** ([packages/bare-os-booter/lib/kernel-runner.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/kernel-runner.js)) resolves scripts on the **system** drive’s **`PATH`** for bare names, resolves explicit paths through the VFS, strips an optional shebang, compiles the body with **`AsyncFunction`**, then **awaits** a top level **`run(ctx, argv)`** when defined. Kernel entry is different: **`runKernelFromSource`** requires a top level **`async function start(ctx)`**.
|
||||||
|
|
||||||
|
### Init services, cron, and delegated control plane bits
|
||||||
|
|
||||||
|
After `ctx.execLine` exists, the booter starts **bare initd** ([packages/bare-os-booter/lib/bare-initd.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/bare-initd.js)) before invoking the kernel. Initd registers units declared in the stock image and merges drop ins from the personal drive under `~/.config/bare-os/units/` and `units.d/`, respects dependency edges (`After=`, `Before=`, `Requires=`, …), and supports socket activation style deferral via FIFO reads. Built in **`kernel-logger`** mirrors `ctx.console` output into `/var/log/bare-os/kernel-console.log` on the personal tree, trimming large files so logging cannot fill the drive unbounded.
|
||||||
|
|
||||||
|
**`/bin/systemctl`** is **not** an in image script evaluated like coreutils. The handbook notes that **`kernel-runner`** delegates to [packages/bare-os-booter/lib/systemctl-cli.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/systemctl-cli.js), exposing `list`, `status`, `logs`, `start`, `stop`, `restart`, `enable`, and `disable` against the same registry that initd uses. **`journalctl -u`** tails the structured NDJSON journals under `/run/bare-os/unit-journal/` when present. That split matters for security reasoning: the service control plane is host implemented and versioned with the booter package, while unit **definitions** can still ship on the system drive or in user overlays.
|
||||||
|
|
||||||
|
**bare cron** reads `/etc/bare-os/crontab` from the system image and `~/.crontab` from the personal drive, plus timer drop ins under `~/.config/bare-os/timers/*.timer`. Jobs execute through `ctx.execLine`, so they inherit the same shell semantics and quotas as interactive use. Installing a user crontab requires an **unlocked** identity so arbitrary guests cannot overwrite scheduled commands.
|
||||||
|
|
||||||
|
## Host runtime versus image runtime
|
||||||
|
|
||||||
|
[developer-guide/01-two-runtimes-host-vs-image.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/developer-guide/01-two-runtimes-host-vs-image.md) is the document every new contributor should read twice. **Host** code (Pear or Node packages under [`packages/bare-os-booter/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/) and [`packages/bare-os-seeder/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-seeder/)) is normal ESM: `import`, `node_modules` or Bare shims, real async I/O. **In image** code (`/boot/init.js`, `/bin/*`, scripts under `$HOME`) is loaded as a **UTF 8 string** and evaluated with **`new AsyncFunction`**. There is **no** ES module graph on the drive, so top level `import` from `'node:fs'` cannot work.
|
||||||
|
|
||||||
|
That split is a trust and ergonomics boundary:
|
||||||
|
|
||||||
|
* The **system** drive is the replicated OS image; treat its contents as part of your integrity and signing story
|
||||||
|
* The **personal** drive is writable; a script in your home directory still receives full **`ctx`** power, which is convenient and dangerous
|
||||||
|
|
||||||
|
CI enforces **Bare first** host policy for Pear bundled sources: [scripts/verify-pear-no-static-node-import.mjs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/scripts/verify-pear-no-static-node-import.mjs) rejects static `node:` specifiers in the booter and seeder lib trees with documented exceptions, pushing authors toward **`#host-fs`** style imports.
|
||||||
|
|
||||||
|
## POSIX stance: declared profile, `ctx` API version, and the 149 utilities
|
||||||
|
|
||||||
|
Bare OS publishes a **declared POSIX like profile**, not a conformance claim. [docs/architecture/POSIX_DECLARED_PROFILE.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/architecture/POSIX_DECLARED_PROFILE.md) states **`BARE_OS_POSIX_PROFILE_VERSION`** `1.0.19` and profile id `bare-os-posix-like`, anchored in [packages/bare-os-protocol/lib/bare-os-posix-profile.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-protocol/lib/bare-os-posix-profile.js). The **`ctx`** API carries its own semver: **`bareOsCtxApiVersion`** is **`1.54.0`** in the stock tree per [docs/reference/compatibility-matrix.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/compatibility-matrix.md), defined in [packages/bare-os-booter/lib/bare-os-ctx-api.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/bare-os-ctx-api.js).
|
||||||
|
|
||||||
|
Userland breadth is real for a research prototype. The README advertises **149** POSIX oriented utilities. The authoritative name list is **`COREUTILS_COMMANDS`** in [packages/bare-os-coreutils/lib/commands.mjs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-coreutils/lib/commands.mjs), consumed by [packages/bare-os-coreutils/build.mjs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-coreutils/build.mjs) and the man database scripts. Root **`pretest`** runs **`verify-man-coverage`** so [kernel/share/man/man.json](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/share/man/man.json) stays aligned with that list.
|
||||||
|
|
||||||
|
Handbook Chapter 9 ([handbook/09-posix-utilities-shell-and-vfs.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/09-posix-utilities-shell-and-vfs.md)) is the narrative index into that surface: how **`PATH`** resolution prefers the system drive, how **`mkdir` / `rmdir`** cooperate with Hyperdrive directory semantics via `.bareos_empty` markers, and how optional **`BARE_OS_VFS_UNION_PREFIXES`** layers reads across multiple logical sources. Delegated network clients deserve a separate mention: **`curl`** and **`wget`** are implemented as host delegates with policy allowlists (`BARE_OS_HTTP_ALLOWLIST`, `BARE_OS_HTTP_DENYLIST`, optional TLS pins) as documented in [docs/reference/http-curl-and-wget.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/http-curl-and-wget.md), while `/bin/curl` and `/bin/wget` on the image may be manifest stubs so sessions do not accidentally bypass the delegate path.
|
||||||
|
|
||||||
|
The shell exposes pipelines, redirects, aliases, and a restricted **`~/.barerc`** (only `export`, `alias`, `unalias` forms; no arbitrary `source`). Interactive sessions can use the fish style line editor ([packages/bare-os-booter/lib/fish-readline.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/fish-readline.js)) when stdin and stdout are TTYs and **`BARE_OS_FISH` is not `0`**. History files live on the **personal** drive keyed by identity so guests and logged in users do not stomp each other. Online help merges JSON handbook pages with generated coreutils man entries; [docs/reference/shell-completion-and-repl-editor.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/shell-completion-and-repl-editor.md) documents completion tables sourced from [kernel/lib/bare/shell-completion.json](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/bare/shell-completion.json) and related artifacts.
|
||||||
|
|
||||||
|
## Identity, encrypted vault, and HDMS
|
||||||
|
|
||||||
|
[Handbook Chapter 5 — Identity, vault, and HDMS](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/handbook/05-identity-vault-and-hdms.md) explains the lifecycle from cold boot to extra mounts:
|
||||||
|
|
||||||
|
1. **Guest** defaults: `USER=guest`, `HOME=/home/guest`, no public key material in the environment
|
||||||
|
2. **`login`**: decrypt an existing **`/.bare/account`** blob or create a new Ed25519 account with **`login --new`**
|
||||||
|
3. **Unlocked** session: `HOME` moves under `/home/<pubkey-prefix>`, `BARE_OS_PUBLIC_KEY` is set, HDMS can attach additional Hyperdrives
|
||||||
|
4. **`hdms create` / `hdms add`**: writable or read only drives appear under `/mnt/<label>` backed by a registry JSON on the personal drive
|
||||||
|
5. **`logout`**: sensitive material is zeroed; **`logout --save`** or **`savevault`** can snapshot selected paths into **`/.bare/vault/`** as encrypted records
|
||||||
|
|
||||||
|
The on disk account format (**v2**) uses magic `BAREOS01`, PBKDF2 SHA256 parameters, and ChaCha20 Poly1305 sealing over secret key material via **`bare-crypto`**. Vault cryptography is only as strong as passphrases, backups, and who can replicate your personal drive, which is why [docs/security/vault-threat-model.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/security/vault-threat-model.md) belongs in any serious deployment reading list.
|
||||||
|
|
||||||
|
## Post boot operator surface: `disk.os`, seed RPC, and observability
|
||||||
|
|
||||||
|
After **bare initd** starts, the stock booter assigns **`disk.os`** on **`SwarmDisk`**. Peers can use the same Protomux channel to query the **running** booter: **`searchLocal`** for path discovery and **`execRpc`** for a strict allowlist of **`bare_os.*`** methods (ping, ctx API version, uptime, service names, package index reads, replication operator sketches, and more). Implementation lives in [packages/bare-os-booter/lib/bare-os-disk-os-bridge.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/bare-os-disk-os-bridge.js), with architecture cross links in [docs/architecture/KERNEL_CONTRACT.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/architecture/KERNEL_CONTRACT.md).
|
||||||
|
|
||||||
|
The project also invests heavily in **observability contracts**: optional NDJSON telemetry paths, structured boot traces, coalesced metrics under **`/proc/bare_os/metrics_live.json`**, and schema versioned lifecycle records described in the [README](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/README.md) and [docs/reference/observability-contracts.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/observability-contracts.md). The goal is not “more logs for fun” but **operator debuggability** in a system where failures may be replication stalls, capability mismatches, or personal drive admission policy issues rather than simple file not found errors on a local disk.
|
||||||
|
|
||||||
|
## `ctx.bare`, `/lib/bare`, and the Pear ecosystem
|
||||||
|
|
||||||
|
[developer-guide/12-bare-modules-and-pear-ecosystem.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/developer-guide/12-bare-modules-and-pear-ecosystem.md) ties Bare OS to the wider Holepunch **`bare-*`** package set. There are four practical tiers:
|
||||||
|
|
||||||
|
1. **`/lib/bare` on the system image**, built by **`bare-os-bare-libs`** into [`kernel/lib/bare/bundles/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/bare/bundles/) `*.js` with a [manifest.json](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/bare/manifest.json)
|
||||||
|
2. **Pear booter manifest data** embedded as [packages/bare-os-booter/lib/bare-module-manifest.data.mjs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/bare-module-manifest.data.mjs) because `bare-fs` cannot open `pear:` URLs the same way as `file:` checkouts
|
||||||
|
3. **Host imports** filling in missing keys when **`BARE_OS_BARE_HOST_IMPORTS` is not `0`**
|
||||||
|
4. **The full public catalog** as discoverability metadata; not every package bundles cleanly into drive IIFEs
|
||||||
|
|
||||||
|
Maintenance commands at the repo root refresh the catalog and sync manifests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run gen:bare-catalog
|
||||||
|
npm run sync:bare-manifest
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
After manifest edits, `npm run build -w bare-os-bare-libs` refreshes `/lib/bare` in `kernel/`, then you re run the seeder so peers receive updated bundles. Pear workflows also call out [scripts/ensure-pear-node-modules.mjs](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/scripts/ensure-pear-node-modules.mjs) so hoisted dependencies resolve under `pear run`, documented in [docs/PEAR-RUN.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/PEAR-RUN.md).
|
||||||
|
|
||||||
|
Pear IPC registry helpers (`ctx.bareOsPearIpcEmit`, optional request or response patterns) let embedded hosts react to reload, mirror, and telemetry hints without forking the guest kernel. That is how Bare OS stays a **guest** while still participating in a Pear app’s lifecycle.
|
||||||
|
|
||||||
|
## Development workflow, testing, and extensibility
|
||||||
|
|
||||||
|
Day to day development combines Node for fast tests, Bare for crypto parity, and Pear for production like bundles. From the repo root:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm ci
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
**`pretest`** is a contract gate: it builds coreutils and bare libs, verifies **kernel** versus **`packages/bare-os-seeder/kernel/`** byte identity, checks **`ctx`** API and feature bits alignment, validates doc links, enforces man coverage, refreshes or verifies POSIX dashboards, and runs Pear import policy guards. The script inventory is summarized in [scripts/README.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/scripts/README.md).
|
||||||
|
|
||||||
|
[developer-guide/08-testing-and-debugging.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/developer-guide/08-testing-and-debugging.md) splits expectations across **`brittle-node`** (most of [packages/bare-os-booter/test.js](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/test.js), including VFS and shell behavior against real `/bin` bytes) and **`brittle-bare`** (identity and protocol tests that need the Bare runtime). `npm run test:bare` offers a lighter Bare native smoke path. Separate marker gates reject `TODO` style debris in hand authored kernel and booter sources while applying a stricter allowlist policy to vendored Holepunch IIFEs under [`kernel/lib/bare/bundles/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/bare/bundles/), documented in [docs/audit/PLACEHOLDER_BASELINE.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/audit/PLACEHOLDER_BASELINE.md).
|
||||||
|
|
||||||
|
Extending the system usually means one of:
|
||||||
|
|
||||||
|
* Add or modify a **`/bin`** utility in [`packages/bare-os-coreutils/src/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-coreutils/src/) and rebuild
|
||||||
|
* Change **`/boot/init.js` indirectly** by editing fragments under [`kernel/lib/init/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/lib/init/) and bundling
|
||||||
|
* Change **host behavior** in [`packages/bare-os-booter/lib/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/lib/) when you need real imports, Hyperswarm policy, or new `ctx` fields (bump **`bareOsCtxApiVersion`** and update [packages/bare-os-booter/CHANGELOG.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/packages/bare-os-booter/CHANGELOG.md) when guest visible behavior changes)
|
||||||
|
|
||||||
|
Kernel hot reload and profile warm reload hooks exist for development (`BARE_OS_KERNEL_HOT_RELOAD`, `BARE_OS_KERNEL_PROFILE_WARM`) so you can iterate on `start(ctx)` without always restarting swarm sessions.
|
||||||
|
|
||||||
|
## Technical challenges, explicit tradeoffs, and governance artifacts
|
||||||
|
|
||||||
|
Several challenges show up repeatedly in issues, logs, and ADRs:
|
||||||
|
|
||||||
|
* **Availability versus convenience:** refusing to boot from an unverified local checkout path is a product decision masquerading as engineering strictness. It keeps demos honest.
|
||||||
|
* **Capability negotiation:** `BARE_OS_SEED_CAP_STRICT` and related gates align seeder and booter expectations against **`bare_os.capabilities`** RPC payloads and **`kernelCapabilityWords`** wire v2 structures documented in [docs/reference/kernel-extensions.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/reference/kernel-extensions.md).
|
||||||
|
* **POSIX fidelity limits:** simulated pipelines, no `fork`, and errno behavior that is documented but not Linux identical mean scripts must be tested on Bare OS itself, not assumed from GNU or BSD habits.
|
||||||
|
* **Trust expansion:** enabling **`BARE_OS_BARE_MODULES`**, drive bundles, HTTP delegates, or extension graphs increases attack surface; boot policy examples under [`kernel/etc/bare-os/`](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/kernel/etc/bare-os/) show how operators think about pins, signers, and hashes.
|
||||||
|
|
||||||
|
ADR [docs/adr/0002-deny-default-rpc-hrpc.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/docs/adr/0002-deny-default-rpc-hrpc.md) and related security docs encode the stance that **default open** RPC surfaces are unacceptable; channel methods and HRPC allowlists are treated as part of the security boundary.
|
||||||
|
|
||||||
|
## Integration summary: where Bare OS sits in Holepunch land
|
||||||
|
|
||||||
|
Bare OS is not trying to replace Linux kernels or win desktop market share. It is a **structured guest** that:
|
||||||
|
|
||||||
|
* uses **Hyperdrive** as the system image transport
|
||||||
|
* uses **Hyperswarm** and **Protomux** the same way other Holepunch tools do
|
||||||
|
* runs under **Pear** and **Bare** hosts with explicit module manifest discipline
|
||||||
|
* exposes a **POSIX shaped** shell and utilities so operators can script, inspect, and teach the system using familiar verbs
|
||||||
|
|
||||||
|
If you already run Pear apps, Bare OS is legible as “what if the app’s replicated tree looked like `/bin` and `/etc` and carried its own `init`?” If you already build P2P data products, Bare OS is legible as “what if replication applied to the **OS artifact** as well as the user database?”
|
||||||
|
|
||||||
|
## Practical usage reminders
|
||||||
|
|
||||||
|
* Prerequisites: **Node.js ≥ 20**, **`npm ci`**, and **Pear CLI** for the recommended `npm run os:*` path (see [users-manual/03-running-seeder-and-booter.md](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/users-manual/03-running-seeder-and-booter.md) for a Node only quick path)
|
||||||
|
* The booter must find a peer on the **`bare-os-v1`** topic within the boot timeout
|
||||||
|
* Maintainer parity commands from the [README](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/README.md):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run maintainer:kernel-image
|
||||||
|
npm run maintainer:sync-kernel-seeder
|
||||||
|
```
|
||||||
|
|
||||||
|
* Personal data persists under **`BARE_OS_BOOT_STORE`**; deleting Corestore or changing store paths creates a **new** personal namespace unless you restore keys
|
||||||
|
|
||||||
|
## Final Thoughts
|
||||||
|
|
||||||
|
Bare Operating System is a rare combination: a serious attempt at **P2P native distribution** for something that **looks** like a Unix userland, paired with documentation and CI machinery that treat protocols, POSIX declarations, and `ctx` API versions as **shipping contracts**. It inherits the strengths of Hyperdrive replication (federated publishers, offline friendly sync once seeded, cryptographic identity of content) and inherits the responsibilities too (peer trust, key hygiene, replication observability).
|
||||||
|
|
||||||
|
The project’s own README warning is still the right last word: treat keys, vaults, and network exposure with the same caution you would bring to any crypto heavy prototype. Inside that boundary, Bare OS offers a concrete blueprint for **how** a minimal “OS image” can ride Holepunch stacks without pretending to be something it is not, and **how** personal state can stay personal while the system tree stays collectively reproducible.
|
||||||
|
|
||||||
|
If you are building peer to peer infrastructure, studying [this repository](https://git.ssh.surf/snxraven/bare-operating-system/src/branch/main/) is worthwhile even if you never ship its shell to end users: the **two drive model**, **`bare-os-v1`** wire layout, and **`executeKernel`** pipeline are reference quality examples of turning replication from a file sharing feature into a **boot path**.
|
||||||
Reference in New Issue
Block a user