v0.0.1 - Reorganize ISO build tree, add docs/plans/scripts, and stage Phase 2 Slice B+C service integration artifacts
28 KiB
Slice B + C: Add fips and c-relay to the n-OS-tr ISO
Status: Ready for implementation
This document specifies the work required to enable the fips
mesh-routing daemon and the c-relay Nostr relay on the
live ISO built by build.sh, replacing the current Slice A
(ginxsom + nginx only) with the full three-service stack planned in
iso_architecture.md.
1. Design Decisions (captured from user)
| # | Topic | Decision |
|---|---|---|
| 1 | Source of c-relay binary | User-provided, already downloaded into includes/c-relay/ |
| 2 | Source of fips binaries | Build locally via cargo deb during build.sh |
| 3 | c-relay admin nsec strategy | Ephemeral — c-relay self-provisions per boot, admin nsec captured from journald |
| 4 | fips identity | Ephemeral — new npub per boot, no persistent key management for this slice |
| 5 | fips peer config | Connect to the same public bootstrap node used elsewhere in the repo: npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98 at 217.77.8.91:2121 (UDP), per examples/sidecar-nostr-relay/.env et al. |
| 6 | fips transport | Ethernet enabled, plus UDP for the static peer |
| 7 | fips-gateway | Disabled (default) |
| 8 | c-relay exposure | nginx reverse-proxies wss://host/relay → ws://127.0.0.1:8888/; nginx reverse-proxies /admin/ → http://127.0.0.1:8888/api/ |
| 9 | Scope | Full Slice B+C — services, nginx wiring, package deps, smoke test, MOTD, README updates |
| 10 | Key management / identity continuity | Out of scope for this slice — revisit in a later pass |
2. What Already Exists (Slice A baseline)
Confirmed present and working, per source inspection:
iso/auto/config— live-build configiso/config/package-lists/base.list.chroot— nginx-light, spawn-fcgi, ca-certificates, curl, jq, vim, htopiso/config/includes.chroot/etc/systemd/system/ginxsom.serviceiso/config/includes.chroot/etc/systemd/system/n-os-tr-firstboot.serviceiso/config/includes.chroot/etc/nginx/sites-available/n-os-tr.conf—:443TLS, Blossom routing, static landing pageiso/config/includes.chroot/usr/local/sbin/n-os-tr-firstboot— generates ginxsom nsec + self-signed TLSiso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest— 5 PASS + 8 SKIP placeholderiso/config/includes.chroot/usr/local/bin/nak— Nostr CLI helperiso/config/includes.chroot/usr/local/bin/ginxsom/ginxsom-fcgi— Blossom FastCGI binaryiso/config/hooks/live/0020-enable-services.hook.chroot— enables nginx, ginxsom, firstboot
Slice A smoke test passes 5 PASS, 0 FAIL, 8 SKIP on a freshly-booted USB.
3. What Needs to Change (target state)
flowchart LR
subgraph Build [Build-time build.sh]
BS[build.sh]
CDB[cargo deb in<br/>includes/fips]
FDeb[iso/local-artifacts/fips_0.3.0_amd64.deb]
CRX[includes/c-relay/c_relay_x86]
CRC[iso/local-artifacts/c_relay_x86]
BS --> CDB --> FDeb
BS --> CRC
end
subgraph Chroot [live-build chroot phase]
H1[0010-fetch-artifacts.hook.chroot]
FDeb --> H1
CRC --> H1
H1 -->|dpkg -i| FInst[/usr/bin/fips etc]
H1 -->|install -m 0755| CInst[/opt/c-relay/c_relay_x86]
H1 -->|adduser --system| CUsr[c-relay system user]
H1 -->|write fips.yaml| FCfg[/etc/fips/fips.yaml]
end
subgraph Boot [Runtime at boot]
Fb[n-os-tr-firstboot]
Fips[fips.service]
FDns[fips-dns.service]
CRel[c-relay.service]
Gx[ginxsom.service]
Ng[nginx.service]
Fb --> Gx
Fips --> FDns
Ng -->|wss /relay| CRel
Ng -->|http /admin/| CRel
end
Summary of changes
| Area | Change |
|---|---|
| Build system | build.sh gains a pre-build step: build fips .deb via cargo deb and stage artifacts into iso/local-artifacts/ |
| Artifact layout | New directory iso/local-artifacts/ holds fips_*_amd64.deb and c_relay_x86 — gitignored |
| Chroot hook (new) | iso/config/hooks/live/0010-fetch-artifacts.hook.chroot installs those two artifacts into the chroot |
| Package list | iso/config/package-lists/base.list.chroot adds runtime deps: libdbus-1-3, iproute2, nftables (optional for gateway mode later) |
| fips config | New iso/config/includes.chroot/etc/fips/fips.yaml overriding the package default with ethernet + static UDP peer enabled |
| c-relay service | New iso/config/includes.chroot/etc/systemd/system/c-relay.service — adapted from upstream unit |
| c-relay user | Chroot hook creates c-relay system user + /opt/c-relay/ working dir |
| nginx config | iso/config/includes.chroot/etc/nginx/sites-available/n-os-tr.conf gains /relay wss upgrade and /admin/ proxy locations |
| Service-enable hook | 0020-enable-services.hook.chroot also enables fips.service, fips-dns.service, c-relay.service |
| Smoke test | n-os-tr-smoketest replaces the 8 SKIPs with real checks |
| MOTD / README | First-boot script and docs updated to surface how to find c-relay admin nsec and fips identity |
.gitignore |
Add iso/local-artifacts/ |
4. Concrete Artifact Details
4.1 c-relay static binary
- Source:
includes/c_relay_static_x86_64— user-downloaded static-musl build, already present at the top level ofincludes/(NOT insideincludes/c-relay/). Filename confirmed by directory listing. - Staged as:
iso/config/includes.chroot_before_packages/live-artifacts/c_relay_x86(canonical name used by the chroot hook and systemd unit — we rename on copy soc-relay.servicecan reference a stable filename regardless of which upstream build variant the user drops in). - Target in chroot:
/opt/c-relay/c_relay_x86, mode0755, ownerc-relay:c-relay. - Copied by:
build.shcopiesincludes/c_relay_static_x86_64→ staging area → chroot hook installs to/opt/c-relay/.
4.2 iso/local-artifacts/fips_0.3.0_amd64.deb
- Source: built by
build.shviacd includes/fips && packaging/debian/build-deb.sh. Requirescargo-debinstalled on the build host (cargo install cargo-debif absent;build.shwill check and fail clearly). - Contents (per
Cargo.toml):/usr/bin/fips,/usr/bin/fipsctl,/usr/bin/fipstop,/usr/bin/fips-gateway/etc/fips/fips.yaml(package default — will be overridden by our includes.chroot version)/etc/fips/hosts/lib/systemd/system/fips.service,/lib/systemd/system/fips-dns.service,/lib/systemd/system/fips-gateway.service/usr/lib/fips/fips-dns-setup,/usr/lib/fips/fips-dns-teardown/usr/lib/tmpfiles.d/fips.conf
- Runtime deps (per Cargo.toml):
libc6, systemd, libdbus-1-3, recommendsbluez(skipped — not needed for non-BLE). - Installed by: chroot hook runs
dpkg -i /tmp/artifacts/fips_*_amd64.debthen cleans up. The postinst enablesfips.serviceandfips-dns.serviceautomatically.
4.3 iso/config/includes.chroot/etc/fips/fips.yaml
Overrides the Debian-packaged default at /etc/fips/fips.yaml. The live-build
includes.chroot mechanism copies this on top after package install. Content:
# n-OS-tr fips configuration.
# Ephemeral identity: new keypair every boot (default).
# To make identity persistent across reboots on a live USB with a
# persistence partition, set node.identity.persistent: true.
node:
identity:
# ephemeral by default
tun:
enabled: true
name: fips0
mtu: 1280
dns:
enabled: true
port: 5354
transports:
udp:
bind_addr: "0.0.0.0:2121"
tcp:
bind_addr: "0.0.0.0:8443"
ethernet:
# Ethernet transport auto-discovers LAN peers.
# interface: omitted → fips picks the first non-loopback interface.
# Override with an explicit interface name if your board uses
# something other than the default (e.g. enp5s0, eno1, eth0).
discovery: true
announce: true
auto_connect: true
accept_connections: true
# Static peer for internet bootstrap.
# Matches the same "fips-test-node" / "vps-chi" public node used across
# the repo's example configs (see includes/fips/examples/... and
# includes/fips/testing/sidecar/.env).
peers:
- npub: "npub1qmc3cvfz0yu2hx96nq3gp55zdan2qclealn7xshgr448d3nh6lks7zel98"
alias: "fips-test-node"
addresses:
- transport: udp
addr: "217.77.8.91:2121"
connect_policy: auto_connect
Notes:
- Omitting
ethernet.interfacerelies on fips's auto-selection logic. If that doesn't pick a sensible interface, addinterface: "eth0"(verified post-boot viaip link show). - Keeping the
udpbootstrap peer in addition toethernetgives the mesh internet reachability even when the LAN has no other fips peers.
4.4 iso/config/includes.chroot/etc/systemd/system/c-relay.service
Adapted from upstream with minor tweaks for the live environment:
[Unit]
Description=C Nostr Relay (n-OS-tr slice C)
Documentation=file:///usr/share/doc/n-os-tr/README
After=network.target n-os-tr-firstboot.service
Wants=network-online.target
[Service]
Type=simple
User=c-relay
Group=c-relay
WorkingDirectory=/opt/c-relay
Environment=DEBUG_LEVEL=0
# c-relay self-provisions admin + relay keys on first start and prints
# the admin nsec to stdout (captured by journald).
ExecStart=/opt/c-relay/c_relay_x86 --debug-level=${DEBUG_LEVEL}
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=c-relay
# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/c-relay
PrivateTmp=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET AF_INET6
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
4.5 Updated nginx site — /relay wss + /admin/ proxy
New locations appended to iso/config/includes.chroot/etc/nginx/sites-available/n-os-tr.conf inside the existing server { listen 443 ssl; ... } block, before the ginxsom FastCGI blocks:
# --- c-relay reverse proxy (slice C) ---------------------------------
# Nostr relay WebSocket: wss://host/relay → ws://127.0.0.1:8888/
# The client library expects a WebSocket upgrade on /relay; c-relay
# itself listens on "/" so we rewrite and proxy to its root.
location = /relay {
proxy_pass http://127.0.0.1:8888/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
# NIP-11 relay info doc (available at wss://host/relay with
# Accept: application/nostr+json). Proxied to the same backend.
# If you want /relay (GET without upgrade) to return NIP-11 too,
# the location above already handles it — c-relay's NIP-11 handler
# triggers based on the Accept header, not the path.
# c-relay embedded web admin UI: https://host/admin/ → http://127.0.0.1:8888/api/
location /admin/ {
proxy_pass http://127.0.0.1:8888/api/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Notes:
- The
/admin/path deliberately overlaps with a Blossom admin path, but Blossom's admin routes go via the FastCGI@ginxsomnamed location and c-relay's admin is explicitly reverse-proxied — nginx's longest-prefix match means/admin/→ c-relay wins for GET/POST, and ginxsom admin is reached via a different path (if ginxsom has one). Potential conflict with Slice A — need to confirm ginxsom doesn't rely on/admin/. Current n-os-tr.conf:53 haslocation /admin/ { try_files $uri @ginxsom; }— this will need to be removed or renamed (e.g./blossom-admin/) to avoid collision. See §6 Open Questions. - The landing page at
/(static/var/www/html/index.html) is unaffected.
4.6 New chroot hook — 0010-fetch-artifacts.hook.chroot
#!/bin/sh
# Install c-relay and fips into the chroot from iso/local-artifacts/.
set -e
ART=/live-artifacts
if [ ! -d "$ART" ]; then
echo "[fetch-artifacts] no $ART; skipping" >&2
exit 0
fi
# --- c-relay -----------------------------------------------------------
if [ -f "$ART/c_relay_x86" ]; then
echo "[fetch-artifacts] installing c-relay binary"
# Create system user and directory
if ! getent passwd c-relay >/dev/null 2>&1; then
adduser --system --no-create-home --group --home /opt/c-relay c-relay
fi
mkdir -p /opt/c-relay
install -m 0755 -o c-relay -g c-relay \
"$ART/c_relay_x86" /opt/c-relay/c_relay_x86
chown -R c-relay:c-relay /opt/c-relay
else
echo "[fetch-artifacts] WARNING: $ART/c_relay_x86 not found" >&2
fi
# --- fips --------------------------------------------------------------
FIPS_DEB=$(ls "$ART"/fips_*_amd64.deb 2>/dev/null | head -1 || true)
if [ -n "$FIPS_DEB" ] && [ -f "$FIPS_DEB" ]; then
echo "[fetch-artifacts] installing fips from $FIPS_DEB"
dpkg -i "$FIPS_DEB" || apt-get -f install -y
else
echo "[fetch-artifacts] WARNING: no fips_*_amd64.deb in $ART" >&2
fi
How $ART gets populated in the chroot: live-build copies
iso/local-artifacts/ into
/live-artifacts/ inside the chroot via an includes.chroot_before_packages/
entry that bind-mounts or symlinks the directory, OR more simply, we place
the artifacts directly under
iso/config/includes.chroot_before_packages/live-artifacts/ so live-build
copies them before package install. See §5 step 2 for the exact location.
4.7 Updated build.sh
Inserted before the sudo "$REPO_ROOT/lb-wrapper.sh" config line:
# --- Stage Slice B artifacts ------------------------------------------------
ARTIFACTS="$WORKSPACE_ISO_DIR/config/includes.chroot_before_packages/live-artifacts"
mkdir -p "$ARTIFACTS"
# 1. c-relay: copy the user-provided binary from includes/c-relay/
CRELAY_SRC=""
for candidate in \
"$REPO_ROOT/includes/c-relay/c_relay_x86" \
"$REPO_ROOT/includes/c-relay/build/c_relay_x86" \
"$REPO_ROOT/includes/c-relay/c-relay" ; do
if [[ -x "$candidate" ]]; then CRELAY_SRC="$candidate"; break; fi
done
if [[ -z "$CRELAY_SRC" ]]; then
echo "[build.sh] ERROR: no c-relay binary found. Looked for:" >&2
echo " includes/c-relay/c_relay_x86" >&2
echo " includes/c-relay/build/c_relay_x86" >&2
echo " includes/c-relay/c-relay" >&2
exit 1
fi
cp "$CRELAY_SRC" "$ARTIFACTS/c_relay_x86"
chmod 0755 "$ARTIFACTS/c_relay_x86"
echo "[build.sh] staged c-relay from $CRELAY_SRC"
# 2. fips: build the .deb (requires cargo-deb)
if ! command -v cargo-deb >/dev/null 2>&1; then
echo "[build.sh] ERROR: cargo-deb not installed. Run: cargo install cargo-deb" >&2
exit 1
fi
pushd "$REPO_ROOT/includes/fips" >/dev/null
packaging/debian/build-deb.sh
popd >/dev/null
FIPS_DEB=$(ls "$REPO_ROOT/includes/fips/deploy"/fips_*_amd64.deb | sort | tail -1)
if [[ -z "$FIPS_DEB" || ! -f "$FIPS_DEB" ]]; then
echo "[build.sh] ERROR: fips .deb build produced no artifact" >&2
exit 1
fi
cp "$FIPS_DEB" "$ARTIFACTS/"
echo "[build.sh] staged fips .deb: $(basename "$FIPS_DEB")"
4.8 Updated package list — base.list.chroot
Add runtime deps needed by fips (already pulled in transitively by the .deb but explicit is safer) and by the smoke test:
nginx-light
spawn-fcgi
libfcgi-bin
ca-certificates
openssl
curl
jq
vim
htop
# Slice B/C additions:
libdbus-1-3
iproute2
nftables
4.9 Updated 0020-enable-services.hook.chroot
#!/bin/sh
set -e
# Nginx
rm -f /etc/nginx/sites-enabled/default
ln -sf /etc/nginx/sites-available/n-os-tr.conf /etc/nginx/sites-enabled/n-os-tr.conf
systemctl enable nginx.service
# Slice A
systemctl enable ginxsom.service
systemctl enable n-os-tr-firstboot.service
# Slice B (fips) — units installed by the .deb postinst already enable
# them, but we're explicit for idempotence:
systemctl enable fips.service || true
systemctl enable fips-dns.service || true
# Slice C (c-relay)
systemctl enable c-relay.service
4.10 Updated smoke test
Replace the fips and c-relay SKIP blocks in n-os-tr-smoketest with real checks:
# -------------------- fips mesh daemon -----------------------------
section "fips mesh daemon"
check "fips.service active" systemctl is-active fips.service
check "fips-dns.service active" systemctl is-active fips-dns.service
check "fips0 interface present" ip link show fips0
# fipsctl identity should return an npub-shaped string
npub=$(fipsctl identity 2>/dev/null | head -1 | tr -d '[:space:]')
case "$npub" in
npub1*) pass "fipsctl identity returns npub" "${npub:0:20}..." ;;
*) fail "fipsctl identity returns npub" "got: ${npub:-<empty>}" ;;
esac
# fips UDP transport should be listening
check "fips UDP bound on :2121" bash -c 'ss -ulnp 2>/dev/null | grep -q ":2121"'
# -------------------- c-relay nostr relay --------------------------
section "c-relay nostr relay"
check "c-relay.service active" systemctl is-active c-relay.service
check "c-relay listening on :8888" bash -c 'ss -tlnp 2>/dev/null | grep -q ":8888"'
# The admin nsec should have been logged during first startup
if journalctl -u c-relay.service --no-pager 2>/dev/null | \
grep -q "Admin Private Key:"; then
pass "admin nsec logged in journal" "found"
else
fail "admin nsec logged in journal" "grep miss"
fi
# wss end-to-end via nginx, using the shipped nak:
if timeout 10 nak req --relay wss://localhost/relay -k 1 -l 1 \
>/dev/null 2>&1; then
pass "wss://localhost/relay answers REQ" "ok"
else
fail "wss://localhost/relay answers REQ" "timeout or error"
fi
# NIP-11 relay info doc
nip11=$(curl -sk -H 'Accept: application/nostr+json' \
https://localhost/relay 2>/dev/null)
if echo "$nip11" | jq -e '.name' >/dev/null 2>&1; then
pass "NIP-11 info doc reachable" "name=$(echo "$nip11" | jq -r .name)"
else
fail "NIP-11 info doc reachable" "no JSON .name"
fi
# c-relay embedded admin UI via nginx
status=$(curl -sk -o /dev/null -w '%{http_code}' https://localhost/admin/ 2>/dev/null)
case "$status" in
200|302|401) pass "admin UI reachable via nginx" "HTTP $status" ;;
*) fail "admin UI reachable via nginx" "HTTP $status" ;;
esac
Target final summary: ~15 PASS / 0 FAIL / 0 SKIP.
4.11 MOTD and README updates
The n-os-tr-firstboot script's MOTD block gains additional hints:
n-OS-tr — Nostr-addressed mesh node (preview)
Ginxsom (Blossom) server pubkey (hex):
$GINXSOM_SERVER_PUBKEY
retrieve nsec: cat /var/lib/n-os-tr/keys/ginxsom.nsec
c-relay Nostr relay:
wss://$(hostname)/relay (admin nsec: journalctl -u c-relay | grep 'Admin Private Key')
https://$(hostname)/admin/ (web admin UI)
fips mesh daemon:
fipsctl identity (show npub)
fipsctl peers (list peers)
Quick health check: n-os-tr-smoketest
The iso/config/includes.chroot/usr/share/doc/n-os-tr/README gets corresponding additions.
5. Build & Deploy Sequence
- Place c-relay binary at
includes/c-relay/c_relay_x86(or one of the fallback pathsbuild.shchecks). Ensure it'schmod +xand runs standalone. - Install
cargo-debon the build host:cargo install cargo-deb. - Edit all files listed in §3 according to §4.
- Move artifacts staging location:
- New directory:
iso/config/includes.chroot_before_packages/live-artifacts/— gitignored. build.shwrites c-relay binary and fips .deb here.0010-fetch-artifacts.hook.chrootreads from/live-artifacts/inside the chroot (live-build copies theincludes.chroot_before_packagestree into the chroot root before packages install).
- New directory:
- Add
iso/config/includes.chroot_before_packages/live-artifacts/to.gitignore. - Full clean build:
sudo ./build.sh --clean(needed because package list changed). - Burn the resulting
iso/live-image-amd64.hybrid.isoto USB withdd. - Boot on the B650I machine.
- Verify: run
n-os-tr-smoketest— expect all checks to PASS.
6. Open Questions / Known Conflicts
6.1 nginx /admin/ path collision
Slice A's n-os-tr.conf:53
routes /admin/ to ginxsom. Slice C wants /admin/ for c-relay.
Resolution proposed: change Slice A's Blossom admin to /blossom/ (if
ginxsom supports path rewriting) or /blossom-admin/. Need to check
ginxsom's source to see whether its admin endpoints are hardcoded to /admin/
or whether the FastCGI layer can remap them.
6.2 Fips ethernet auto-interface selection
If the B650I's Ethernet shows up as enp5s0 or similar and fips's
"auto-pick first non-loopback" heuristic grabs the wrong interface (e.g. Wi-Fi
— though we explicitly said runtime Wi-Fi is fine, we don't want fips
scanning it), we may need to hardcode ethernet.interface: "enp5s0" in
fips.yaml. Resolution:
check ip link show on first boot; update if needed.
6.3 Stray file =4 in includes/c-relay/
Shown in the directory listing but not the c-relay binary (the real binary
is includes/c_relay_static_x86_64
at the top level of includes/). Likely a shell-redirect typo artifact
(command >=4 file or similar). Safe to delete during cleanup; does not
affect the build.
6.4 c-relay writable database location
c-relay writes .nrdb files to its WorkingDirectory (/opt/c-relay/). In
a live session with ephemeral rootfs this works — the writes go to the
tmpfs union layer. For persistence-partition boots we'd want /opt/c-relay/
on the persistence mount. Not addressed in this slice per decision #10.
6.5 fips running as root
The fips Debian package runs fips as root (needs TUN + raw sockets). The
hardening in fips.service
is meaningful but fips itself is privileged. Acceptable for this slice.
6.6 Reverse proxy's X-Forwarded-Proto and c-relay's NIP-42
NIP-42 requires the relay to know its own URL (for the ["relay", "url"] tag
in the AUTH challenge). c-relay has logic
that falls back to ws://127.0.0.1:PORT — this means NIP-42 challenges will
reference the internal address, not wss://host/relay. Clients may then
fail auth. Mitigation: c-relay has a configurable relay_url config
key (set via admin event). Post-boot procedure documented in updated README
for users who want NIP-42 to work correctly. Not blocking for basic
operation — the relay accepts unauthenticated connections by default.
7. Success Criteria
From a booted USB on fresh hardware with wired Ethernet:
systemctl status fips-dns ginxsom c-relay nginx n-os-tr-firstboot— all activefipsctl identity— prints a valid npubfipsctl peers— at minimum listsfips-test-node(may show as "connecting" if UDP blocked)ip link show fips0— fips0 TUN interface upjournalctl -u c-relay | grep 'Admin Private Key'— returns the nsec (once)curl -k https://localhost/— landing pagecurl -k -I https://localhost/admin/— returns 200 or 302 (c-relay UI)nak req --relay wss://localhost/relay -k 1 -l 1— returns["EOSE",...]after an empty resultcurl -ksI https://localhost/0000000000000000000000000000000000000000000000000000000000000000— 404 (ginxsom still works)n-os-tr-smoketest—15 PASS / 0 FAIL / 0 SKIP
8. Rollback
If something goes sideways during development:
- The entire Slice A → Slice B+C diff is confined to these files/directories:
build.sh (additive step) iso/config/hooks/live/0010-fetch-artifacts.hook.chroot (new) iso/config/hooks/live/0020-enable-services.hook.chroot (edited) iso/config/package-lists/base.list.chroot (edited) iso/config/includes.chroot/etc/fips/ (new dir) iso/config/includes.chroot/etc/systemd/system/c-relay.service (new) iso/config/includes.chroot/etc/nginx/sites-available/n-os-tr.conf (edited) iso/config/includes.chroot/usr/local/sbin/n-os-tr-firstboot (edited motd) iso/config/includes.chroot/usr/local/bin/n-os-tr-smoketest (edited) iso/config/includes.chroot/usr/share/doc/n-os-tr/README (edited) iso/config/includes.chroot_before_packages/ (new, gitignored) .gitignore (edited) - A revert is a
git checkoutof those paths plus removal ofiso/config/includes.chroot_before_packages/.
9. Out of Scope (deferred to later slices)
- Persistent identity (ginxsom nsec, c-relay admin nsec, fips npub survive reboots).
- Gitea release fetch for artifacts (current plan is local-only).
- c-relay
relay_urlauto-configuration for NIP-42 (manual admin event for now). /admin/conflict resolution if ginxsom truly hardcodes that path.- fips-gateway service (disabled; users can enable manually for LAN translation).
- Tor transport for fips (transport is available but not wired into the config).
- Installer variant (live-only for now).
- arm64 build.
- Signed / reproducible builds.
- Hardening tests: SELinux, AppArmor profiles.
10. References
plans/iso_architecture.md— overall target designplans/network_boot.md— sibling plan, pausedbuild.sh/lb-wrapper.sh— build entryiso/auto/config— live-build optionsincludes/fips/packaging/debian/build-deb.shincludes/fips/packaging/common/fips.yamlincludes/fips/packaging/debian/fips.serviceincludes/c-relay/systemd/c-relay.serviceincludes/c-relay/README.mdincludes/c-relay/API.md- Live-build manual — includes.chroot_before_packages