# n-OS-tr

**A privacy-preserving, ephemeral operating system whose identity and configuration live on [Nostr](https://nostr.com).**

You boot n-OS-tr. It asks for a 12-word mnemonic (or generates one for you). From that mnemonic it deterministically derives every key the system needs — your personal identity, your relay keys, your blob-store keys, your mesh identity — using the standard [NIP-06](https://github.com/nostr-protocol/nips/blob/master/06.md) derivation scheme. Your preferences, dotfiles, bookmarks, and personal configuration are then loaded from Nostr relays, decrypted with your own key, and projected into your home directory on a RAM-backed filesystem.

When you power off, **everything disappears**. There is no local trace that you were ever on this machine.

The next time you boot — on the same machine, a different machine, a Pi in your pocket — you type the same 12 words and your environment materializes again.

---

## Status

- **Phase 2 Slice B+C: live.** Base ISO with [`fips`](https://github.com/) mesh daemon, [`c-relay`](https://github.com/) Nostr relay, [`ginxsom`](https://github.com/) Blossom blob server, nginx reverse proxy, first-boot provisioning, and smoke test are all green. See [`plans/slice_bc_fips_crelay.md`](plans/slice_bc_fips_crelay.md).
- **Phase 3 (identity + config): planned.** Mnemonic-driven identity subsystem and Nostr-as-home-directory are in design. See [`plans/identity_subsystem.md`](plans/identity_subsystem.md) and [`plans/nostr_config_projection.md`](plans/nostr_config_projection.md).
- **Phase 4 (Pi flavor and GUI): scoped.** Pi Zero 2 W live image and an optional amd64 GUI flavor come after the identity/config work stabilizes.

---

## The core idea in three sentences

1. **One mnemonic = your whole identity.** A single BIP-39 seed phrase deterministically generates every key the OS and its apps need, via [NIP-06](https://github.com/nostr-protocol/nips/blob/master/06.md) (`m/44'/1237'/{index}'/0/0`).
2. **All config lives on Nostr.** Replaceable events signed by your main key hold your dotfiles, preferences, and per-app state, encrypted to yourself with [NIP-44](https://github.com/nostr-protocol/nips/blob/master/44.md).
3. **The OS is ephemeral.** Root filesystem is an overlay on tmpfs. Shutdown wipes memory. No persistent local state by default — not even `machine-id`, Wi-Fi credentials, or shell history.

---

## The key tree

Every key in the system is deterministically derived from your single 12-word mnemonic. Each role gets its own index on the NIP-06 derivation path:

| Index | Role                 | Used by                                                    |
|-------|----------------------|------------------------------------------------------------|
| `0`   | Main account         | Your public Nostr identity (profile, posts, social graph)  |
| `1`   | Throwaway / test     | Experimental account, scratch work, testing                |
| `2`   | c-relay admin        | Admin key for your local [`c-relay`](includes/c-relay/) personal Nostr relay |
| `3`   | ginxsom server       | Server key for your local [`ginxsom`](includes/ginxsom/) Blossom blob store |
| `4`   | fips node            | Mesh node identity for the [`fips`](includes/fips/) daemon (also yields your fips IPv6) |
| `5`+  | Reserved future uses | New apps request an index from the identity agent at install time |

An app never sees the mnemonic or the seed. It asks the local **identity agent** for "the key assigned to role X", and the agent derives and returns it (or signs on its behalf via [NIP-46](https://github.com/nostr-protocol/nips/blob/master/46.md)). Details in [`plans/identity_subsystem.md`](plans/identity_subsystem.md).

The derivation method itself is not invented — it's standard NIP-06 and matches the reference implementation in [`/home/user/lt/client/www/tools.html`](../client/www/tools.html) (`nostr-tools.nip06.privateKeyFromSeedWords(mnemonic, "", index, 0, 0)`).

**Crypto core.** All mnemonic handling, key derivation, event signing, NIP-44 encryption, and NIP-46 signer/bunker flows are implemented by the vendored [`includes/nostr_core_lib`](includes/nostr_core_lib/) library — a C implementation of the relevant NIPs already unit-tested in [`includes/nostr_core_lib/tests`](includes/nostr_core_lib/tests/). The identity agent and config projection services are thin wrappers around its API; n-OS-tr does not reimplement any Nostr crypto itself.

**Language and toolchain.** Every n-OS-tr binary we ship (identity-agent, TUI, config-loader, config-writer, smoketest helpers) is **C99, statically linked against musl libc**, built inside Alpine Docker — the same pattern [`includes/nostr_core_lib`](includes/nostr_core_lib/), [`includes/ginxsom`](includes/ginxsom/), and [`includes/c-relay`](includes/c-relay/) already use. Output is self-contained static ELFs (`ldd` reports "not a dynamic executable"), identical toolchain across amd64 and arm64, no Python or Node.js at runtime. Details in [`plans/tui_login.md §0.1`](plans/tui_login.md#01-toolchain-alpine--musl-dev-built-in-docker).

```mermaid
flowchart LR
    M[12-word BIP-39 mnemonic<br/>user enters or generates at boot]
    M --> S[BIP-32 seed]
    S --> D0[Index 0<br/>main account]
    S --> D1[Index 1<br/>throwaway]
    S --> D2[Index 2<br/>c-relay admin]
    S --> D3[Index 3<br/>ginxsom]
    S --> D4[Index 4<br/>fips node]
    S --> DN[Index 5..N<br/>future roles]
```

---

## The privacy contract

n-OS-tr makes a small number of hard promises to the user. These are non-negotiable; they're enforced by the image build and audited by the smoke test. The full list is in [`plans/threat_model.md`](plans/threat_model.md).

The short version:

- **Your mnemonic never touches disk.** Not swap, not logs, not journal, not `~/.bash_history`, not crash dumps.
- **The root filesystem is ephemeral.** Every boot is a clean slate; shutdown leaves no recoverable trace on the boot media.
- **No cross-boot fingerprint.** `machine-id`, MAC address, hostname, and Wi-Fi credentials do not persist by default.
- **No on-disk logs.** systemd-journald runs in volatile mode. User app caches are tmpfs-backed.
- **Your config is encrypted on Nostr to yourself.** Relay operators see ciphertext and metadata only. Run your own [`c-relay`](includes/c-relay/) to keep even the metadata local.
- **Identity can be walked away from.** Power off, remove the USB/SD, destroy it if you want — the only recoverable identity is the one you carry in your head or on paper.

---

## Architecture at a glance

```mermaid
flowchart TB
    subgraph boot[Boot sequence]
        direction TB
        B1[Kernel + initramfs]
        B2[tmpfs overlay root<br/>= ephemeral]
        B3[privacy-hardener<br/>MAC rand, swap off,<br/>volatile journald,<br/>fresh machine-id]
        B4[identity-agent<br/>prompt for 12 words<br/>or generate new]
        B5[network-bootstrap<br/>Wi-Fi / Ethernet /<br/>fips mesh]
        B6[config-loader<br/>Nostr replaceable events<br/>projected to ~/]
        B7[user shell or GUI]
        B1 --> B2 --> B3 --> B4 --> B5 --> B6 --> B7
    end

    subgraph core[Core subsystems]
        ID[identity-agent<br/>NIP-06 derivation<br/>NIP-46 signer]
        CFG[config projection<br/>NIP-44 encrypted]
        HARD[privacy-hardener<br/>+ shutdown-wiper]
    end

    subgraph opt[Optional user services]
        FIPS[fips mesh daemon]
        CREL[c-relay personal relay]
        GINX[ginxsom + nginx blob store]
    end

    B4 --- ID
    B6 --- CFG
    B3 --- HARD
    B7 -.optional.-> FIPS
    B7 -.optional.-> CREL
    B7 -.optional.-> GINX
```

The "core subsystems" (identity, config, hardening) define the product. Everything else — fips, c-relay, ginxsom, nginx, the GUI, the Pi HAT drivers — is optional user-facing infrastructure layered on top.

---

## Form factors

n-OS-tr is one product, delivered as multiple image flavors that all share the same core subsystems.

| Flavor                              | Status          | Use case                                                                                 |
|-------------------------------------|-----------------|------------------------------------------------------------------------------------------|
| **amd64 live ISO (text console)**   | Live (Phase 2)  | Boot any x86_64 laptop/desktop from USB, get a privacy-preserving session.               |
| **amd64 live ISO with GUI**         | Planned         | Adds a minimal window manager for users who want graphical apps on the same session.     |
| **Raspberry Pi Zero 2 W live image**| Planned         | Pocket-sized hardware token + mesh node; Waveshare LCD HAT as the mnemonic-entry UI.     |
| **Other Pi models (Pi 4, CM4)**     | Possible later  | Same stack, larger form factor with HDMI-GUI capable.                                    |

The design goal is that a user who knows their 12 words can sit down in front of any of these, boot, type their phrase, and have the same configuration materialize. See [`plans/iso_architecture.md`](plans/iso_architecture.md) for the amd64 build details today and the companion project [`raspberry_pi_zero_nostr`](../raspberry_pi_zero_nostr) for current Pi exploration work that will fold into the monorepo later.

---

## Current service stack (Phase 2)

The live Phase 2 Slice B+C ISO ships these services out of the box. They are *infrastructure for advanced users*, not the core product — the core product is identity + config, which is Phase 3.

| Service                                                                        | Role                                                                     |
|--------------------------------------------------------------------------------|--------------------------------------------------------------------------|
| [`n-os-tr-firstboot`](iso/config/includes.chroot/usr/local/sbin/n-os-tr-firstboot) | Generates ephemeral service keypairs, issues self-signed TLS, configures fips interface |
| [`fips`](includes/fips/)                                                       | Nostr-addressed mesh networking daemon (virtual IPv6, mesh routing)      |
| [`c-relay`](includes/c-relay/)                                                 | High-performance C Nostr relay running locally                           |
| [`ginxsom`](includes/ginxsom/)                                                 | Blossom blob server, served via nginx reverse proxy                      |
| [`nginx`](iso/config/includes.chroot/etc/nginx/sites-available/n-os-tr.conf)   | TLS-terminating reverse proxy for relay and blob endpoints               |
| [`n-os-tr-smoketest`](iso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest) | End-to-end health check (21 checks, currently all green)                |

When Phase 3 lands, these services become **opt-in keys at NIP-06 indices 2, 3, 4** — they inherit deterministic identities from the user's mnemonic instead of generating fresh keys on first boot.

---

## Planning documents

Read these in order for the full picture:

1. [`README.md`](README.md) — this file. Vision and structure.
2. [`plans/threat_model.md`](plans/threat_model.md) — the privacy contract. What we defend, what we don't, forbidden behaviors.
3. [`plans/identity_subsystem.md`](plans/identity_subsystem.md) — how the 12-word mnemonic becomes every key in the system.
4. [`plans/nostr_config_projection.md`](plans/nostr_config_projection.md) — how Nostr events become your home directory.
5. [`plans/iso_architecture.md`](plans/iso_architecture.md) — the current amd64 live-build architecture.
6. [`plans/slice_bc_fips_crelay.md`](plans/slice_bc_fips_crelay.md) — Phase 2 Slice B+C implementation notes (shipped).
7. [`plans/network_boot.md`](plans/network_boot.md) — research and notes on network-boot delivery options.

---

## Running the current ISO

For practical "how do I build and boot it" instructions see [`docs/RUNNING.md`](docs/RUNNING.md).

TL;DR:

```bash
# Build
./build.sh --clean

# Run locally in a VM (headless serial)
HEADLESS=1 ./scripts/run-iso.sh

# Or flash to USB and boot real hardware
sudo dd if=iso/live-image-amd64.hybrid.iso of=/dev/sdX bs=4M status=progress
```

Once booted, run [`n-os-tr-smoketest`](iso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest) for an end-to-end health check.

---

## Developer notes

- Historical Debian live-build reference material (tutorials, package discovery, GUI/splash options, minimization, persistence) has been moved to [`docs/debian_live_notes.md`](docs/debian_live_notes.md). Nothing in there is authoritative for the product — it's a cheatsheet we built up while bootstrapping the ISO.
- The amd64 live image is built with [`live-build`](live-build/) via [`build.sh`](build.sh). The ISO itself is produced at `iso/live-image-amd64.hybrid.iso`.
- Service artifacts staged into the ISO come from submodules under [`includes/`](includes/): [`fips`](includes/fips/) (mesh daemon), [`c-relay`](includes/c-relay/) (Nostr relay), [`ginxsom`](includes/ginxsom/) (Blossom server), and [`nostr_core_lib`](includes/nostr_core_lib/) (the C Nostr library used as the crypto core for identity and config projection).

---

## Licensing and contributing

TBD. The product principle is: **you should always be able to build and run this from source, verify it matches the shipped image, and run it on your own hardware with no external dependencies.** Anything that violates that principle does not belong in the product.

---

## Why this exists

Operating systems today are identity sinks. They remember your SSIDs, your login history, your hostnames, your keys, your clipboard, your browsing state. When a machine changes hands — sold, seized, borrowed, stolen — those traces go with it.

At the same time, Nostr gives us something new: **a place to keep identity and preferences that is not tied to any particular computer, account, server, or company**. Your keys are just math. Your preferences are just signed events. Any machine that can do elliptic-curve crypto can reconstitute your setup.

n-OS-tr puts those two facts together. The computer is disposable. The identity and configuration are portable. And the glue between them — the mnemonic, the derivation scheme, the config projection — is open, standard, and auditable.

That's the product.
