Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
713ce16
Add 2009-style firstboot whiptail wrapper
Deadbytes101 Jul 8, 2026
13220fc
Wire firstboot console theme
Deadbytes101 Jul 8, 2026
bf9890c
Install firstboot theme wrapper as executable
Deadbytes101 Jul 8, 2026
44a8b68
Add firstboot console theme wiring tests
Deadbytes101 Jul 8, 2026
7030f3b
Harden firstboot theme backend execution
Deadbytes101 Jul 9, 2026
47f10f2
Update theme tests for backend hardening
Deadbytes101 Jul 9, 2026
b98e9e5
Add behavioral firstboot theme wrapper test
Deadbytes101 Jul 9, 2026
2dc0b51
Add local firstboot theme preview harness
Deadbytes101 Jul 9, 2026
3b868af
Add authoritative Linux source gate workflow
Deadbytes101 Jul 9, 2026
6bc5f60
Expand firstboot theme preview modes
Deadbytes101 Jul 9, 2026
1752ab0
Add read-only firstboot theme preview contracts
Deadbytes101 Jul 9, 2026
490d139
Document firstboot console theme contract
Deadbytes101 Jul 9, 2026
777b48e
Enforce LF for firstboot runtime scripts
Deadbytes101 Jul 9, 2026
6394d1a
Format firstboot theme tests
Deadbytes101 Jul 9, 2026
5359482
Lock firstboot wrapper LF contract in tests
Deadbytes101 Jul 9, 2026
8f9c3c7
Remove synthetic separators from firstboot theme
Deadbytes101 Jul 9, 2026
ba758be
Use plain setup utility backtitle
Deadbytes101 Jul 9, 2026
aa5b548
Make firstboot preview read like a real setup utility
Deadbytes101 Jul 9, 2026
6aa4fb0
Format theme tests and ban slash separators
Deadbytes101 Jul 9, 2026
b3900e2
Ban slash separators from theme previews
Deadbytes101 Jul 9, 2026
f2660f6
Match firstboot theme tests to rustfmt output
Deadbytes101 Jul 9, 2026
951b950
Move firstboot wrapper behavior out of Rust crate tests
Deadbytes101 Jul 9, 2026
2524971
Add shell behavioral verification for firstboot theme wrapper
Deadbytes101 Jul 9, 2026
e9f1bbe
Run firstboot wrapper behavior in authoritative WSL gate
Deadbytes101 Jul 9, 2026
fdce587
Lock wrapper behavior verification into WSL authority
Deadbytes101 Jul 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ build/usb/hooks/* text eol=lf
build/usb/package-lists/rigos.list.chroot text eol=lf
build/usb/includes.chroot/usr/local/bin/* text eol=lf
build/usb/includes.chroot/usr/local/sbin/rigos-* text eol=lf
build/usb/includes.chroot/usr/lib/rigos/rigos-firstboot-* text eol=lf
build/usb/includes.chroot/usr/lib/rigos/rigos-randomx-msr text eol=lf
build/usb/includes.chroot/usr/lib/rigos/rigos-runtime-* text eol=lf
build/usb/includes.chroot/usr/lib/rigos/rigos-miner-* text eol=lf
Expand Down
60 changes: 60 additions & 0 deletions .github/workflows/source-gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: RIGOS Source Gate

on:
pull_request:
branches:
- performance/randomx-sustained-hash
- stability/hive-exit-gates
workflow_dispatch:

permissions:
contents: read

concurrency:
group: source-gate-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
verify:
name: Authoritative Linux source verification
runs-on: ubuntu-24.04
timeout-minutes: 45

steps:
- name: Check out exact pull-request head
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install required host tools
run: |
set -euo pipefail
sudo apt-get update
sudo apt-get install --yes --no-install-recommends ripgrep

- name: Install locked Rust toolchain
run: |
set -euo pipefail
rustup toolchain install 1.85.1 \
--profile minimal \
--component rustfmt \
--component clippy
rustup override set 1.85.1
rustc --version
cargo --version
cargo fmt --version
cargo clippy --version

- name: Run authoritative RIGOS source gate
env:
CARGO_TERM_COLOR: always
run: |
set -euo pipefail
bash ./scripts/verify-wsl-entrypoint.sh "$GITHUB_WORKSPACE"

- name: Record exact verified revision
if: always()
run: |
set -euo pipefail
printf 'RIGOS_VERIFIED_HEAD=%s\n' "$(git rev-parse HEAD)"
git status --short
2 changes: 1 addition & 1 deletion build/usb/hooks/010-rigos.chroot
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ install -d -m 0755 /usr/lib/rigos /usr/local/bin
systemd-tmpfiles --create /usr/lib/tmpfiles.d/rigos.conf

rm -f /etc/ssh/ssh_host_*_key /etc/ssh/ssh_host_*_key.pub
chmod 0755 /usr/local/bin/rigosd /usr/local/bin/rigosctl /usr/local/sbin/rigos-firstboot /usr/local/sbin/rigos-recovery-access /usr/local/sbin/rigos-state-orchestrate /usr/lib/rigos/rigos-miner-gate /usr/lib/rigos/rigos-miner-health /usr/lib/rigos/rigos-runtime-render /usr/lib/rigos/rigos-runtime-publish /usr/lib/rigos/rigos-runtime-gate /usr/lib/rigos/rigos-randomx-msr /usr/lib/rigos/rigos-ssh-hostkeys /usr/lib/rigos/rigos-state-init /usr/lib/rigos/rigos-state-ready /usr/lib/rigos/rigos-config /usr/lib/rigos/rigos-performance /usr/lib/rigos/rigos-lifecycle-cycles /usr/lib/rigos/rigos-identity-seed /usr/lib/rigos/xmrig
chmod 0755 /usr/local/bin/rigosd /usr/local/bin/rigosctl /usr/local/sbin/rigos-firstboot /usr/local/sbin/rigos-recovery-access /usr/local/sbin/rigos-state-orchestrate /usr/lib/rigos/rigos-firstboot-whiptail /usr/lib/rigos/rigos-miner-gate /usr/lib/rigos/rigos-miner-health /usr/lib/rigos/rigos-runtime-render /usr/lib/rigos/rigos-runtime-publish /usr/lib/rigos/rigos-runtime-gate /usr/lib/rigos/rigos-randomx-msr /usr/lib/rigos/rigos-ssh-hostkeys /usr/lib/rigos/rigos-state-init /usr/lib/rigos/rigos-state-ready /usr/lib/rigos/rigos-config /usr/lib/rigos/rigos-performance /usr/lib/rigos/rigos-lifecycle-cycles /usr/lib/rigos/rigos-identity-seed /usr/lib/rigos/xmrig
systemctl enable NetworkManager.service ssh.service rigos-state.service rigos-recovery-access.service rigos-state-ready.service rigos-ssh-hostkeys.service rigos-profile-apply.service rigos-runtime-render.service rigos-hugepages.service rigos-firstboot.service rigos-randomx-msr.service rigos-miner.service rigos-miner-health.timer tmp.mount
systemctl disable ssh.socket 2>/dev/null || true
systemctl disable apt-daily.timer apt-daily-upgrade.timer logrotate.timer fstrim.timer 2>/dev/null || true
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[Service]
Environment=RIGOS_WHIPTAIL=/usr/lib/rigos/rigos-firstboot-whiptail
Environment="RIGOS_FIRSTBOOT_BACKTITLE=RIGOS SETUP UTILITY LOCAL NODE CONFIGURATION"
35 changes: 35 additions & 0 deletions build/usb/includes.chroot/usr/lib/rigos/rigos-firstboot-whiptail
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/sh
# RIGOS firstboot presentation wrapper.
# Keeps the configuration engine and dialog return-code contract unchanged.
set -eu

TERM=${TERM:-linux}
export TERM

NEWT_COLORS=${NEWT_COLORS:-'root=white,blue:border=blue,lightgray:window=black,lightgray:shadow=black,black:title=white,blue:button=black,lightgray:actbutton=white,blue:compactbutton=black,lightgray:checkbox=black,lightgray:actcheckbox=white,blue:entry=black,white:disentry=gray,lightgray:label=black,lightgray:listbox=black,lightgray:actlistbox=white,blue:sellistbox=black,cyan:actsellistbox=white,blue:textbox=black,lightgray:acttextbox=white,blue:helpline=white,blue:roottext=white,blue'}
export NEWT_COLORS

backtitle=${RIGOS_FIRSTBOOT_BACKTITLE:-'RIGOS SETUP UTILITY LOCAL NODE CONFIGURATION'}
whiptail_real=${RIGOS_WHIPTAIL_REAL:-/usr/bin/whiptail}

if [ ! -x "$whiptail_real" ]; then
echo "rigos-firstboot-whiptail: backend is not executable: $whiptail_real" >&2
exit 127
fi

case " $* " in
*' --menu '*)
set -- --ok-button SELECT --cancel-button BACK "$@"
;;
*' --yesno '*)
set -- --yes-button APPLY --no-button BACK "$@"
;;
*' --inputbox '*|*' --passwordbox '*)
set -- --ok-button NEXT --cancel-button BACK "$@"
;;
*' --msgbox '*)
set -- --ok-button CONTINUE "$@"
;;
esac

exec "$whiptail_real" --backtitle "$backtitle" "$@"
93 changes: 93 additions & 0 deletions crates/rigos-config/tests/firstboot_theme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use std::fs;
use std::path::PathBuf;

const WRAPPER_PATH: &str = "build/usb/includes.chroot/usr/lib/rigos/rigos-firstboot-whiptail";

fn repo_path(path: &str) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join(path)
}

fn repo_file(path: &str) -> String {
let path = repo_path(path);
fs::read_to_string(&path)
.unwrap_or_else(|error| panic!("failed to read {}: {error}", path.display()))
}

#[test]
fn firstboot_uses_the_dedicated_console_theme_wrapper() {
let drop_in = repo_file(
"build/usb/includes.chroot/etc/systemd/system/rigos-firstboot.service.d/2009-console-theme.conf",
);

assert!(
drop_in.contains("Environment=RIGOS_WHIPTAIL=/usr/lib/rigos/rigos-firstboot-whiptail"),
"firstboot must select the dedicated presentation wrapper"
);
assert!(
drop_in.contains("RIGOS SETUP UTILITY LOCAL NODE CONFIGURATION"),
"firstboot must publish the static non-secret backtitle"
);
assert!(
!drop_in.contains("//"),
"setup utility titles must not use synthetic slash separators"
);
}

#[test]
fn firstboot_wrapper_is_pinned_to_lf_in_git() {
let attributes = repo_file(".gitattributes");
let required = "build/usb/includes.chroot/usr/lib/rigos/rigos-firstboot-* text eol=lf";

assert!(
attributes.lines().any(|line| line == required),
"firstboot runtime wrappers must remain LF on Windows and WSL checkouts"
);
}

#[test]
fn firstboot_theme_is_ascii_and_preserves_whiptail_as_the_ui_engine() {
let wrapper = repo_file(WRAPPER_PATH);

assert!(wrapper.is_ascii(), "console theme must remain ASCII-only");
assert!(wrapper.contains("NEWT_COLORS="));
assert!(wrapper.contains("root=white,blue"));
assert!(wrapper.contains("window=black,lightgray"));
assert!(wrapper.contains("actlistbox=white,blue"));
assert!(wrapper.contains("--backtitle"));
assert!(wrapper.contains("--ok-button SELECT --cancel-button BACK"));
assert!(wrapper.contains("--yes-button APPLY --no-button BACK"));
assert!(wrapper.contains("RIGOS_WHIPTAIL_REAL:-/usr/bin/whiptail"));
assert!(wrapper.contains("exec \"$whiptail_real\""));
assert!(wrapper.contains("backend is not executable"));
assert!(!wrapper.contains("//"));
assert!(
!wrapper.contains("xterm")
&& !wrapper.contains("Xorg")
&& !wrapper.contains("wayland")
&& !wrapper.contains("electron"),
"theme must not introduce a graphical runtime"
);
}

#[test]
fn authoritative_wsl_gate_runs_the_wrapper_behavior_test() {
let entrypoint = repo_file("scripts/verify-wsl-entrypoint.sh");
let verifier = repo_file("scripts/verify-firstboot-theme-wrapper.sh");

assert!(entrypoint.contains("bash ./scripts/verify-firstboot-theme-wrapper.sh"));
assert!(verifier.contains("RIGOS firstboot theme wrapper verification passed"));
assert!(verifier.contains("RIGOS_THEME_EXIT=7"));
assert!(verifier.contains("missing-backend"));
}

#[test]
fn image_hook_installs_the_theme_wrapper_as_executable() {
let hook = repo_file("build/usb/hooks/010-rigos.chroot");

assert!(
hook.contains("/usr/lib/rigos/rigos-firstboot-whiptail"),
"image construction must install the wrapper as executable"
);
}
65 changes: 65 additions & 0 deletions crates/rigos-config/tests/firstboot_theme_preview.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::fs;
use std::path::PathBuf;

fn preview_script() -> String {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("../..")
.join("scripts/preview-firstboot-theme.sh");
fs::read_to_string(&path)
.unwrap_or_else(|error| panic!("failed to read {}: {error}", path.display()))
}

#[test]
fn preview_covers_every_firstboot_dialog_class() {
let script = preview_script();

for required in [
"preview_menu",
"preview_input",
"preview_confirm",
"preview_message",
"menu|input|confirm|message|all",
] {
assert!(
script.contains(required),
"preview harness is missing required mode marker: {required}"
);
}

for required in ["--menu", "--inputbox", "--yesno", "--msgbox"] {
assert!(
script.contains(required),
"preview harness is missing dialog class: {required}"
);
}

assert!(
!script.contains("//"),
"preview titles must not use synthetic slash separators"
);
}

#[test]
fn preview_is_read_only_and_does_not_touch_appliance_state() {
let script = preview_script();

for forbidden in [
"/var/lib/rigos",
"systemctl",
"rigos-config",
"rigos-miner",
"rigos-randomx-msr",
"mount ",
"umount ",
"rm -rf",
"sudo ",
] {
assert!(
!script.contains(forbidden),
"preview harness contains forbidden mutation surface: {forbidden}"
);
}

assert!(script.contains("RIGOS_WHIPTAIL_REAL=/usr/bin/whiptail"));
assert!(script.contains("RIGOS_THEME_PREVIEW_EXIT="));
}
93 changes: 93 additions & 0 deletions docs/developer/firstboot-theme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
RIGOS FIRSTBOOT CONSOLE THEME
=============================

PURPOSE
-------

Give the local first-boot selector the look of a late-2000s or early-2010s
firmware utility without adding a graphical desktop, browser, display server,
or background daemon.

The theme is presentation only. Configuration, identity, persistent state,
miner, MSR, SSH, runtime publication, and activation behavior stay unchanged.

VISUAL CONTRACT
---------------

Root background deep blue
Dialog window light gray / silver
Window border blue
Active row white on blue
Input field black on white
Shadow black
Backtitle static ASCII, no private values
Buttons SELECT BACK NEXT APPLY CONTINUE

The source remains ASCII-only so it renders on the Linux console without a
Unicode-font dependency.

ARCHITECTURE
------------

Firstboot still executes the Python workflow at:

/usr/local/sbin/rigos-firstboot

The service sets RIGOS_WHIPTAIL to:

/usr/lib/rigos/rigos-firstboot-whiptail

The wrapper exports NEWT_COLORS, adds a static backtitle, maps button labels,
and execs the existing /usr/bin/whiptail backend. Backend exit status and
selected values retain the original whiptail contract.

PREVIEW
-------

Run from a Linux or WSL checkout with whiptail installed:

bash scripts/preview-firstboot-theme.sh menu
bash scripts/preview-firstboot-theme.sh input
bash scripts/preview-firstboot-theme.sh confirm
bash scripts/preview-firstboot-theme.sh message
bash scripts/preview-firstboot-theme.sh all

The preview harness does not read or modify /var/lib/rigos and does not call
systemctl, the configuration engine, miner services, or MSR authority.

VERIFICATION
------------

Targeted tests:

cargo test --locked -p rigos-config --test firstboot_theme
cargo test --locked -p rigos-config --test firstboot_theme_preview

Authoritative Linux source gate:

bash scripts/verify-wsl-entrypoint.sh "$PWD"

A PASS may only be claimed for the exact Git head printed by the gate.

BRANCH BOUNDARY
---------------

UI work belongs on:

ui/firstboot-2009-theme

It is stacked on performance/randomx-sustained-hash only for review. Do not
merge it into PR #15 while the physical performance and endurance evidence is
still tied to the exact performance head.

NON-GOALS
---------

No X11.
No Wayland.
No Electron.
No browser UI.
No framebuffer daemon.
No persistent-state format change.
No miner behavior change.
No image-release claim before source and image verification pass.
Loading