Docs+handbook

This commit is contained in:
Raven Scott
2026-04-03 03:12:44 -04:00
parent d794c87b32
commit 7435f4b353
16 changed files with 1044 additions and 33 deletions
+65
View File
@@ -0,0 +1,65 @@
# Chapter 1 — Introduction: what “Bare OS” is
If you have only a minute: **Bare operating system** is a tiny **Unix-flavored environment** whose root filesystem is a **Hyperdrive** replicated from peers. A **seeder** publishes that drive and a **512-byte MBR** over **Hyperswarm**; a **booter** joins the swarm, downloads the image, mounts a **second** Hyperdrive for **per-user mutable state**, and runs JavaScript “kernel” and `/bin` scripts inside a **Bare** or **Node** runtime.
The rest of this chapter sets vocabulary straight—without it, the architecture diagrams in [Chapter 2](02-blueprints.md) will not stick.
---
## The problem this project explores
Traditional OS images live on block devices or tarball layers. Here, the **image is a Merkle tree** you can **address by key** and **replicate live**. Peers do not hand you a `.iso`; they help you **fill in** the same Hyperdrive from the same discovery key.
That raises three design questions this repo answers in code:
1. **Discovery** — How does a fresh node find _someone_ who has block 0 (the MBR) and the drive root?
2. **Separation of concerns** — What is **immutable-ish OS** vs **mutable per-device home**?
3. **Execution model** — What runs in the host process vs what is “inside” the simulated POSIX surface?
Bare OS picks: **one swarm topic** for the project, **Protomux** channels for control + replication, **two Hyperdrives** (system + personal), and **AsyncFunction-loaded JS** for kernel and utilities.
---
## Key vocabulary
| Term | Meaning here |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| **System drive** | Hyperdrive containing `/boot/init.js`, `/bin`, `/etc` — replicated from the seeder image |
| **Personal drive** | Separate Hyperdrive (Corestore namespace) for `$HOME`, `/.bare`, cron, logs |
| **MBR** | 512 bytes: magic `BIOS` + embedded Hyperdrive **public keys** (primary + optional failover) |
| **Kernel** | `/boot/init.js``async function start(ctx)`; not a microkernel, a **session loop** |
| **/bin** | Small JS programs (`async function run(ctx, argv)`) built from **bare-os-coreutils** |
| **VFS** | Booter-provided path layer: routes paths under `$HOME` to the **personal** drive, else **system** |
| **ctx** | Context object passed to kernel and commands: `vfs`, `console`, `execLine`, identity hooks, etc. |
| **Guest** | Default session before `login` — predictable `HOME=/home/guest`, no Ed25519 identity |
| **HDMS** | “Hyperdrive management” — optional extra drives mounted under `/mnt` after unlock |
---
## Why Hyperdrive and Hyperswarm
**Hyperdrive** gives you a **single-writer** (per key) log-backed filesystem with **deterministic** reads and **sparse** replication—good for an OS tree that many nodes can share.
**Hyperswarm** gives you **topic-based** and **discovery-key-based** peer finding. The seeder joins both the **bare-os-v1 topic** (so booters find _some_ peer) and the **drive discovery key** (so Hyperdrive replication completes).
You do not need to agree with every product choice to read the code: the handbook describes **what the repo does**, not whether it is the only way to build a P2P OS.
---
## Relationship to Pear and Bare
- **Bare** is a minimal JavaScript runtime used by **Pear** apps.
- Both **seeder** and **booter** are **Pear applications** (`pear` field in `package.json`) and can run under **`node index.js`** for development.
- **brittle-bare** vs **brittle-node** split in tests reflects native addons (e.g. identity crypto) that only load on Bare.
---
## Where to go next
- Big picture: [Chapter 2 — Blueprints](02-blueprints.md)
- Wire protocol: [Chapter 3](03-protocol-and-disk.md)
- Day-to-day hacking: [Chapter 7](07-operations-and-development.md)
---
[← Handbook home](README.md) · [Next: Blueprints →](02-blueprints.md)
+142
View File
@@ -0,0 +1,142 @@
# Chapter 2 — Blueprints: architecture and trust
This chapter is the **aerial view**: boxes, arrows, and what is allowed to trust what. Implementation details live in later chapters.
---
## 1. Two applications, one protocol
```mermaid
flowchart LR
subgraph publishers [Publish side]
Seeder[bare-os-seeder]
SysImg[System Hyperdrive]
Seeder --> SysImg
end
subgraph network [Hyperswarm]
Topic[bare-os-v1 topic]
Disc[Drive discovery keys]
end
subgraph consumers [Boot side]
Booter[bare-os-booter]
PeerDisk[SwarmDisk MBR + blocks]
Booter --> PeerDisk
end
Seeder --> Topic
Booter --> Topic
SysImg --> Disc
Booter --> Disc
```
- The **seeder** is the **publisher** of the OS image (plus MBR in a small RAM map).
- The **booter** is a **consumer** that refuses to invent a local copy: it **must** see peers.
---
## 2. Two drives on the booter
```mermaid
flowchart TB
subgraph booterProcess [Booter process]
VFS[VFS layer]
Sys[System Hyperdrive]
Pers[Personal Hyperdrive]
VFS -->|"paths outside HOME"| Sys
VFS -->|"HOME and below"| Pers
end
```
**Trust model (pragmatic):**
- **System drive** content is **whatever replicated from the swarm** matching the MBR keys. In dev you treat the seeder as trusted; in the wild this is “who you peer with.”
- **Personal drive** is **your** namespace (Corestore `bare-os-personal-v1`). It holds secrets, cron, dotfiles, HDMS registry, vault snapshots.
---
## 3. Protocol, MBR, and discovery
The shared package **bare-os-protocol** pins:
- `TOPIC_STRING === 'bare-os-v1'`
- `topicKey()` = `crypto.hash(b4a.from(TOPIC_STRING))`
- MBR layout: **512 bytes**, magic **`BIOS`**, primary key at offset **8**, optional failover keys at **40** and **72**
MBR layout (512 bytes, see `bare-os-protocol/constants.js`):
- Bytes **03**: `BIOS` magic
- Bytes **839**: primary system Hyperdrive public key
- Bytes **4071**, **72103**: optional additional keys
Protomux channel **`bare-os-v1`** carries:
- Block read requests (MBR and any indexed RAM the seeder exposes)
- Hyperdrive **replication** on the same socket
- Stubs for gossip, search, RPC (see `packages/bare-os-protocol/lib/channel.js`)
---
## 4. Execution stack inside the booter
```mermaid
flowchart TB
Init[index.js main]
Splash[Boot splash TTY]
Swarm[Hyperswarm + SwarmDisk]
ExecK[executeKernel]
Repl[Kernel REPL session]
Init --> Splash
Init --> Swarm
Swarm --> ExecK
ExecK --> Repl
Repl --> Kernel["runKernelFromSource /boot/init.js"]
Kernel --> Shell["execLine → execShellLine"]
Shell --> Bin["runBinCommand / paths / PATH"]
```
**Kernel** and **/bin** scripts are **not** separate processes. They are **`AsyncFunction`** closures in the **same** JS realm as the booter, with a **synthetic** `ctx` instead of syscalls.
---
## 5. Services after the console exists
```mermaid
flowchart LR
Session[createKernelReplSession]
Console[ctx.console = session.console]
Initd[startBareInitd]
Logger[kernel-logger wraps log/error]
Cron[bare-cron setInterval]
Session --> Console
Console --> Initd
Initd --> Logger
Initd --> Cron
```
`stopBareInitd()` runs from **REPL session cleanup** so timers do not leak across session restarts.
---
## 6. Identity states
```mermaid
stateDiagram-v2
[*] --> Guest
Guest --> Unlocked: login / login --new
Unlocked --> Guest: logout
Unlocked --> Unlocked: HDMS active after unlock
```
- **Guest**: fixed `HOME=/home/guest`, read-oriented personal tree policy for some operations.
- **Unlocked**: `HOME` under `/home/<pubkey-prefix>`, HDMS can attach writable drives, `crontab` install/remove allowed.
---
## 7. What is _not_ here (boundary)
- No hardware kernel, no MMU, no ELF loader for native `/bin`.
- No container cgroup isolation—**commands are JS** with full host capability **of the Pear/Bare process**.
- No global consensus: **two booters** can diverge if they replicate **different** forks of the same discovery key (Hyperdrive versioning is a separate concern).
---
[← Introduction](01-introduction.md) · [Handbook home](README.md) · [Next: Protocol and disk →](03-protocol-and-disk.md)
+86
View File
@@ -0,0 +1,86 @@
# Chapter 3 — Protocol, MBR, and SwarmDisk
Here we connect **bare-os-protocol** to what **seeder** and **booter** actually do on the wire and in RAM.
---
## Seeder lifecycle
1. Resolve **kernel root** (`BARE_OS_KERNEL_ROOT` or vendored `kernel/`).
2. Optionally **rebuild coreutils** when running under Node (`file:` URL) — skipped under Pear.
3. Open **Corestore** + **Hyperdrive**, **`stageKernelTree`**:
- `init.js``/boot/init.js`
- `bin/*``/bin/*`
- `etc/*``/etc/*`
4. Build **MBR** with `buildMbr(drive.key)` and store block **0** in a **`Map`** (`localRAM`).
5. **Hyperswarm** `join(topicKey())` and `join(drive.discoveryKey)`.
6. On each connection: **Protomux** + **`setupSeedChannel`**, which:
- Answers **read index** requests from `localRAM` (index `0` → MBR)
- Attaches **`drive.replicate(stream)`**
```mermaid
sequenceDiagram
participant S as Seeder
participant W as Hyperswarm
participant B as Booter
S->>W: join topic + discoveryKey
B->>W: join topic
B->>S: mux connection
Note over B,S: Protomux bare-os-v1
B->>S: read block 0
S-->>B: MBR 512 bytes
B->>S: hyperdrive replicate
```
---
## Booter: from peers to Hyperdrive
**`SwarmDisk`** (booter) mirrors the seeders channel handlers:
- **`read(index)`** — if not local RAM, broadcast **msg 0** to peers, await **msg 1** (timeout).
- **`addPeer`** — open channel, replicate **system** (and later **personal**) drives on the mux stream.
**Boot path:**
1. Wait until **`disk.peers.size > 0`** or **boot timeout**.
2. **`parseMbr(await disk.read(0))`** → list of 32-byte keys.
3. For each key, try `Hyperdrive(store, key)` + replicate until **`/boot/init.js`** exists.
4. Initialize **personal drive** namespace and join its discovery key.
5. Hand off to **`executeKernel`**.
There is **intentionally** no “use my checkouts `kernel/` if the network fails” path—the project forces you to think about **availability** of the swarm.
---
## Message IDs (reference)
Aligned with `packages/bare-os-protocol/lib/channel.js` and `swarm-disk.js`:
| ID | Direction | Purpose |
| ----- | -------------- | -------------------- |
| 0 | Client → peers | Read block by index |
| 1 | Peer → client | Data payload |
| 2 | Gossip stub | Bitfield buffer |
| 3 / 4 | Search req/res | Stub (empty matches) |
| 5 / 6 | RPC req/res | Stub on seeder |
The **important** path for boot is **0/1** + **Hyperdrive replication** on the same socket.
---
## Personal drive replication
`SwarmDisk.initPersonalDrive` creates a **separate** Hyperdrive under a stable Corestore namespace and **`swarm.join(personalDrive.discoveryKey)`**. Your `$HOME` tree can therefore sync across **your** devices if peers share that discovery key—orthogonal to the **system** image key from the MBR.
---
## Failure modes you will see in the wild
- **Boot timeout** — no peer answered the topic (seeder not running, firewall, wrong network).
- **Invalid MBR** — corrupt block 0 or wrong magic; `parseMbr` throws.
- **Drive never completes** — replication stalled; check peer count and discovery key joins.
---
[← Blueprints](02-blueprints.md) · [Handbook home](README.md) · [Next: Booter runtime →](04-the-booter-runtime.md)
+117
View File
@@ -0,0 +1,117 @@
# Chapter 4 — The booter runtime: `ctx`, VFS, shell, kernel, services
The booter is the **largest** package because it **is** the machine: everything the user experiences as “the OS” (except the raw Hyperdrive bytes) is assembled in **`packages/bare-os-booter/index.js`** and **`lib/*.js`**.
---
## Boot splash and stdio
`resolveStdio()` picks **session stdin/stdout** appropriate for Pear/Bare vs Node. When stdout is a TTY and `BARE_OS_NO_SPLASH` is unset, **`createBootSplash`** shows a **full-screen** progress UI tied to **`BARE_OS_BOOT_TIMEOUT_MS`**, then **`prepareForKernel()`** clears the screen before the line editor attaches.
Non-TTY mode skips splash noise; automation uses **`BARE_OS_SKIP_REPL=1`**.
---
## `executeKernel` in one paragraph
After the **system** and **personal** drives exist:
1. Build **`shellEnv`** (guest defaults: `HOME`, `PATH`, `USER`, …).
2. **`createVfs(drive, personalDrive, shellEnv)`** — the two-drive router.
3. **`applyGuestEnv` + `ensureGuestHome`** — identity stub and `/.bare` skeleton on the personal drive.
4. Construct **`ctx`**: disks, `vfs`, `env`, `b4a`, `topic`, identity hooks (`applyUnlock`, `applyLogout`, `saveVault`, …), **`runHdms`** for `/bin/hdms`, **`requestBooterExit`** for `exit`.
5. **`createKernelReplSession`** — fish-style **`readLine`** + **`console`** bound to the same stdout as the prompt.
6. Set **`ctx.execLine`** to a wrapper that handles **`exit`** then **`execShellLine`**.
7. **`await startBareInitd(ctx)`** — see below.
8. **`runKernelFromSource(initSource, ctx)`** — runs `/boot/init.js`.
Cleanup path closes swarm/drives and calls **`session.cleanup()`**, which runs **`stopBareInitd()`**.
---
## VFS: two drives, one path space
`lib/vfs.js` implements **`resolveLogical`** with **`unix-path-resolve(cwd, userPath)`** (two arguments only—important when reading the code).
- Paths under **`$HOME`** resolve to the **personal** Hyperdrive (mutable `writeFile` / `unlink` where policy allows).
- Other absolute paths hit the **system** drive (OS image).
- Hyperdrive rejects **`/`** as a filename; the VFS special-cases **logical root** for `stat`, `chdir`, `exists`.
Virtual listings include **`/home`** (session-specific) and **`/mnt`** when HDMS mounts exist.
---
## Shell and kernel runner
**`execShellLine`** (`lib/shell.js`):
- Tokenizes words, quotes, escapes, **`$VAR`**, pipelines **`|`**, redirections **`>` / `>>` / `<`**.
- Builtins: **`cd`**, **`export`**, **`login`**, **`logout`**, **`exit`** — plus external commands via **`runBinCommand`**.
- Pipes capture **`console.log`** into the next stage or a string sink.
**`runBinCommand`** (`lib/kernel-runner.js`):
1. If **`argv[0]`** contains **`/`** — resolve via VFS, **`drive.get`**, **`runScriptFromSource`**.
2. Else if the name **ends with `.js`** — resolve **`$PWD/name.js`** first (same as explicit `./` for many cases).
3. Else walk **`PATH`** on the **system** drive only.
**`runScriptFromSource`** strips an optional **`#!`** line, requires **`async function run(ctx, argv)`**, and **catches** errors—logs to **`ctx.console.error`** without unwinding the kernel loop.
**`runKernelFromSource`** requires **`async function start(ctx)`** at the top level of `/boot/init.js`.
---
## bare-initd and kernel logger
**`bare-initd.js`**:
- **`registerBareService({ name, start })`**
- **`startBareInitd(ctx)`** — sequential start, per-service `try/catch`, `[bare-initd] name: err` on failure
- **`registerBareInitdDisposer(fn)`** + **`stopBareInitd()`** — for intervals and teardown
Built-in **`kernel-logger`** wraps **`ctx.console.log` / `error`** to also append UTF-8 lines to **`$HOME/.kernel/kernel.log`** (creates **`~/.kernel/.keep`** best-effort). Failures to write logs are swallowed so logging never kills the session.
---
## bare-cron
**`bare-cron.js`** registers service **`bare-cron`**:
- Reads **`~/.crontab`** via VFS (silent if missing).
- Parses five-field cron lines + command remainder.
- Aligns to **minute boundaries**, **`setInterval(60s)`**, runs **`await ctx.execLine(command)`** with per-line **in-flight** guard.
- Registers a **disposer** to clear timeout/interval on shutdown.
Install/list/remove crontab with **`/bin/crontab`** (see [Chapter 6](06-kernel-and-binaries.md)).
---
## REPL: fish-style line editor
When stdin/stdout are a capable TTY and **`BARE_OS_FISH≠0`**, **`fish-readline.js`** provides history, hints, and synchronized **`Console`** output so prompts and **`console.log`** do not fight. History files live on the **personal** drive keyed by user identity.
---
## Debug
**`debug-repl.js`** and env-driven logging can trace readline and write paths—useful when stdin is a pipe vs TTY.
---
```mermaid
flowchart TB
subgraph ctxCore [ctx surface]
vfs[vfs]
execLine[execLine]
console[console]
identity[identity + hooks]
hdms[runHdms]
end
execLine --> shell[execShellLine]
shell --> runner[runBinCommand]
runner --> script[runScriptFromSource]
```
---
[← Protocol and disk](03-protocol-and-disk.md) · [Handbook home](README.md) · [Next: Identity and HDMS →](05-identity-vault-and-hdms.md)
+88
View File
@@ -0,0 +1,88 @@
# Chapter 5 — Identity, vault, and HDMS
This chapter covers **who the session is** (guest vs unlocked), **where keys live**, **encrypted vault snapshots**, and **extra Hyperdrives** under `/mnt`.
---
## Guest session
On boot, **`applyGuestEnv`** sets:
- **`USER` / `LOGNAME`** — `guest`
- **`HOME` / `PWD`** — `/home/guest`
- **`BARE_OS_IDENTITY`** — `guest`
- Empty or absent **`BARE_OS_PUBLIC_KEY`**
The personal drive still persists: guest data is **not** anonymous to the drive—it is simply the **unauthenticated** profile.
---
## Account blob: `/.bare/account`
**`identity-account.js`** defines **v2** on-disk format:
- Magic **`BAREOS01`**, version **2**
- 32-byte **Ed25519 public key**
- **PBKDF2-SHA256** salt + iteration count (default **210000**)
- **ChaCha20-Poly1305** seal over the **64-byte** secret key material (`bare-crypto`)
**`login --new`** creates a new account; **`login`** decrypts an existing one. Legacy v1 blobs are rejected with a message to recreate.
---
## Unlocked session
**`identity-session.js`**:
- Updates **`ctx.vfs.env`** with real **`USER`**, **`HOME`** under **`/home/<pubkey-prefix>`**, **`BARE_OS_PUBLIC_KEY`**, derived **`UID`/`GID`**-like fields from a hash of the public key.
- **`vfs.chdir`** to the new home.
- **`onIdentityUnlocked`** (from `index.js`) activates **HDMS** with Corestore, swarm bootstrap, personal drive, mount map.
**`logout`** zeroes sensitive material and returns to guest; **`logout --save`** (and **`savevault`**) snapshot selected paths into **`/.bare/vault/`** as encrypted records (see `identity-account.js` helpers for AEAD and path hashing).
---
## HDMS (Hyperdrive management)
**`hdms-manager.js`** implements **`/bin/hdms`** via **`ctx.runHdms(argv)`**:
- Registry JSON on the **personal** drive: **`/.bare/hdms/registry.json`**
- **Writable** drives: new Corestore namespace + Hyperdrive, label, replicate to swarm
- **Read-only** drives: open by key string
- **invite / pair** — uses **Autopass** (static ESM import for Pear tracing)
**`assertLoggedIn`** requires **`ctx.identity.state === 'unlocked'`** and active controller—guests can list mounts that are already open but cannot **mutate** registry until login.
**VFS** exposes **`/mnt/<label>/...`** for mounted drives; writable mounts allow **`put`** on those routes.
```mermaid
flowchart LR
subgraph personal [Personal drive]
Acc["/.bare/account"]
Reg["/.bare/hdms/registry.json"]
Vault["/.bare/vault/"]
end
subgraph hdms [HDMS]
Extra[Extra Hyperdrives]
end
Reg --> Extra
Extra --> Mnt["/mnt labels"]
```
---
## Cron and identity
**`crontab`** install/remove requires **unlocked** identity so arbitrary guests cannot overwrite **`~/.crontab`** on a shared replica interpretation—**reading** jobs is still “whatever file exists on your personal drive.”
---
## Threat sketch (not a formal audit)
- **Passphrase strength** matters: PBKDF2 iterations slow brute force but do not fix weak secrets.
- **Vault** ciphertext is only as safe as the **derived key** and **where copies replicate**.
- **JS in-process** commands can exfiltrate keys from memory—this is a **toy OS shell**, not a sandbox.
---
[← Booter runtime](04-the-booter-runtime.md) · [Handbook home](README.md) · [Next: Kernel and binaries →](06-kernel-and-binaries.md)
+86
View File
@@ -0,0 +1,86 @@
# Chapter 6 — Kernel and `/bin` utilities
The **kernel** is a single script. The **utilities** are many small scripts. Both follow strict **`AsyncFunction`** contracts so the same code runs under **Bare** without a bundler per command.
---
## `/boot/init.js`
Staged from **`kernel/init.js`**. Responsibilities (typical):
1. Print **`/etc/os-release`** via **`ctx.drive.get`** + **`b4a.toString`**
2. Print a **one-line** hint (commands, login, paths)
3. Loop forever:
- **`line = await readLine('')`**
- Break on **`null`** (EOF / session end)
- Skip empty lines
- **`try/catch`** around **`execLine(t)`** so stray throws do not kill the loop
The **prompt** (`[user@host:path] > `) is applied by the booters readline layer, not by `init.js`.
---
## Coreutils build pipeline
```
packages/bare-os-coreutils/lib/runtime.js
+
packages/bare-os-coreutils/src/<cmd>.js
↓ (build.mjs)
kernel/bin/<cmd>
packages/bare-os-seeder/kernel/bin/<cmd> ← Pear vendored copy
```
**Rule:** no `import` in `src/*.js` — only `async function run(ctx, argv)`.
---
## Command reference (summary)
| Command | Role |
| -------------------------------- | -------------------------------------------------------------------------- |
| `basename`, `dirname` | Path manipulation |
| `cat`, `head`, `tail`, `nl` | Text |
| `clear` | ANSI clear screen |
| `crontab` | `-l` list, `-r` remove, `<file>` install (`~/.crontab`; writes need login) |
| `date` | Date/time |
| `echo`, `printf`-like simplicity | Args to stdout |
| `env`, `printenv` | Environment |
| `exit` | Sets exit code / session end via booter |
| `false`, `true` | Status |
| `hdms` | Hyperdrive management CLI |
| `help` | Lists builtins + `/bin` |
| `hostname` | Host string |
| `id`, `whoami`, `tty` | Identity / TTY |
| `login`, `logout` | Account session |
| `ls` | Lists directories; **hides `.*` unless `-a`** |
| `pathchk` | Path sanity |
| `pwd` | Logical cwd |
| `rm` | Unlink files |
| `savevault` | Encrypted vault snapshot |
| `seq`, `sleep`, `sort` | Misc |
| `test`, `[` | Conditionals (as implemented) |
| `touch` | Create/empty files |
| `uname` | OS string |
| `wc`, `which` | Text / PATH lookup |
Exact flags vary—read each **`src/<cmd>.js`** for truth.
---
## Running user scripts
- **`./foo.js`** — explicit relative path via VFS.
- **`foo.js`** — if the basename ends with **`.js`**, the runner tries **`$PWD/foo.js`** **before** scanning **`PATH`** on the system drive.
Shebang lines **`#!...`** are stripped before compilation.
---
## Editing the banner
Update **`kernel/init.js`** and **`packages/bare-os-seeder/kernel/init.js`** if you want the **staged** Pear copys first-run text to match (some workflows copy automatically via build; the seeders `kernel/` tree may be vendored separately—check your release process).
---
[← Identity and HDMS](05-identity-vault-and-hdms.md) · [Handbook home](README.md) · [Next: Operations →](07-operations-and-development.md)
+120
View File
@@ -0,0 +1,120 @@
# Chapter 7 — Operations, development, and release
This chapter is the **operators desk**: how to install, test, run Pear apps, and interpret common failures.
---
## Repository layout (monorepo)
| Path | Package / role |
| ---------------------------- | ------------------------------------------- |
| `package.json` | Workspaces root, `pretest` builds coreutils |
| `kernel/` | System image sources |
| `packages/bare-os-protocol` | Topic + MBR + Protomux helpers |
| `packages/bare-os-coreutils` | Build `/bin` scripts |
| `packages/bare-os-seeder` | Publish OS drive |
| `packages/bare-os-booter` | Network boot + runtime |
| `scripts/` | Pear `node_modules` fixer, etc. |
| `data/` | Gitignored Corestore dirs (default for dev) |
Each workspace has its own **`README.md`** with package-specific commands.
---
## Install and test
```bash
npm ci
npm test
```
- **`pretest`** runs **`npm run build -w bare-os-coreutils`**.
- **booter** tests use **Node** for Hyperdrive + **Bare** for identity crypto (`test.identity.js`).
Install **Bare** globally for CI parity: **`npm install -g bare`** (see `.github/workflows/ci.yml`).
---
## Running seeder and booter (Node)
From **`packages/bare-os-seeder`**:
```bash
node index.js
```
From **`packages/bare-os-booter`**:
```bash
node index.js
```
Corestore paths resolve under repo **`data/`** when using `file:` URLs (see each packages `lib/paths.js`).
---
## Running with Pear (recommended for “real” behavior)
From **repo root**:
```bash
npm run os:seeder
npm run os:booter # second terminal
```
These run **`scripts/ensure-pear-node-modules.mjs`** first. **Do not** run `pear run os:seeder``os:seeder` is an npm script name, not a Pear link.
---
## Environment variables (cheat sheet)
| Variable | Component | Meaning |
| ------------------------- | ------------- | -------------------------------- |
| `BARE_OS_KERNEL_ROOT` | Seeder | Override kernel tree path |
| `BARE_OS_SEED_STORE` | Seeder | Corestore directory |
| `BARE_OS_BOOT_TIMEOUT_MS` | Booter | Boot deadline (default 60000) |
| `BARE_OS_NO_SPLASH` | Booter | Disable TTY splash |
| `BARE_OS_SKIP_REPL` | Booter | Non-interactive kernel |
| `BARE_OS_FISH` | Booter | Set `0` to disable fish readline |
| `HYPERSWARM_BOOTSTRAP` | Booter / HDMS | Comma-separated bootstrap nodes |
---
## Pear staging and `pear://` links
After **`pear stage`** / **`pear release`**, Pear prints a **`pear://…`** link per app. Distribution expects consumers to run **those** keys—not arbitrary git checkouts—unless they run in **dev** mode with **`pear run --dev .`**.
---
## Formatting
```bash
npm run format
npm run lint
```
Prettier config: **no semicolons**, **single quotes** (`.prettierrc`).
---
## Troubleshooting
| Symptom | Likely cause |
| ------------------------------------- | -------------------------------------------------------------------------- |
| Booter exits at timeout | No seeder peer on `bare-os-v1` topic |
| `/bin/foo` missing under Pear | Forgot `npm run build -w bare-os-coreutils` before staging |
| `autopass` / module not found in Pear | Hoist/`ensure-pear-node-modules` / static imports in HDMS |
| `test is not defined` in user script | Bug in user JS—should **log** and continue (kernel runner catches) |
| Double cron or log spam | Session restarted without **`stopBareInitd`** — should run on REPL cleanup |
---
## Further reading
- **[DOCUMENTATION.md](../DOCUMENTATION.md)** — file-by-file reference (large, authoritative for paths)
- **[README.md](../README.md)** — short overview
- **Handbook [Chapter 1](01-introduction.md)** — vocabulary recap
---
[← Kernel and binaries](06-kernel-and-binaries.md) · [Handbook home](README.md)
+48
View File
@@ -0,0 +1,48 @@
# Bare operating system — handbook
Welcome. This handbook is the **narrative companion** to the repo: it explains _why_ the pieces exist, _how_ they connect, and _what_ to run when things go wrong. For an **exhaustive file-by-file inventory**, keep [DOCUMENTATION.md](../DOCUMENTATION.md) open alongside—it is the closest thing to a generated map of every source path.
This project is **experimental research software**: a distributed **system image** living in **Hyperdrive**, discovered over **Hyperswarm**, executed by **Bare**/**Pear** apps. It is not a production OS.
---
## Who this is for
- You want a **mental model** of seeder vs booter vs kernel vs `/bin`.
- You need **diagrams** of data flow and trust boundaries.
- You are extending **coreutils**, **VFS**, **identity**, **HDMS**, or **initd** services.
---
## Reading order
| Chapter | Topic |
| ------------------------------------------------------------------- | --------------------------------------------------- |
| [01 — Introduction](01-introduction.md) | Goals, vocabulary, Holepunch stack |
| [02 — Blueprints](02-blueprints.md) | Layered architecture, trust, diagrams |
| [03 — Protocol and disk](03-protocol-and-disk.md) | MBR, swarm, Protomux, SwarmDisk |
| [04 — The booter runtime](04-the-booter-runtime.md) | `ctx`, VFS, shell, kernel runner, initd, cron, REPL |
| [05 — Identity, vault, HDMS](05-identity-vault-and-hdms.md) | Guest vs user, `/.bare/account`, extra drives |
| [06 — Kernel and binaries](06-kernel-and-binaries.md) | `/boot/init.js`, coreutils catalog |
| [07 — Operations and development](07-operations-and-development.md) | Env vars, npm scripts, CI, Pear, troubleshooting |
---
## Package READMEs (quick links)
- [bare-os-protocol](../packages/bare-os-protocol/README.md)
- [bare-os-coreutils](../packages/bare-os-coreutils/README.md)
- [bare-os-seeder](../packages/bare-os-seeder/README.md)
- [bare-os-booter](../packages/bare-os-booter/README.md)
- [kernel](../kernel/README.md)
- [scripts](../scripts/README.md)
---
## Root README
The top-level [README.md](../README.md) is the short **runbook** (install, test, `pear run`, guest identity). Start there if you only need commands.
---
_License: Apache-2.0 — see [LICENSE](../LICENSE)._