This commit is contained in:
Raven Scott
2026-04-03 23:42:47 -04:00
parent d8e580d1af
commit 2ef56ac314
43 changed files with 1941 additions and 553 deletions
+8 -5
View File
@@ -16,8 +16,8 @@ Non-TTY mode skips splash noise; automation uses **`BARE_OS_SKIP_REPL=1`**.
After the **system** and **personal** drives exist:
1. Build **`shellEnv`** (guest defaults: `HOME`, `PATH`, `USER`, …, **`BARE_OS_CTX_API_VERSION`**), copying host keys when set — including **`BARE_OS_PIPELINE_*`**, boot and audit toggles (**`BARE_OS_BOOT_PROFILE`**, **`BARE_OS_ONBOOT`**, **`BARE_OS_BOOT_STRICT`**, **`BARE_OS_RC_D_SKIP`**, **`BARE_OS_BOOT_MINIMAL`**, **`BARE_OS_BOOT_SKIP`**, **`BARE_OS_BOOT_TRACE`**, **`BARE_OS_KERNEL_SELFTEST`**, **`BARE_OS_SELFTEST_FORMAT`**, **`BARE_OS_AUDIT`**, **`BARE_OS_AUDIT_JSON`**, **`BARE_OS_AUDIT_REDACT`**, **`BARE_OS_BOOT_ALLOWLIST`**, **`BARE_OS_EXEC_MAX_DEPTH`**, **`BARE_OS_IPC_MAX_BYTES`**, **`BARE_OS_IPC_RPC_TOKEN`**, **`BARE_OS_IPC_FANOUT`**, **`BARE_OS_IPC_JSON_MAX_BYTES`**, **`BARE_OS_HTTP_ALLOWLIST`**, **`BARE_OS_HTTP_DENYLIST`**, **`BARE_OS_TLS_PIN_SHA256`**, **`BARE_OS_VFS_WATCH`**, **`BARE_OS_IMAGE_DIGEST`**, **`BARE_OS_PEAR_CHANNEL`**, **`BARE_OS_PEAR_RELEASE`**, **`BARE_OS_BARE_MODULES`**, **`BARE_OS_BARE_DRIVE_BUNDLES`**, **`PEAR_CHANNEL`**) — see [Chapter 7](07-operations-and-development.md) and the [context object developer guide](../developer-guide/02-the-context-object.md). Set **`BARE_OS_BOOT_PROFILE_RESOLVED`** from the host override or the first line of **`/etc/bare-os/profile`** on the system drive; assign **`BARE_OS_SESSION_ID`** for **`/run/bare-os/session`**. Seed **`/run/bare-os/boot.json`** fields **`imageDigest`**, **`pearChannel`**, **`pearRelease`**, and accumulate **`booterPhases`** (**`vfs`**, **`ctx`**, **`repl`**, **`initd`**, **`kernel_invoke`**) for observability alongside kernel **`phases`**.
2. **`createBareOsIpc({ maxFifoBytes, ipcRpcToken?, enableFanout?, maxJsonRpcLineBytes? })`** — in-memory FIFOs under **`/run/bare-os/ipc/<name>`**; **`pushJson`/`takeJson`** with optional shared-secret field **`bareOsIpcToken`** when **`BARE_OS_IPC_RPC_TOKEN`** is set; **fan-out** topics **`fanoutPublish`/`fanoutSubscribe`** (disable with **`BARE_OS_IPC_FANOUT=0`**); **`stats`** includes fan-out subscriber counts.
1. Build **`shellEnv`** (guest defaults: `HOME`, `PATH`, `USER`, …, **`BARE_OS_CTX_API_VERSION`**), copying host keys when set — including **`BARE_OS_PIPELINE_*`**, boot and audit toggles (**`BARE_OS_BOOT_PROFILE`**, **`BARE_OS_ONBOOT`**, **`BARE_OS_BOOT_STRICT`**, **`BARE_OS_RC_D_SKIP`**, **`BARE_OS_BOOT_MINIMAL`**, **`BARE_OS_BOOT_SKIP`**, **`BARE_OS_BOOT_TRACE`**, **`BARE_OS_KERNEL_SELFTEST`**, **`BARE_OS_SELFTEST_FORMAT`**, **`BARE_OS_AUDIT`**, **`BARE_OS_AUDIT_JSON`**, **`BARE_OS_AUDIT_REDACT`**, **`BARE_OS_BOOT_ALLOWLIST`**, **`BARE_OS_EXEC_MAX_DEPTH`**, **`BARE_OS_IPC_*`**, **`BARE_OS_HTTP_ALLOWLIST`**, **`BARE_OS_HTTP_DENYLIST`**, **`BARE_OS_TLS_PIN_SHA256`**, **`BARE_OS_VFS_WATCH`**, **`BARE_OS_VFS_UNION_PREFIXES`**, **`BARE_OS_VFS_BIN_CACHE`**, **`BARE_OS_IMAGE_DIGEST`**, **`BARE_OS_PEAR_CHANNEL`**, **`BARE_OS_PEAR_RELEASE`**, **`BARE_OS_BARE_MODULES`**, **`BARE_OS_BARE_DRIVE_BUNDLES`**, **`BARE_OS_BOOT_MANIFEST`**, **`BARE_OS_BOOT_MANIFEST_SIGN`**, **`BARE_OS_BOOT_MANIFEST_PUBKEY_HEX`**, **`BARE_OS_SANDBOX_SCRIPT`**, **`BARE_OS_SANDBOX_WORKER`**, **`BARE_OS_INITD_MAX_PARALLEL`**, **`BARE_OS_URANDOM_CRYPTO`**, **`BARE_OS_BLIND_BOOTSTRAP_URL`**, **`BARE_OS_BLIND_BOOTSTRAP_JSON`**, **`BARE_OS_MIRROR_READ_KEY`**, **`PEAR_CHANNEL`**) — see [Chapter 7](07-operations-and-development.md), the [environment appendix](../docs/reference/environment-and-posix-appendix.md#14-environment-variables-complete-list), and the [context object developer guide](../developer-guide/02-the-context-object.md). Set **`BARE_OS_BOOT_PROFILE_RESOLVED`** from the host override or the first line of **`/etc/bare-os/profile`** on the system drive; assign **`BARE_OS_SESSION_ID`** for **`/run/bare-os/session`**. Seed **`/run/bare-os/boot.json`** fields **`imageDigest`**, **`pearChannel`**, **`pearRelease`**, and accumulate **`booterPhases`** (**`vfs`**, **`ctx`**, **`repl`**, **`initd`**, **`kernel_invoke`**) for observability alongside kernel **`phases`**.
2. **`createBareOsIpc({ maxFifoBytes, ipcRpcToken?, enableFanout?, maxJsonRpcLineBytes? })`** — in-memory FIFOs under **`/run/bare-os/ipc/<name>`**; **`pushJson`/`takeJson`** with optional shared-secret field **`bareOsIpcToken`** when **`BARE_OS_IPC_RPC_TOKEN`** is set; **fan-out** topics **`fanoutPublish`/`fanoutSubscribe`** (disable with **`BARE_OS_IPC_FANOUT=0`**); **`createDuplexBridge(baseName)`** pairs two **`push`/`take`** sides for bidirectional byte streams; **`duplexJsonRoundTrip(side, request)`** sends one JSON object and awaits one JSON reply (bounded); **`stats`** includes fan-out subscriber counts.
3. **`createVfs(drive, personalDrive, shellEnv, mntRef, vfsOptions?)`** — the two-drive router; optional **`vfsOptions`** supply **`procSnapshot`** (**`/proc/version`**, **`cmdline`**), dynamic text for **`/proc/net/dev`**, **`/proc/diskstats`**, **`/proc/bare_os_quotas`**, **`/proc/bare_os_resources`**, **`/proc/bare_os_features`**, **`/sys/class/net/lo`**, **`bootProfileText`**, **`sessionText`**, **`initdRunText`**, **`bootReadyJsonText`**, **`getVirtualReaders`** for **`/run/bare-os/virtual/<name>`**, etc.
4. After VFS: **`buildBareCtxObjectFromHost`** + **`maybeMergeBareFromDrive`** fill a **`bareLibrary`** map (host imports first; drive bundles only add **missing** keys). **`/lib/bare/manifest.json`** and **`/lib/bare/bundles/*.js`** are **trusted** like **`/bin`**. See [developer guide ch.12](../developer-guide/12-bare-modules-and-pear-ecosystem.md).
5. Construct **`ctx`**: disks, `vfs`, **`bareOsIpc`**, `env`, `b4a`, optional **`bare: Object.freeze(bareLibrary)`** when **`BARE_OS_BARE_MODULES`** is enabled, `topic`, **`bareOsRuntimeCaps`** (pipeline limits, **`quotas`**, pseudo path list, feature flags such as **`vfsWatch`**, **`ipcRpcJson`**, **`ipcFanout`**, **`initdSocketActivation`**, **`bareCtxModules`**, **`bareDriveBundles`**), optional **`httpFetch`** (policy-wrapped **`fetch`** when the host provides global **`fetch`**), optional **`bareOsHostStats`** from the **`bare-os`** module, **`bareOsGetResourceStatus`**, **`bareOsRegisterVirtualFile`**, Pear/sandbox stubs, identity hooks, **`bareOsSubscribeBootEvent`** / **`bareOsEmitBootEvent`**, **`bareOsSubscribeHdmsLifecycle`**, **`bareOsAwaitInitdUnits`**, **`runHdms`**, **`requestBooterExit`**, **`bareOsPublishBootReady`**, …
@@ -45,10 +45,11 @@ Virtual listings include **`/home`** (session-specific), **`/mnt`** when HDMS mo
These paths are **synthetic** (not stored on either Hyperdrive). They exist for inspection and scripting ergonomics, **not** Linux ABI compatibility.
- **`/proc`**: **`version`**, **`bare_os_version`**, **`uptime`**, **`meminfo`**, **`cpuinfo`**, **`loadavg`**, **`mounts`**, **`diskstats`** (stub text), **`bare_os_quotas`** (JSON: pipeline limits, exec-depth cap, IPC cap, session stats, FIFO **`stats`**), **`bare_os_resources`** (unified operator snapshot), **`bare_os_features`** (protocol/kernel feature bitmask doc), **`net/dev`** (P2P-oriented stub), **`self/`** with **`environ`**, **`cmdline`**, **`exe`**, plus **`bare_os_session_stats`**. **`environ`** omits keys whose names look secret-bearing (e.g. **`PASSWORD`**, **`TOKEN`**, **`VAULT`**) and only includes a small public set plus **`BARE_OS_*`** (including **`BARE_OS_SESSION_ID`**).
- **`/proc`**: **`version`**, **`bare_os_version`**, **`uptime`**, **`meminfo`**, **`cpuinfo`**, **`loadavg`**, **`mounts`**, **`diskstats`** (stub text), **`bare_os_quotas`** (JSON: pipeline limits, exec-depth cap, IPC cap, session stats, FIFO **`stats`**), **`bare_os_resources`**, **`bare_os_features`**, **`bare_os_swarm`** (bounded P2P / session snapshot when the host provides it), **`bare_os_replication`** (JSON hints: version, peers, last error when known), **`bare_os_capabilities`** (human-readable dump of **`ctx.bareOsRuntimeCaps`**; **`bare_os_capabilities.json`** or **`Accept: application/json`** for machine output), **`bare_os_bootstrap`** (optional blind-peer style hints: **`BARE_OS_BLIND_BOOTSTRAP_URL`** or parsed **`BARE_OS_BLIND_BOOTSTRAP_JSON`** surfaced as JSON for operators — no automatic network fetch from the guest), **`net/dev`** (P2P-oriented stub), **`self/`** with **`environ`**, **`cmdline`**, **`exe`**, plus **`bare_os_session_stats`**. **`environ`** omits keys whose names look secret-bearing (e.g. **`PASSWORD`**, **`TOKEN`**, **`VAULT`**) and only includes a small public set plus **`BARE_OS_*`** (including **`BARE_OS_SESSION_ID`**).
- **`/sys`**: **`fs/bare_os/version`**, **`fs/bare_os/build_id`**, **`class/net/lo`** (stub **`operstate`** / **`carrier`**).
- **`/sys/fs/bare_os/version`**: same text as **`/proc/version`**.
- **`/run/bare-os/units`**: tab-separated snapshot of **bare-initd** registered units (phase, start time, description).
- **`/run/bare-os/unit-journal/`**: append-only **NDJSON** per unit (**`<name>.ndjson`**) for start/stop/health/restart events (size-capped); **`journalctl -u`** also tails this file when present.
- **`/run/bare-os/boot_profile`**: one line (plus newline): resolved boot profile name (**`BARE_OS_BOOT_PROFILE`** from the host, else first line of **`/etc/bare-os/profile`**, else empty). Listed in **`ctx.bareOsRuntimeCaps.pseudoFsPaths`**.
- **`/run/bare-os/session`**: session UUID (from **`BARE_OS_SESSION_ID`**) plus newline.
- **`/run/bare-os/virtual/`**: optional kernel-registered synthetic files via **`ctx.bareOsRegisterVirtualFile`**.
@@ -58,6 +59,8 @@ These paths are **synthetic** (not stored on either Hyperdrive). They exist for
**`vfs.watch(logicalPath)`** (Hyperdrive-backed paths only — not pseudo roots): returns **`{ watcher, destroy, logicalAbs, driveFolder }`**; use Hyperdrives async iterator on **`watcher`**. Disabled when host sets **`BARE_OS_VFS_WATCH=0`**. See **`ctx.bareOsRuntimeCaps.features.vfsWatch`**.
**Union read:** when **`BARE_OS_VFS_UNION_PREFIXES`** lists comma-separated logical prefixes, **`readFile`** / **`readlink`** on those paths may merge the **system** image with overlays (see **`vfs.js`** and **`ctx.bareOsRuntimeCaps.features.vfsUnionRead`**). **`BARE_OS_VFS_BIN_CACHE=1`** enables a small LRU read cache for **`/bin`** entries, invalidated when **`vfs.watch`** notifications fire on watched prefixes.
**Implementation note:** pseudo-file content is UTF-8 encoded with **`b4a`**, not **`TextEncoder`**, because some Bare/Pear runtimes omit the Web Encoding globals (`TextEncoder` / `TextDecoder`). The same applies elsewhere in the booter and in-image utilities that must run on Bare.
### **`/dev`** and **`/run`** (minimal subset)
@@ -88,7 +91,7 @@ Work is sequenced for **POSIX/script ergonomics first**, then networking and lon
**`execShellLine`** (`lib/shell.js`):
- Tokenizes words, quotes, escapes, **`$VAR`**, pipelines **`|`**, redirections **`>` / `>>` / `<`**.
- Builtins: **`alias`**, **`unalias`**, **`cd`**, **`export`**, **`unset`**, **`readonly`**, **`umask`**, **`:`**, **`command`**, **`type`**, **`login`**, **`logout`**, **`exit`** — plus external commands via **`runBinCommand`**. **`readonly`** blocks **`export`** and assignment writes to the same name; **`command -v` / `-V`** and **`type`** use **`resolveBinInPath`** for **`PATH`** lookup.
- Builtins: **`alias`**, **`unalias`**, **`cd`**, **`export`**, **`unset`**, **`readonly`**, **`umask`**, **`:`**, **`command`**, **`type`**, **`login`**, **`logout`**, **`exit`**, bounded **`if`/`while`/`for`/`case`** — plus external commands via **`runBinCommand`**. **`readonly`** blocks **`export`** and assignment writes to the same name; **`command -v` / `-V`** and **`type`** use **`resolveBinInPath`** for **`PATH`** lookup.
- First-word **aliases** (defaults like **`ll``ls -la`**, **`nano``edit`**) expand after **`$VAR`** substitution; **`alias`** / **`unalias`** match the restricted **`~/.barerc`** syntax (not full POSIX **`sh`**).
- Pipes capture **`console.log`** into the next stage or a string sink.
@@ -118,7 +121,7 @@ There is no arbitrary command execution, **`source`**, or control flow — it is
**`bare-initd.js`**:
- **`registerBareService({ name, start, stop?, description?, logPath? })`** — optional **`stop`** enables **`systemctl stop`** / **`restart`** for that unit; **`logPath`** is a logical VFS path for **`systemctl status`** / **`logs`**
- **`startBareInitd(ctx)`** — ensures **`/var/log/bare-os`** (see below), then ordered start (skips units listed in **`~/.config/bare-os/initd/disabled.txt`** on the personal drive; optional **`~/.config/bare-os/units/<name>.unit`** with **`[Unit]`** keys **`After=`**, **`Requires=`**, **`Wants=`**, **`TimeoutStartSec=`**, **`TimeoutStopSec=`**, **`Restart=`**, **`RestartSec=`**, **`ExecStartPost=`**, **`SocketActivationIpc=`** — the last defers **`start()`** until the first read on that logical FIFO name — plus **`ReadinessPath=`** (VFS path that must exist before the unit is marked **`active`**) and **`ReadinessTimeoutSec=`** (poll budget, default 30s)). Default **`bare-cron`** runs after **`kernel-logger`**. Per-service `try/catch`, `[bare-initd] name: err` on failure; failures append to **`/var/log/bare-os/initd.log`**; runtime state **`active`** / **`failed`** / **`inactive`**. **`waitForBareInitdUnits(names, timeoutMs)`** polls until listed units are **`active`** (exposed on **`ctx`** as **`bareOsAwaitInitdUnits`**).
- **`startBareInitd(ctx)`** — ensures **`/var/log/bare-os`** (see below), then **DAG-ordered** start with optional parallelism (**`BARE_OS_INITD_MAX_PARALLEL`**, default **1**). Skips units listed in **`~/.config/bare-os/initd/disabled.txt`**. Drop-ins **`~/.config/bare-os/units/<name>.unit`** support **`[Unit]`** keys **`After=`**, **`Before=`**, **`Requires=`**, **`Wants=`**, **`TimeoutStartSec=`**, **`TimeoutStopSec=`**, **`Restart=`**, **`RestartSec=`**, **`OnFailure=`**, **`FailureAction=`**, **`ExecStartPost=`**, **`SocketActivationIpc=`** (defers **`start()`** until the first read on that FIFO), **`ReadinessPath=`**, **`ReadinessTimeoutSec=`**. Cycles in **`After`/`Before`** are detected and logged; affected units fail start. Default **`bare-cron`** runs after **`kernel-logger`**. Per-service `try/catch`, `[bare-initd] name: err` on failure; failures append to **`/var/log/bare-os/initd.log`** and the structured unit journal; runtime state **`active`** / **`failed`** / **`inactive`**. **`waitForBareInitdUnits(names, timeoutMs)`** polls until listed units are **`active`** (exposed as **`ctx.bareOsAwaitInitdUnits`**).
- **`listBareServices()`**, **`getBareServiceRuntime(name)`**, **`findBareServiceDefinition(name)`**, **`startBareService` / `stopBareService` / `restartBareService`** — introspection and lifecycle (used by the CLI below)
- **`registerKernelShutdownHook(fn)`** + **`runKernelShutdownHooks()`** — async-friendly teardown before disposers (REPL **`session.cleanup`** awaits hooks, then **`stopBareInitd()`**)
- **`registerBareInitdDisposer(fn)`** + **`stopBareInitd()`** — for intervals and synchronous teardown
+4
View File
@@ -39,6 +39,10 @@ The **prompt** (`[user@host:path] > `) is applied by the booters readline lay
| **`BARE_OS_BOOT_ALLOWLIST=1`** | Only run boot snippet lines whose first shell token is listed in **`/etc/bare-os/boot.allow`** (plus safe builtins); distributors can start from **`etc/bare-os/boot.allow.example`** on the system image. Pair with **`BARE_OS_BOOT_STRICT`** to exit on the first disallowed or failing line. |
| **`BARE_OS_EXEC_MAX_DEPTH`** | Max nested **`execLine`** depth (host → session; default **64**). |
| **`ctx.bareOsPublishBootReady(...)`** | Kernel calls this when boot is complete; populates **`/run/bare-os/ready`** (**`1`** / **`0`**) and **`/run/bare-os/boot.json`** (**`imageDigest`**, **`pearChannel`**, **`pearRelease`** are pre-seeded from host env when set — see [environment variables reference](../docs/reference/environment-and-posix-appendix.md#14-environment-variables-complete-list)). |
| **`BARE_OS_BOOT_MANIFEST`** | When **`1`** / **`true`**, the stock kernel verifies **`/etc/bare-os/boot.manifest.json`** against an expected SHA-256 (see kernel **`init.js`** and **`ctx.bareOsBootFileSha256Hex`**). Example layout: [`kernel/etc/bare-os/boot.manifest.example.json`](../kernel/etc/bare-os/boot.manifest.example.json). |
| **`BARE_OS_BOOT_MANIFEST_SIGN`**, **`BARE_OS_BOOT_MANIFEST_PUBKEY_HEX`** | Optional **Ed25519** over the **raw manifest bytes**: expects **`/etc/bare-os/boot.manifest.sig`** and **`ctx.bareOsVerifyBootManifestSignature`** (host/booter). Mismatch fails boot with a clear stderr line. |
| **`ctx.bareOsRegisterBootPhaseHook` / `bareOsInvokeBootPhaseHooks`** | Kernel extensions can observe **`before:` / `after:`** stock phases (e.g. **`rc`**, **`repl`**) without replacing **`init.js`**. See [developer guide §2](../developer-guide/02-the-context-object.md). |
| **`/etc/bare-os/selftest.d/`** | Optional digit-prefixed **`*.sh`** snippets run after the main boot path when **`BARE_OS_KERNEL_SELFTEST`** is enabled (same **`execLine`** rules as other boot snippets). Pair with **`BARE_OS_SELFTEST_FORMAT=tap`** for CI-friendly stderr. |
### Custom `init.js` contract
+5 -5
View File
@@ -10,7 +10,7 @@ Bare OS targets a **usable subset** of [POSIX.1-2017](https://pubs.opengroup.org
| Expectation (full POSIX) | Bare OS reality |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`sh`** grammar (`for`, subshells, …) | Line-at-a-time shell: builtins + **`/bin`**; lists with **`;`** (outside **`if`/`fi`**), **`&&`**, **`\|`** pipelines; bounded **`if`** **`then`** **[** **`else`** **]** **`fi`** (condition = last exit status like **`&&`**)—no **`for`**, groups, or full **`sh`** grammar. |
| **`sh`** grammar (full POSIX) | Line-at-a-time shell: builtins + **`/bin`**; lists with **`;`** (outside compound statements), **`&&`**, **`\|`** pipelines; bounded **`if`** **`fi`**; bounded **`while`** / **`for`** (iteration cap **`BARE_OS_SHELL_LOOP_MAX`**, default **10000**); bounded **`case`** … **`esac`** (**`BARE_OS_SHELL_CASE_MAX_BRANCHES`**, default **32**). No subshells, **`$(…)`**, or full **`sh`** grammar. |
| **Processes, `fork`, pipes as OS primitives** | Pipelines are simulated by capturing **`console.log`** (and merged **`console.error`** when **`2>&1`** is used) into the next command. |
| **`chown` / `chgrp` / real UIDs across users** | Single-session identity; metadata carries **uid/gid** for display and checks. |
| **FIFOs, `mknod`, real devices** | No kernel FIFOs or **`mknod`**; **`mkfifo`** creates **in-memory** channels under **`/run/bare-os/ipc/<name>`** (see **`bare-os-ipc.js`**). |
@@ -37,7 +37,7 @@ Hyperdrive does not always behave like a POSIX directory tree. Empty directories
### 2.3 Pseudo **`/proc`**, **`/sys`**, **`/run`**, **`/dev`**, and session **`/tmp`**
- **`/proc`**, **`/sys`**, **`/run`**, **`/dev`** — read-only synthetic trees except **`/dev/null`** and **`/dev/zero`** accept writes that are discarded (see [Chapter 4](04-the-booter-runtime.md)). Other pseudo **`writeFile`** / **`unlink`** / **`chmod`** paths fail as documented there. Extra Linux-shaped stubs include **`/proc/cpuinfo`**, **`/proc/loadavg`**, **`/proc/net/dev`**, **`/proc/diskstats`**, **`/proc/bare_os_quotas`** (JSON quotas + session stats), **`/proc/bare_os_resources`** (unified resource snapshot), **`/proc/bare_os_features`** (documented capability bitmask), **`/proc/bare_os_session_stats`**, **`/proc/self/exe`**, **`/sys/class/net/lo`**, **`/sys/fs/bare_os/build_id`**, **`/run/bare-os/virtual/*`** (optional kernel-registered readers), and **`/dev/urandom`** (each **`readFile`** of urandom returns a **bounded** buffer; **not** suitable for cryptography).
- **`/proc`**, **`/sys`**, **`/run`**, **`/dev`** — read-only synthetic trees except **`/dev/null`** and **`/dev/zero`** accept writes that are discarded (see [Chapter 4](04-the-booter-runtime.md)). Other pseudo **`writeFile`** / **`unlink`** / **`chmod`** paths fail as documented there. Extra Linux-shaped stubs include **`/proc/cpuinfo`**, **`/proc/loadavg`**, **`/proc/net/dev`**, **`/proc/diskstats`**, **`/proc/bare_os_quotas`**, **`/proc/bare_os_resources`**, **`/proc/bare_os_features`**, **`/proc/bare_os_session_stats`**, **`/proc/bare_os_swarm`**, **`/proc/bare_os_replication`**, **`/proc/bare_os_capabilities`** (and **`/proc/bare_os_capabilities.json`**), **`/proc/bare_os_bootstrap`**, **`/proc/self/exe`**, **`/sys/class/net/lo`**, **`/sys/fs/bare_os/build_id`**, **`/run/bare-os/virtual/*`**, **`/run/bare-os/unit-journal/*.ndjson`**, and **`/dev/urandom`** (each **`readFile`** of urandom returns a **bounded** buffer; **not** suitable for cryptography unless **`BARE_OS_URANDOM_CRYPTO`** is left at default).
- **`/tmp`** — writable on the **personal** drive under **`/.bare-os/tmp/<HOME-basename>/…`**, isolated like **`$HOME`** and **`/var/log`**.
### 2.4 `chmod` (octal and symbolic)
@@ -58,7 +58,7 @@ Hyperdrive does not always behave like a POSIX directory tree. Empty directories
## 3. Shell lists, pipelines, and builtins (`packages/bare-os-booter/lib/shell.js`)
**Top-level syntax:** the line is split on **`;`** into separate lists (semicolons **inside** an **`if`** … **`fi`** block do not end the outer statement). **`if`** **`then`** **[** **`else`** **]** **`fi`** uses the same **`&&`** / **`||`** / pipeline rules inside the condition and each branch; the condition is true when the last evaluated command in that **`&&`/`||`** list exits **0**. Each list is an **AND-OR** chain: **pipelines** separated by **`&&`** or **`||`**, evaluated left-to-right with POSIX-style short-circuiting (**`ctx.exitCode`** — treat missing as **0**). Within a pipeline, **`|`** connects stages as before (simulated stdin between utilities).
**Top-level syntax:** the line is split on **`;`** into separate lists (semicolons **inside** compound blocks do not end the outer statement). **`if`** **`then`** **[** **`else`** **]** **`fi`** uses the same **`&&`** / **`||`** / pipeline rules inside the condition and each branch; the condition is true when the last evaluated command in that **`&&`/`||`** list exits **0**. **`while`** **`list;`** **`do`** **`list;`** **`done`** and **`for`** **`name`** **`in`** **words** **`;`** **`do`** **`list;`** **`done`** repeat the body while respecting **`BARE_OS_SHELL_LOOP_MAX`**. **`case`** **`word`** **`in`** **`pattern)`** **`list`** **`;;`** … **`esac`** matches the first glob pattern (token-safe); branch count is capped by **`BARE_OS_SHELL_CASE_MAX_BRANCHES`**. Each list is an **AND-OR** chain: **pipelines** separated by **`&&`** or **`||`**, evaluated left-to-right with POSIX-style short-circuiting (**`ctx.exitCode`** — treat missing as **0**). Within a pipeline, **`|`** connects stages as before (simulated stdin between utilities).
**Background / jobs (subset):** a trailing **`&`** on a top-level list runs that list asynchronously (microtask). **`jobs`** lists recent jobs; **`fg`** awaits the selected (or latest) job; **`bg`** is a stub (no stopped-job resume). This is **not** POSIX job control (no real processes or signals).
@@ -136,7 +136,7 @@ Sources: **`packages/bare-os-coreutils/src/<name>.js`**. **Authoritative sorted
| **`tee`** | **`-a`** append; duplicates stdin to files and stdout. |
| **`sed`** | Large subset — see §6. |
| **`awk`** | Substantial interpreter — see §7. |
| **`grep`** | **`-F`**, **`-i`**, **`-v`**, **`-w`**, **`-x`**, **`-n`**, **`-c`**, **`-l`**, **`-o`**, **`-m`**, **`-A`/`-B`/`-C`**, \*\*`--color=never | always | auto`**, **`-e`**, **`-f`**, etc.; JS **`RegExp`\*\* (not PCRE / full GNU). |
| **`grep`** | **`-F`**, **`-i`**, **`-v`**, **`-w`**, **`-x`**, **`-n`**, **`-c`**, **`-l`**, **`-o`**, **`-m`**, **`-r`/`-R`** with **`--include`**, **`--exclude`**, **`--exclude-dir`** (glob count capped by **`BARE_OS_GREP_FILTER_MAX`**, default **32**), **`-A`/`-B`/`-C`**, **`--color=never` / `always` / `auto`**, **`-e`**, **`-f`**, etc.; JS **`RegExp`** (not PCRE / full GNU). |
| **`base64`** | **`-d`/`--decode`**, **`-w`** line wrap; decode uses **`bareOsEmitRaw`** when **`console.log`** would corrupt binary. |
| **`base32`** | RFC 4648 encode/decode; decode path same raw-output contract as **`base64`**. |
| **`basenc`** | **`--base16`** (hex) encode/decode only; other alphabets not implemented. |
@@ -215,7 +215,7 @@ All other commands from **`build.mjs`** not listed here follow the summaries in
**Engine:** **`packages/bare-os-coreutils/lib/sed-engine.js`** (prepended before **`src/sed.js`** at build time).
**CLI:** **`sed`** supports **`-n`**, **`-E`/`-r`**, multiple **`-e`**, **`-f`**, and operands as files or stdin.
**CLI:** **`sed`** supports **`-n`**, **`-E`/`-r`**, **`-z`** (NUL-separated “lines”; max records **`BARE_OS_SED_NULL_MAX_RECORDS`**, default **100000**), multiple **`-e`**, **`-f`**, and operands as files or stdin.
**Broadly supported:** line addresses (**`#`**, **`$`**, **`/re/`**, ranges, **`first~step`**), **`s///`** with common flags (**`g`**, **`p`**, digit), **`y///`**, **`d`/`D`/`p`/`P`/`n`/`N`**, hold space (**`h`/`H`/`g`/`G`/`x`**), **`b`/`t`/`:label`**, **`q`**, **`r`/`w`**, **`=`**, **`l`**, **`a`/`i`/`c`** (backslash forms). **`r`** reads paths via a preload scan + **`vfs.readFile`**; **`w`** appends via **`vfs.writeFile`**.