diff --git a/AGENTS.md b/AGENTS.md index e8cf6a2..790bdfd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,218 +1,216 @@ - 1|# Clawdie ISO Agent Guidelines - 2| - 3|## Agent Identity and Current Role Split - 4| - 5|The XFCE operator USB work now uses a git-coordinated split. Agents may review - 6|or suggest across boundaries, but should not silently take over another role's - 7|load-bearing responsibility. - 8| - 9|| Role name | Identity | Owns | Restrictions | - 10|| ---------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | - 11|| **Pi ISO Developer** | Pi harness (this dev agent) | Source changes, docs, static checks, commits, pushes | Does not start ISO builds or flash media unless explicitly assigned | - 12|| **Codex ISO Builder** | codex pkg on the FreeBSD 15 build host | `./build.sh`, mounted-image inspection, publishing, hardware validation | Should avoid broad source refactors; reports exact logs/output back through git or handoff notes | - 13|| **Hermes USB/IMG Deployer** | Hermes on Debian/Linux | Downloading verified published artifacts, USB target identification, flashing | Does not need Codeberg (mirror only); pushes to Forgejo exclusively | - 14|| **Claude Reviewer / XFCE Tweaker** | Claude (Linux) | Review/plans plus Track E XFCE GUI polish | Cannot build ISO, cannot run FreeBSD-only validation, should mark speculative runtime claims as such | - 15|| **Opencode / Z.ai Integrator** | Opencode CLI on Linux | Linux-side Herdr/dashboard experiments plus Pi/DeepSeek v4 provider-lane smoke wiring | Cannot claim FreeBSD runtime proof; uses Sam-provided API keys only for provider validation | - 16|| **Operator (Sam)** | Human operator | Product, hardware, acceptance, release judgment | Human approval required for release/tagging decisions | - 17| - 18|### Git Coordination Rules - 19| - 20|- Coordinate through git: fetch before commenting on remote state, push small - 21| reviewable commits, and include test/build status in commit messages. - 22|- Claude may push critique/suggestion commits, but Pi ISO Developer should - 23| re-check and adjust implementation details before the next build target is - 24| treated as final. - 25|- Codex ISO Builder consumes pushed build targets, builds/publishes artifacts, - 26| and reports hardware findings with exact commands and output. - 27|- Hermes USB/IMG Deployer consumes published artifact URLs/manifests, verifies - 28| checksums on Linux, identifies the USB target, and owns the final image-to-USB - 29| deployment handoff. - 30|- Opencode / Z.ai Integrator owns Linux-side Herdr/dashboard experiments and - 31| the Pi/DeepSeek v4 smoke lane when Sam provides a `ZAI_API_KEY`; findings - 32| should come back as exact commands, output, provider/version notes, and small - 33| manifests/summaries that Colibri can ingest. - 34|- If a change needs a long ISO build, USB flash, or real hardware proof, hand it - 35| to the owning role instead of running it opportunistically. - 36| - 37|### Markdown Formatting Gate - 38| - 39|Markdown formatting is tool-owned, not taste-owned. Before pushing any commit - 40|that edits `*.md`, run: - 41| - 42|```sh - 43|./scripts/check-format.sh - 44|``` - 45| - 46|If it fails, format only the touched markdown files, then rerun the check: - 47| - 48|```sh - 49|npx --yes prettier@3 --write path/to/file.md - 50|``` - 51| - 52|Do not hand-align Markdown tables or reflow prose manually. `.prettierrc` uses - 53|`proseWrap: preserve` so existing prose line breaks stay intentional, while - 54|Prettier still catches table padding, list spacing, and emphasis drift. - 55| - 56|### Private Planning Workspace - 57| - 58|`private/` is gitignored and may contain operator-private strategy notes or PRDs. - 59|Agents on this host may read files there only when directly relevant to the - 60|assigned work. Do not commit, quote, summarize publicly, or copy private content - 61|to Forgejo unless the operator explicitly approves it. - 62| - 63|If working on custom ISO / hardware-report monetization, check - 64|`private/PRD-CUSTOM-ISO.md` when present. Codex ISO Builder should focus first - 65|on the local-only `hw-report` feasibility path and, after analysis, - 66|return concise action notes for Claude Reviewer / XFCE Tweaker on what GUI - 67|surface should expose for report collection and review. - 68| - 69|### Linux Agent Constraints - 70| - 71|Linux agents MUST NOT attempt to build the ISO (`./build.sh`, `./build-vps.sh`). - 72|ISO builds require FreeBSD 15 system tools (`mdconfig`, `mount_msdosfs`, `pkg`). - 73|Instead, guide Codex ISO Builder with exact commands to run on the FreeBSD 15 - 74|system. - 75| - 76|Agents on any platform MUST NOT start a new ISO build unless explicitly assigned. - 77|Builds are long-running, mutate repo-local caches, and can leave mounted md(4) - 78|devices that require cleanup. - 79| - 80|### Colibri Dependency - 81| - 82|The ISO build stages FreeBSD-native Colibri control-plane artifacts from the - 83|adjacent `../colibri` checkout (`FEATURE_COLIBRI=YES` is the default lane). The - 84|staging is wired into `build.sh` and `scripts/stage-colibri-iso.sh`; the ISO - 85|does **not** build Rust while the image is mounted. - 86| - 87|- Build Colibri release artifacts on the FreeBSD/OSA host, not on Debian/Linux. - 88|- Build order, binary verification, and cleanup timing live in the `iso-build` - 89| skill (§Colibri artifact preflight). - 90|- Staging layout (installed paths, rc.d, directory ownership) is owned by - 91| Colibri `docs/ISO-INTEGRATION-PLAN.md`. - 92|- Required by ISO preflight: `colibri-daemon`, `colibri`, `colibri-smoke-agent`. - 93| `colibri-tui` is optional in staging code but desired for this USB target and - 94| should be verified alongside the other three. - 95| - 96|**Invariant:** do not `cargo clean` the Colibri checkout until the ISO - 97|preflight/build has consumed `../colibri/target/release`. - 98| - 99|--- - 100| - 101|## Current XFCE Operator USB Baseline - 102| - 103|The active branch target is the XFCE live operator USB. Authoritative state - 104|lives in `packages/` (what ships) and `PLAN-OPERATOR-USB-NEXT.md` (round-scope - 105|decisions and any "for now" retention notes). Final graphical validation - 106|requires real hardware — do not treat bhyve, nested VMs, or static image - 107|inspection as final proof that SDDM/XFCE works. - 108| - 109|--- - 110| - 111|## System Configuration - 112| - 113|**Privilege model:** distinguish build-host administration from live-USB runtime. - 114| - 115|- On the FreeBSD 15 build host, operator-facing commands may use `sudo`. - 116|- Inside the live USB, `sudo` is intentionally absent (deleted via `pkg delete -f sudo`). - 117|- Live privileged actions use FreeBSD `mac_do` via `mdo -u root `. - 118|- `~/.bashrc` aliases `sudo` → `mdo -u root` for muscle-memory compatibility. - 119| The shell function wraps `mdo` with a fire-and-forget ZFS snapshot - 120| (`zroot@cli-`) before each privileged invocation, so rollback - 121| is always available without confirmation prompts or warning popups. - 122|- Agent runtime code must not shell out to `sudo` for privileged host changes. - 123|- Privileged Clawdie-AI host operations go through the hostd RPC layer. - 124| - 125|**Why `sudo` as alias, not as pkg:** - 126| - 127|| Approach | Install sudo pkg | Alias to mdo | - 128|| ------------------- | ------------------------ | ---------------------------- | - 129|| Extra package | Yes (sudo + deps) | No | - 130|| Two privilege paths | `sudo` AND `mdo` coexist | Single path (`mdo`) | - 131|| Audit surface | Two tools to audit | One kernel-enforced MAC | - 132|| ZFS safety net | Requires sudoers hooks | Built into bash function | - 133|| Agent confusion | Agents try both paths | Agents use `sudo`, get `mdo` | - 134|| ISO size | Larger | Zero bytes | - 135| - 136|The alias approach keeps the ISO lean, eliminates dual-privilege-path - 137|confusion, and bakes ZFS rollback safety directly into the operator shell. - 138|`mac_do` is FreeBSD base system — no package dependency, kernel-enforced, - 139|auditable via MAC framework. - 140| - 141|--- - 142| - 143|## Installer Temp Files - 144| - 145|The GUI installer uses `/tmp/clawdie-install.conf` to pass wizard values to - 146|`firstboot.sh`. This is an exemption from the project-local `tmp/` rule. - 147| - 148|**Rationale:** - 149| - 150|- Live ISO has no project root - 151|- Single-user install phase (no other users on the system) - 152|- File is consumed once by `firstboot.sh` then deleted on reboot - 153|- PF firewall is not yet running during install - 154| - 155|**Applies to:** - 156| - 157|- `/tmp/clawdie-install.conf` — GUI wizard config output - 158|- `/tmp/clawdie-firstboot.*` — firstboot progress and log (written by rc.d) - 159| - 160|## Repo-local ISO Build Workspace - 161| - 162|ISO builds use repo-local `tmp/` for large caches and output artifacts: - 163| - 164|- `tmp/cache` — build cache - 165|- `tmp/cache/mnt` — temporary md(4) work-image mountpoint - 166|- `tmp/output` — generated `.img.gz` artifacts and checksums - 167|- `tmp/packages` — fetched package archives - 168| - 169|`tmp/cache/mnt` is an ISO-builder-specific mountpoint exception. Do not mount - 170|unrelated datasets, recovery filesystems, or scratch filesystems elsewhere under - 171|repo `tmp/`. If a build is interrupted, use the `iso-build-cleanup` skill before - 172|retrying. - 173| - 174|--- - 175| - 176|## Cross-Repo Coordination - 177| - 178|Clawdie spans three repos. Changes often require coordinated updates. - 179| - | Repo | Purpose | Remote | - | ------------- | ---------------------------------------- | -------------------------------------------------- | - | `clawdie-ai` | Agent runtime, control plane, channels | `git@code.smilepowered.org:clawdie/clawdie-ai.git` | - | `clawdie-iso` | ISO builder, firstboot wizard, installer | `git@code.smilepowered.org:clawdie/clawdie-iso.git`| - | `Colibri` | Cross-platform Rust control plane core | `git@code.smilepowered.org:clawdie/colibri.git` | - 185| - 186|When changes span repos, create a handoff doc in the secondary repo - 187|listing what needs updating. See `Clawdie-AI/AGENTS.md` for full protocol. - 188| - 189|--- - 190| - 191|## Agent Handoff Documents - 192| - 193|Use ephemeral handoff files to transfer context between agents. - 194| - 195|- **Name:** `doc/-HANDOFF.md` or `-HANDOFF.md` (repo root) - 196|- **Lifecycle:** Create when handing off, delete when complete - 197|- **Structure:** Must include task checklist, deletion criteria, results section - 198| - 199|See `Clawdie-AI/AGENTS.md` for the full handoff template and protocol. - 200| - 201|--- - 202| - 203|## Attribution in Commit History - 204| - 205|Use attribution in commit messages, not in code comments. - 206| - 207|Labels: - 208| - 209|- `Sam & Codex` — changes made by Sam and Codex - 210|- `Sam & Claude` — changes made by Sam and Claude - 211|- `C&C` — joint change with equal credit for Claude and Codex - 212| - 213|Add the label to the commit subject or body. Example: - 214| - 215|``` - 216|Fix bhyve preflight checks (C&C) - 217|``` - 218| \ No newline at end of file +# Clawdie ISO Agent Guidelines + +## Agent Identity and Current Role Split + +The XFCE operator USB work now uses a git-coordinated split. Agents may review +or suggest across boundaries, but should not silently take over another role's +load-bearing responsibility. + +| Role name | Identity | Owns | Restrictions | +| ---------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | +| **Pi ISO Developer** | Pi harness (this dev agent) | Source changes, docs, static checks, commits, pushes | Does not start ISO builds or flash media unless explicitly assigned | +| **Codex ISO Builder** | codex pkg on the FreeBSD build host | `./build.sh`, mounted-image inspection, publishing, hardware validation | Should avoid broad source refactors; reports exact logs/output back through git or handoff notes | +| **Hermes USB/IMG Deployer** | Hermes on Debian/Linux | Downloading verified published artifacts, USB target identification, flashing | Does not need git-host access; never flashes unverified artifacts or partition paths | +| **Claude Reviewer / XFCE Tweaker** | Claude (Linux) | Review/plans plus Track E XFCE GUI polish | Cannot build ISO, cannot run FreeBSD-only validation, should mark speculative runtime claims as such | +| **Opencode / Z.ai Integrator** | Opencode CLI on Linux | Linux-side Herdr/dashboard experiments plus Pi/DeepSeek v4 provider-lane smoke wiring | Cannot claim FreeBSD runtime proof; uses Sam-provided API keys only for provider validation | +| **Operator (Sam)** | Human operator | Product, hardware, acceptance, release judgment | Human approval required for release/tagging decisions | + +## Agent / Codebase Check-In Matrix + +Use this as the lightweight "who checks in where" matrix while work spans +multiple repos. Pushed commits, mounted-image reports, manifests, or explicit +handoff docs are the expected check-in surface. + +| Agent lane / identity | Primary codebase(s) | Typical check-in artifact | +| ------------------------------ | ------------------------------------ | -------------------------------------------------------------- | +| **Pi ISO Developer** | `clawdie-iso` | Small pushed commit on active branch plus static-check result | +| **Codex ISO Builder** | `clawdie-iso`, adjacent `../colibri` | Build log, mounted-image sweep, publish manifest, smoke notes | +| **Hermes USB/IMG Deployer** | published ISO artifacts | Checksum/manifest verification plus flash-target confirmation | +| **Claude Reviewer / Tweaker** | `clawdie-iso` | Review/GUI-polish commit or explicit handoff note | +| **Opencode / Z.ai Integrator** | `clawdie-ai`, `colibri` | Provider smoke output, small manifest, or handoff doc | +| **Operator (Sam)** | all three repos | Final acceptance note, branch choice, release/publish approval | + +### Git Coordination Rules + +- Coordinate through git: fetch before commenting on remote state, push small + reviewable commits, and include test/build status in commit messages. +- Claude may push critique/suggestion commits, but Pi ISO Developer should + re-check and adjust implementation details before the next build target is + treated as final. +- Codex ISO Builder consumes pushed build targets, builds/publishes artifacts, + and reports hardware findings with exact commands and output. +- Hermes USB/IMG Deployer consumes published artifact URLs/manifests, verifies + checksums on Linux, identifies the USB target, and owns the final image-to-USB + deployment handoff. +- Opencode / Z.ai Integrator owns Linux-side Herdr/dashboard experiments and + the Pi/DeepSeek v4 smoke lane when Sam provides a `ZAI_API_KEY`; findings + should come back as exact commands, output, provider/version notes, and small + manifests/summaries that Colibri can ingest. +- If a change needs a long ISO build, USB flash, or real hardware proof, hand it + to the owning role instead of running it opportunistically. + +### Markdown Formatting Gate + +Markdown formatting is tool-owned, not taste-owned. Before pushing any commit +that edits `*.md`, run: + +```sh +./scripts/check-format.sh +``` + +If it fails, format only the touched markdown files, then rerun the check: + +```sh +npx --yes prettier@3 --write path/to/file.md +``` + +Do not hand-align Markdown tables or reflow prose manually. `.prettierrc` uses +`proseWrap: preserve` so existing prose line breaks stay intentional, while +Prettier still catches table padding, list spacing, and emphasis drift. + +### Private Planning Workspace + +`private/` is gitignored and may contain operator-private strategy notes or PRDs. +Agents on this host may read files there only when directly relevant to the +assigned work. Do not commit, quote, summarize publicly, or copy private content +to Forgejo unless the operator explicitly approves it. + +If working on custom ISO / hardware-report monetization, check +`private/PRD-CUSTOM-ISO.md` when present. Codex ISO Builder should focus first +on the local-only `hw-report` feasibility path and, after analysis, +return concise action notes for Claude Reviewer / XFCE Tweaker on what GUI +surface should expose for report collection and review. + +### Linux Agent Constraints + +Linux agents MUST NOT attempt to build the ISO (`./build.sh`, `./build-vps.sh`). +ISO builds require FreeBSD system tools (`mdconfig`, `mount_msdosfs`, `pkg`). +Instead, guide Codex ISO Builder with exact commands to run on the FreeBSD +system. + +Agents on any platform MUST NOT start a new ISO build unless explicitly assigned. +Builds are long-running, mutate repo-local caches, and can leave mounted md(4) +devices that require cleanup. + +### Colibri Dependency + +The ISO build stages FreeBSD-native Colibri control-plane artifacts from the +adjacent `../colibri` checkout (`FEATURE_COLIBRI=YES` is the default lane). The +staging is wired into `build.sh` and `scripts/stage-colibri-iso.sh`; the ISO +does **not** build Rust while the image is mounted. + +- Build Colibri release artifacts on the FreeBSD/OSA host, not on Debian/Linux. +- Build order, binary verification, and cleanup timing live in the `iso-build` + skill (§Colibri artifact preflight). +- Staging layout (installed paths, rc.d, directory ownership) is owned by + Colibri `docs/ISO-INTEGRATION-PLAN.md`. +- Required by ISO preflight: `colibri-daemon`, `colibri`, `colibri-smoke-agent`. + `colibri-tui` is optional in staging code but desired for this USB target and + should be verified alongside the other three. + +**Invariant:** do not `cargo clean` the Colibri checkout until the ISO +preflight/build has consumed `../colibri/target/release`. + +--- + +## Current XFCE Operator USB Baseline + +The active branch target is the XFCE live operator USB. Authoritative state +lives in `packages/` (what ships) and `PLAN-OPERATOR-USB-NEXT.md` (round-scope +decisions and any "for now" retention notes). Final graphical validation +requires real hardware — do not treat bhyve, nested VMs, or static image +inspection as final proof that SDDM/XFCE works. + +--- + +## System Configuration + +**Privilege model:** distinguish build-host administration from live-USB runtime. + +- On the FreeBSD build host, operator-facing commands may use `sudo`. +- Inside the live USB, `sudo` is intentionally absent. +- Live privileged actions use FreeBSD `mac_do` via `mdo -u root `. +- Agent runtime code must not shell out to `sudo` for privileged host changes. +- Privileged Clawdie-AI host operations go through the hostd RPC layer. + +--- + +## Installer Temp Files + +The GUI installer uses `/tmp/clawdie-install.conf` to pass wizard values to +`firstboot.sh`. This is an exemption from the project-local `tmp/` rule. + +**Rationale:** + +- Live ISO has no project root +- Single-user install phase (no other users on the system) +- File is consumed once by `firstboot.sh` then deleted on reboot +- PF firewall is not yet running during install + +**Applies to:** + +- `/tmp/clawdie-install.conf` — GUI wizard config output +- `/tmp/clawdie-firstboot.*` — firstboot progress and log (written by rc.d) + +## Repo-local ISO Build Workspace + +ISO builds use repo-local `tmp/` for large caches and output artifacts: + +- `tmp/cache` — build cache +- `tmp/cache/mnt` — temporary md(4) work-image mountpoint +- `tmp/output` — generated `.img.gz` artifacts and checksums +- `tmp/packages` — fetched package archives + +`tmp/cache/mnt` is an ISO-builder-specific mountpoint exception. Do not mount +unrelated datasets, recovery filesystems, or scratch filesystems elsewhere under +repo `tmp/`. If a build is interrupted, use the `iso-build-cleanup` skill before +retrying. + +--- + +## Cross-Repo Coordination + +Clawdie spans three repos. Changes often require coordinated updates. + +| Repo | Purpose | Remote | +| ------------- | ---------------------------------------- | --------------------------------------------------- | +| `Clawdie-AI` | Agent runtime, control plane, channels | `git@code.smilepowered.org:clawdie/clawdie-ai.git` | +| `clawdie-iso` | ISO builder, firstboot wizard, installer | `git@code.smilepowered.org:clawdie/clawdie-iso.git` | +| `Colibri` | Cross-platform Rust control plane core | `git@code.smilepowered.org:clawdie/colibri.git` | + +Primary remote: `code.smilepowered.org` (self-hosted Forgejo, SSH via local host +config). Codeberg is the public mirror only; do not treat it as the source of +truth for agent coordination or branch-state claims. + +When changes span both repos, create a handoff doc in the secondary repo +listing what needs updating. See `Clawdie-AI/AGENTS.md` for full protocol. + +--- + +## Agent Handoff Documents + +Use ephemeral handoff files to transfer context between agents. + +- **Name:** `doc/-HANDOFF.md` or `-HANDOFF.md` (repo root) +- **Lifecycle:** Create when handing off, delete when complete +- **Structure:** Must include task checklist, deletion criteria, results section + +See `Clawdie-AI/AGENTS.md` for the full handoff template and protocol. + +--- + +## Attribution in Commit History + +Use attribution in commit messages, not in code comments. + +Labels: + +- `Sam & Codex` — changes made by Sam and Codex +- `Sam & Claude` — changes made by Sam and Claude +- `C&C` — joint change with equal credit for Claude and Codex + +Add the label to the commit subject or body. Example: + +``` +Fix bhyve preflight checks (C&C) +``` diff --git a/BUILD.md b/BUILD.md index 0b951f5..2ad8dc3 100644 --- a/BUILD.md +++ b/BUILD.md @@ -90,7 +90,10 @@ When enabled, the image includes: ``` The build also creates the `colibri` service user/group and writes rc.conf -values for `colibri_daemon_enable`, paths, and `colibri_cost_mode`. +values for `colibri_daemon_enable`, paths, and `colibri_cost_mode`. Operator +USB builds stage Colibri by default but keep `colibri_daemon_enable=NO` unless +the build explicitly overrides `COLIBRI_DAEMON_ENABLE=YES`, so the daemon cannot +block SDDM/XFCE boot while service supervision is still being validated. --- diff --git a/PLAN-OPERATOR-USB-NEXT.md b/PLAN-OPERATOR-USB-NEXT.md index 78cd67e..dd452d2 100644 --- a/PLAN-OPERATOR-USB-NEXT.md +++ b/PLAN-OPERATOR-USB-NEXT.md @@ -334,8 +334,8 @@ network setup hooks ```sh ls -l /etc/resolv.conf cat /etc/resolv.conf -host codeberg.org -ping -c 1 codeberg.org +host code.smilepowered.org +ping -c 1 code.smilepowered.org ``` #### 2. Touchpad base/input enablement and diagnostics @@ -614,6 +614,50 @@ Real-hardware acceptance should be recorded against `doc/AMD-ASUS-XFCE-LIVE-USB- --- +## 2.2. Live Self-Debug Code Checkout Seed + +**Operator request — 2026-06-01 AMD live session:** the next rebuilt operator +USB should prepopulate the live `clawdie` home with the relevant source trees so +the operator can start a local `pi` session from XFCE, log in with a provider, +and let that agent inspect the live system and the shipped source side by side. + +**Goal:** make the live USB self-debuggable without first cloning repositories +over a possibly flaky network. + +**Candidate layout:** keep the source snapshots under one operator-facing +folder so `$HOME` stays uncluttered: + +```text +/home/clawdie/ai/clawdie-iso +/home/clawdie/ai/clawdie-ai +/home/clawdie/ai/colibri +``` + +**Implementation notes:** + +- Seed clean checkouts or source snapshots only; do not copy API keys, + `.env` files, SSH private keys, build caches, package caches, `tmp/`, or + other private host state. +- Prefer the exact branch/commit used by the image build, recorded in + `/usr/local/share/clawdie-iso/build-manifest.json` and visible from + `hw-report`. +- The snapshots should be owned by `clawdie:clawdie` and readable/writable from + XFCE terminals. +- Keep provider authentication manual. The image may include code, but it must + not bake provider credentials. +- If full `.git` history is too large, use shallow clones or archive snapshots + plus a small manifest that records remote URL, branch, commit, and dirty + state. +- This is a live-debug aid, not a build-host replacement: Linux agents still do + not build the ISO, and real hardware proof remains operator/Codex-owned. + +**Why it matters:** when Colibri, XFCE, rc.d, input, or package-list bugs only +show up on real hardware, a local Pi session can read `/var/log`, `hw-report`, +XFCE config, and the source tree in the same environment where the bug occurs. +That shortens the loop between operator observations and source fixes. + +--- + ## 3. Sequencing Recommended order (each can be a separate PR / commit cluster): diff --git a/README.md b/README.md index 22fd64d..87af0e7 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ later from the live session. ## Quick Start: Build Image ```sh -git clone https://codeberg.org/Clawdie/Clawdie-ISO.git +git clone https://code.smilepowered.org/clawdie/clawdie-iso.git cd Clawdie-ISO # Full build: fetch FreeBSD, packages, Clawdie-AI, then assemble image. diff --git a/build-vps.sh b/build-vps.sh index c8753a2..601af43 100755 --- a/build-vps.sh +++ b/build-vps.sh @@ -65,8 +65,28 @@ fi # --- step 2: fetch Clawdie-AI tarball --- if [ "$CLAWDIE_VERSION" = "latest" ] || [ -z "$CLAWDIE_VERSION" ]; then echo "==> [2/6] Resolving latest Clawdie-AI version..." - CLAWDIE_VERSION=$(curl -s "https://codeberg.org/api/v1/repos/Clawdie/Clawdie-AI/releases?limit=1" \ - | grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4 | sed 's/^v//') + CLAWDIE_VERSION=$( + curl -fsS "https://code.smilepowered.org/api/v1/repos/clawdie/clawdie-ai/releases?limit=20" 2>/dev/null \ + | grep -o '"tag_name":"[^"]*"' \ + | head -1 \ + | cut -d'"' -f4 \ + | sed 's/^v//' + ) + if [ -z "$CLAWDIE_VERSION" ]; then + CLAWDIE_VERSION=$( + git ls-remote --tags "https://code.smilepowered.org/clawdie/clawdie-ai.git" 2>/dev/null \ + | awk -F/ '$2 == "tags" && $3 ~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ { print $3 }' \ + | sed 's/^v//' \ + | sort -t. -k1,1n -k2,2n -k3,3n \ + | tail -n 1 \ + | sed 's/^v//' + ) + fi + if [ -z "$CLAWDIE_VERSION" ]; then + echo "ERROR: could not resolve latest Clawdie-AI release/tag from Forgejo." + echo " Pin --clawdie-version X.Y.Z explicitly." + exit 1 + fi echo " Resolved: v${CLAWDIE_VERSION}" fi @@ -74,7 +94,7 @@ CLAWDIE_TARBALL="${CACHE_DIR}/clawdie-ai-v${CLAWDIE_VERSION}.tar.gz" if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$CLAWDIE_TARBALL" ]; then echo "==> [2/6] Downloading Clawdie-AI v${CLAWDIE_VERSION}..." curl -L --progress-bar -o "$CLAWDIE_TARBALL" \ - "https://codeberg.org/Clawdie/Clawdie-AI/archive/v${CLAWDIE_VERSION}.tar.gz" + "https://code.smilepowered.org/clawdie/clawdie-ai/archive/v${CLAWDIE_VERSION}.tar.gz" else echo "==> [2/6] Clawdie-AI cached." fi diff --git a/build.cfg b/build.cfg index 998d439..399a78b 100644 --- a/build.cfg +++ b/build.cfg @@ -29,7 +29,7 @@ IMAGE_SIZE="28G" # build.sh derives IMAGE_NAME from desktop, the FreeBSD major-version codename, # and the build date. -# Clawdie-AI ref to bundle from Codeberg. +# Clawdie-AI ref to bundle from Forgejo. # Use main for install validation so ISO firstboot exercises the current # post-install setup/token flow. Use --clawdie-version X.Y.Z for release builds. CLAWDIE_VERSION="main" @@ -75,7 +75,10 @@ EMBED_DIMENSIONS="${EMBED_DIMENSIONS:-1024}" FEATURE_COLIBRI="${FEATURE_COLIBRI:-YES}" COLIBRI_REPO="${COLIBRI_REPO:-../colibri}" COLIBRI_ARTIFACT_DIR="${COLIBRI_ARTIFACT_DIR:-}" -COLIBRI_DAEMON_ENABLE="${COLIBRI_DAEMON_ENABLE:-YES}" +# Stage Colibri binaries by default, but do not block live boot on the daemon. +# Hardware validation can start it manually after rc.d supervision is proven on +# the target image. +COLIBRI_DAEMON_ENABLE="${COLIBRI_DAEMON_ENABLE:-NO}" COLIBRI_COST_MODE="${COLIBRI_COST_MODE:-smart}" # Local LLM runtime (optional) diff --git a/build.sh b/build.sh index 9d12725..cb2f1e3 100755 --- a/build.sh +++ b/build.sh @@ -283,11 +283,23 @@ preflight_colibri_artifacts() { resolve_colibri_paths _colibri_rc="${_resolved_colibri_repo}/packaging/freebsd/colibri_daemon.in" + _colibri_newsyslog="${_resolved_colibri_repo}/packaging/freebsd/newsyslog-colibri.conf" if [ ! -f "${_colibri_rc}" ]; then echo "ERROR: Colibri rc.d source missing: ${_colibri_rc}" echo " Set COLIBRI_REPO=/path/to/colibri or FEATURE_COLIBRI=NO." exit 1 fi + if ! grep -q '^command="/usr/sbin/daemon"' "${_colibri_rc}" || \ + ! grep -q '^procname="/usr/sbin/daemon"' "${_colibri_rc}"; then + echo "ERROR: Colibri rc.d source does not supervise with daemon(8): ${_colibri_rc}" + echo " Update the Colibri checkout before building; a foreground daemon blocks live boot." + exit 1 + fi + if [ ! -f "${_colibri_newsyslog}" ]; then + echo "ERROR: Colibri newsyslog source missing: ${_colibri_newsyslog}" + echo " Set COLIBRI_REPO=/path/to/colibri or FEATURE_COLIBRI=NO." + exit 1 + fi for _colibri_bin in colibri-daemon colibri colibri-smoke-agent; do if [ ! -x "${_resolved_colibri_artifact_dir}/${_colibri_bin}" ]; then echo "ERROR: Colibri release binary missing: ${_resolved_colibri_artifact_dir}/${_colibri_bin}" @@ -332,7 +344,7 @@ json_escape() { resolve_clawdie_commit() { _ref="$1" - _repo="https://codeberg.org/Clawdie/Clawdie-AI.git" + _repo="https://code.smilepowered.org/clawdie/clawdie-ai.git" if printf '%s' "$_ref" | grep -Eq '^[0-9a-fA-F]{40}$'; then printf '%s\n' "$_ref" return 0 @@ -350,6 +362,29 @@ resolve_clawdie_commit() { fi } +resolve_latest_clawdie_tag() { + _repo_api="https://code.smilepowered.org/api/v1/repos/clawdie/clawdie-ai" + _repo_git="https://code.smilepowered.org/clawdie/clawdie-ai.git" + + _tag=$( + curl -fsS "${_repo_api}/releases?limit=20" 2>/dev/null \ + | grep -o '"tag_name":"[^"]*"' \ + | head -1 \ + | cut -d'"' -f4 + ) + if [ -n "$_tag" ]; then + printf '%s\n' "$_tag" + return 0 + fi + + git ls-remote --tags "$_repo_git" 2>/dev/null \ + | awk -F/ '$2 == "tags" && $3 ~ /^v[0-9]+\.[0-9]+\.[0-9]+$/ { print $3 }' \ + | sed 's/^v//' \ + | sort -t. -k1,1n -k2,2n -k3,3n \ + | tail -n 1 \ + | sed 's/^/v/' +} + is_pinned_clawdie_ref() { _ref="$1" printf '%s' "$_ref" | grep -Eq '^[0-9a-fA-F]{40}$|^v[0-9]+\.[0-9]+\.[0-9]+$' @@ -542,10 +577,13 @@ refresh_live_desktop_caches() { run_live_chroot /usr/local/bin/update-desktop-database /usr/local/share/applications fi if [ -x "${MOUNT_POINT}/usr/local/bin/gtk-update-icon-cache" ]; then - for _icon_theme in hicolor Adwaita AdwaitaLegacy Papirus; do - if [ -d "${MOUNT_POINT}/usr/local/share/icons/${_icon_theme}" ]; then - run_live_chroot /usr/local/bin/gtk-update-icon-cache -f -t "/usr/local/share/icons/${_icon_theme}" || true - fi + # Regenerate every installed icon theme cache. FreeBSD packages and + # Clawdie branding install icons into hicolor and other theme + # directories; missed caches show up as blank/dot panel icons. + for _icon_theme_dir in "${MOUNT_POINT}/usr/local/share/icons"/*/; do + [ -d "$_icon_theme_dir" ] || continue + _theme_name=$(basename "$_icon_theme_dir") + run_live_chroot /usr/local/bin/gtk-update-icon-cache -f -t "/usr/local/share/icons/${_theme_name}" || true done fi @@ -764,6 +802,67 @@ install_live_npm_globals() { fi } +seed_live_ai_source_repo() { + _repo_src="$1" + _repo_name="$2" + _repo_dest="${MOUNT_POINT}/home/clawdie/ai/${_repo_name}" + + if [ ! -d "${_repo_src}" ]; then + echo " Skipping AI source seed ${_repo_name}: ${_repo_src} not found" + return 0 + fi + if ! command -v git >/dev/null 2>&1 || ! git -C "${_repo_src}" rev-parse --git-dir >/dev/null 2>&1; then + echo " Skipping AI source seed ${_repo_name}: not a git worktree" + return 0 + fi + + echo " Seeding AI source snapshot: ${_repo_name}" + rm -rf "${_repo_dest}" + mkdir -p "${_repo_dest}" + git -C "${_repo_src}" archive --format=tar HEAD | tar -C "${_repo_dest}" -xf - + + _repo_branch=$(git -C "${_repo_src}" symbolic-ref --short -q HEAD 2>/dev/null || echo detached) + _repo_commit=$(git -C "${_repo_src}" rev-parse HEAD 2>/dev/null || echo unknown) + _repo_origin=$(git -C "${_repo_src}" remote get-url origin 2>/dev/null || echo unknown) + _repo_dirty=false + if ! git -C "${_repo_src}" diff --quiet 2>/dev/null || ! git -C "${_repo_src}" diff --cached --quiet 2>/dev/null; then + _repo_dirty=true + fi + + cat > "${_repo_dest}/.clawdie-source.json" < "${MOUNT_POINT}/home/clawdie/ai/README.txt" <<'EOF' +Clawdie live AI source snapshots + +These directories are included so the operator can start a local provider-backed +Pi session from the live XFCE desktop and inspect the shipped source beside the +running system. + +No API keys, .env files, SSH private keys, build caches, package caches, tmp/ +directories, or uncommitted worktree changes are included. Each snapshot has a +.clawdie-source.json file recording the source remote, branch, commit, and dirty +state at image build time. +EOF + seed_live_ai_source_repo "${SCRIPT_DIR}" "clawdie-iso" + seed_live_ai_source_repo "${SCRIPT_DIR}/../clawdie-ai" "clawdie-ai" + seed_live_ai_source_repo "${SCRIPT_DIR}/../colibri" "colibri" + chroot "${MOUNT_POINT}" chown -R clawdie:clawdie /home/clawdie/ai +} + configure_live_operator_session() { echo " Configuring live operator session..." @@ -772,6 +871,8 @@ configure_live_operator_session() { "${MOUNT_POINT}/usr/local/bin/clawdie-bootstrap-launch.sh" install -m 0755 "${LIVE_SESSION_DIR}/clawdie-noblank-guard.sh" \ "${MOUNT_POINT}/usr/local/bin/clawdie-noblank-guard.sh" + install -m 0755 "${LIVE_SESSION_DIR}/clawdie-xfce-visuals-guard.sh" \ + "${MOUNT_POINT}/usr/local/bin/clawdie-xfce-visuals-guard.sh" install -m 0755 "${LIVE_SESSION_DIR}/hw-report" \ "${MOUNT_POINT}/usr/local/bin/hw-report" @@ -830,6 +931,8 @@ EOF "${MOUNT_POINT}/usr/local/etc/xdg/autostart/clawdie-bootstrap.desktop" install -m 0644 "${LIVE_SESSION_DIR}/autostart/clawdie-noblank-guard.desktop" \ "${MOUNT_POINT}/usr/local/etc/xdg/autostart/clawdie-noblank-guard.desktop" + install -m 0644 "${LIVE_SESSION_DIR}/autostart/clawdie-xfce-visuals-guard.desktop" \ + "${MOUNT_POINT}/usr/local/etc/xdg/autostart/clawdie-xfce-visuals-guard.desktop" mkdir -p "${MOUNT_POINT}/usr/local/etc/X11/xorg.conf.d" install -m 0644 "${LIVE_SESSION_DIR}/xorg.conf.d/30-keyboard.conf" \ "${MOUNT_POINT}/usr/local/etc/X11/xorg.conf.d/30-keyboard.conf" @@ -1110,6 +1213,8 @@ EOF "${MOUNT_POINT}/home/clawdie/Desktop/Clawdie Bootstrap.desktop" \ "${MOUNT_POINT}/home/clawdie/Desktop/Clawdie Hardware Report.desktop" + install_live_ai_source_snapshots + # The stock FreeBSD install memstick is intentionally read-only. This live # operator USB needs a writable root so SDDM, Xorg, NetworkMgr, logs, and # operator diagnostics can create runtime state on the flashed stick. @@ -1378,14 +1483,31 @@ EOF cp "${_wallpapers_dir}"/* "${MOUNT_POINT}/usr/local/share/clawdie-iso/wallpapers/" 2>/dev/null || true fi - # Brand icons (e.g. the Whisker Start-button triangle). Referenced by - # absolute path from xfce4-panel.xml so the button never depends on an - # icon-theme cache being current at first login. + # Brand icons (e.g. the Whisker Start-button triangle). Install both the + # raw files for direct diagnostics and hicolor theme names for XFCE plugins + # that do not reliably load absolute icon paths. _icons_dir="${LIVE_SESSION_DIR}/icons" if [ -d "$_icons_dir" ]; then echo " Installing brand icons..." - mkdir -p "${MOUNT_POINT}/usr/local/share/clawdie-iso/icons" + mkdir -p \ + "${MOUNT_POINT}/usr/local/share/clawdie-iso/icons" \ + "${MOUNT_POINT}/usr/local/share/icons/hicolor/48x48/apps" \ + "${MOUNT_POINT}/usr/local/share/icons/hicolor/64x64/apps" \ + "${MOUNT_POINT}/usr/local/share/icons/hicolor/scalable/apps" cp "${_icons_dir}"/* "${MOUNT_POINT}/usr/local/share/clawdie-iso/icons/" 2>/dev/null || true + if [ -f "${_icons_dir}/clawdie-start.png" ]; then + install -m 0644 "${_icons_dir}/clawdie-start.png" \ + "${MOUNT_POINT}/usr/local/share/icons/hicolor/48x48/apps/clawdie-start.png" + install -m 0644 "${_icons_dir}/clawdie-start.png" \ + "${MOUNT_POINT}/usr/local/share/icons/hicolor/64x64/apps/clawdie-start.png" + fi + if [ -f "${_icons_dir}/clawdie-start.svg" ]; then + install -m 0644 "${_icons_dir}/clawdie-start.svg" \ + "${MOUNT_POINT}/usr/local/share/icons/hicolor/scalable/apps/clawdie-start.svg" + fi + if [ -x "${MOUNT_POINT}/usr/local/bin/gtk-update-icon-cache" ]; then + run_live_chroot /usr/local/bin/gtk-update-icon-cache -f -t /usr/local/share/icons/hicolor || true + fi fi rm -rf "${MOUNT_POINT}/home/clawdie/.cache" "${MOUNT_POINT}/etc/skel/.cache" @@ -1517,11 +1639,15 @@ else fi # --- step 4: fetch + prepare Clawdie-AI tarball (offline-ready) --- -# Resolve "latest" to the most recent Codeberg tag. +# Resolve "latest" from Forgejo releases first, then tags. if [ "${CLAWDIE_REF:-${CLAWDIE_VERSION:-}}" = "latest" ] || [ -z "${CLAWDIE_REF:-}" ]; then echo "==> [4/7] Resolving latest Clawdie-AI version..." - CLAWDIE_VERSION=$(curl -s "https://codeberg.org/api/v1/repos/Clawdie/Clawdie-AI/releases?limit=1" \ - | grep -o '"tag_name":"[^"]*"' | head -1 | cut -d'"' -f4 | sed 's/^v//') + CLAWDIE_VERSION=$(resolve_latest_clawdie_tag | sed 's/^v//') + if [ -z "$CLAWDIE_VERSION" ]; then + echo "ERROR: could not resolve latest Clawdie-AI release/tag from Forgejo." + echo " Pin --clawdie-ref main or --clawdie-version X.Y.Z explicitly." + exit 1 + fi CLAWDIE_REF="v${CLAWDIE_VERSION}" echo " Resolved: ${CLAWDIE_REF}" fi @@ -1545,7 +1671,7 @@ else fi CLAWDIE_TARBALL="${CACHE_DIR}/clawdie-ai-${CLAWDIE_CACHE_KEY}.tar.gz" -CLAWDIE_TARBALL_URL="https://codeberg.org/Clawdie/Clawdie-AI/archive/${CLAWDIE_ARCHIVE_REF}.tar.gz" +CLAWDIE_TARBALL_URL="https://code.smilepowered.org/clawdie/clawdie-ai/archive/${CLAWDIE_ARCHIVE_REF}.tar.gz" if [ "$SKIP_FETCH" -eq 0 ] || [ ! -f "$CLAWDIE_TARBALL" ]; then echo "==> [4/7] Fetching Clawdie-AI ${CLAWDIE_REF} (${CLAWDIE_ARCHIVE_REF})..." mkdir -p "$CACHE_DIR" diff --git a/doc/AMD-ASUS-XFCE-LIVE-USB-FINDINGS.md b/doc/AMD-ASUS-XFCE-LIVE-USB-FINDINGS.md index cf2efe0..ff5d626 100644 --- a/doc/AMD-ASUS-XFCE-LIVE-USB-FINDINGS.md +++ b/doc/AMD-ASUS-XFCE-LIVE-USB-FINDINGS.md @@ -926,6 +926,34 @@ xrandr --query xfconf-query -c xfce4-panel -p /panels/panel-1 -lv ``` +## Follow-up live XFCE command evidence — 2026-06-01 + +After the report archive was collected, the operator ran direct `xfconf-query` +checks in the live XFCE session before rebooting. + +Confirmed good state: + +- `xsettings` had `Greybird`, `Papirus`, `DMZ-White`, `Noto Sans 11`, and + `Hack 11`; global GTK/icon/cursor/font configuration is loading. +- `xfce4-desktop` had `image-show=true`, `image-style=5`, and + `last-image=/usr/local/share/clawdie-iso/wallpapers/clawdie-operator-bg.png`; + the wallpaper config and image file exist. +- `xfce4-panel` had the intended panel size, opacity, plugin order, and launcher + entries; the panel seed is loading. + +Confirmed problem state: + +- The shipped live image only had `clawdie-start` under + `/usr/local/share/clawdie-iso/icons/`; `find /usr/local/share/icons -name +'clawdie-start*'` returned nothing until the operator manually copied the icon + into `hicolor` and rebuilt the cache. +- The Whisker button still did not visibly change during that live-session test, + so the next build should stage the icon in the theme at build time and verify + real first-login behavior rather than relying on hot panel reloads. +- `xfce4-mixer` auto-selected `ATIR6xxHDMI`/`Vol` even though FreeBSD selected + the internal Realtek speaker as the default device. The default panel should + not ship a mixer plugin that controls HDMI on AMD laptops. + ## Fix-planning backlog derived from this report This is a backlog only; solutions should be discussed separately. diff --git a/doc/XFCE-PANEL-BUGS-HANDOFF.md b/doc/XFCE-PANEL-BUGS-HANDOFF.md index c194c00..970efe5 100644 --- a/doc/XFCE-PANEL-BUGS-HANDOFF.md +++ b/doc/XFCE-PANEL-BUGS-HANDOFF.md @@ -66,14 +66,29 @@ FreeBSD/operator side. Pass 2 only improves _proportion and uniformity_. - [ ] `square-icons` took effect on the systray (network/mixer icons square and uniform) — confirm the installed `systray` plugin honors the property. +## Pre-build changes applied (2026-06-01) — Pass 3 + +Follow-up from the AMD live report and direct `xfconf-query` checks: + +- **Start icon:** the live image had only `/usr/local/share/clawdie-iso/icons/*`; + no `clawdie-start` entries existed under `/usr/local/share/icons`. The build + now stages `clawdie-start.png` into `hicolor/48x48/apps` and + `hicolor/64x64/apps`, stages the SVG into `hicolor/scalable/apps`, updates the + `hicolor` cache at build time, and uses the themed icon name + `button-icon="clawdie-start"`. +- **Mixer:** `xfce4-mixer` auto-selected `ATIR6xxHDMI`/`Vol` on AMD hardware even + when FreeBSD's default sound unit was the internal Realtek speaker. The default + panel now omits the mixer plugin instead of shipping a visible control pinned + to HDMI. Re-add only after a reliable backend/default-device strategy exists. + ## Deletion Criteria - [ ] Whiskermenu Start button icon is visible (not missing/broken). - [ ] Clock plugin renders date+time in the panel. - [ ] Clipman re-added and loads without "could not be loaded" dialog (dropped from this build pending D-Bus root-cause). -- [ ] Systray icons (NetworkMgr, mixer) and xkb flag icon are visually - uniform in size — no oversized or undersized outliers. +- [ ] Systray icons (NetworkMgr) and xkb flag/text display are visually uniform + in size — no oversized or undersized outliers. - [ ] All fixes confirmed on real hardware boot (not just image inspection). ## Operator-Reported Issues diff --git a/docs/ISO-MANIFESTS.md b/docs/ISO-MANIFESTS.md new file mode 100644 index 0000000..e556beb --- /dev/null +++ b/docs/ISO-MANIFESTS.md @@ -0,0 +1,128 @@ +# ISO Workflow Manifest Conventions + +This repo is the producer of operator-USB workflow artifacts. Colibri and +operator dashboards consume the JSON manifests, summaries, and referenced logs; +they do not scrape terminal scrollback as the contract. + +## Common rules + +All ISO workflow manifests SHOULD include these top-level fields: + +| Field | Meaning | +| ----------------------------- | ------------------------------------------------------------------------------- | +| `schema` | Stable schema id, for example `clawdie.iso.publish.v1` | +| `project` | `clawdie-iso` | +| `workflow` | Skill or script name that produced the manifest | +| `run_id` | Unique run id; include UTC time and commit or artifact stem when possible | +| `status` | `pass`, `fail`, `warn`, or `skipped` | +| `actor` | Responsible role or operator-visible identity | +| `host` | Host that performed the workflow | +| `branch` / `commit` | ISO repo branch and commit when a checkout is available | +| `started_at` / `completed_at` | UTC ISO-8601 timestamps; use `null` when unknown | +| `inputs` | Artifact URLs, image paths, package lists, device ids, or report paths consumed | +| `checks` | Array or object of named checks with pass/fail status and concise details | +| `outputs` | Manifest path, public URLs, copied reports, or produced artifact paths | +| `logs` | Paths to raw logs. Do not inline large logs. | +| `summary` | Short human-readable result suitable for Colibri activity text | + +Secrets, API keys, auth keys, private SSH keys, and full unredacted environment +dumps MUST NOT be written into manifests. If a workflow uses a secret, record a +boolean such as `tailscale_auth_key_baked: true` or a public fingerprint only. + +## Canonical schema ids and paths + +| Workflow | Schema | Canonical output path | +| ---------------------- | ------------------------------ | --------------------------------------------------------------------------------------------- | +| ISO build | `clawdie.iso.build.v1` | `tmp/colibri/iso-build/.json` and `tmp/colibri/iso-build/latest.json` | +| ISO publish | `clawdie.iso.publish.v1` | `tmp/output/.manifest.json` | +| Flash verification | `clawdie.iso.flash.v1` | `tmp/colibri/iso-flash/.json` and `tmp/colibri/iso-flash/latest.json` | +| Mounted validation | `clawdie.iso.validation.v1` | `tmp/colibri/iso-validation/.json` and `tmp/colibri/iso-validation/latest.json` | +| Hardware report ingest | `clawdie.iso.hardware.v1` | `tmp/colibri/iso-hardware/.json` and `tmp/colibri/iso-hardware/latest.json` | +| Package audit | `clawdie.iso.package-audit.v1` | `tmp/colibri/iso-package-audit/.json` and `tmp/colibri/iso-package-audit/latest.json` | + +`tmp/colibri/` is repo-local scratch/output state. It is intentionally not +committed. When a result must survive across hosts, commit a concise handoff +summary under `doc/` or publish the manifest with the image artifact. + +## Workflow-specific fields + +### `clawdie.iso.build.v1` + +Use for the build result, not for the embedded image manifest alone. Include: + +- build command and flags +- FreeBSD version/architecture +- source branch/commit/dirty state +- Colibri staging mode and artifact directory when `FEATURE_COLIBRI=YES` +- output image path, compressed image path when present, checksum path when present +- static checks run before build (`sh -n`, markdown format, Colibri preflight) +- build log path under `tmp/` + +The image itself also carries +`/usr/local/share/clawdie-iso/build-manifest.json`; that file is for runtime +inspection from the live USB and does not replace the workflow result manifest. + +### `clawdie.iso.publish.v1` + +Produced by `scripts/write-artifact-manifest.sh`. Include: + +- compressed image, checksum file, and manifest names +- SHA256 of the compressed image +- raw and compressed sizes when known +- public URLs when published +- checksum verification status +- publish host, actor, branch, and commit + +### `clawdie.iso.flash.v1` + +Use for Hermes USB/IMG Deployer verification and flashing. Include: + +- consumed publish manifest URL/path +- downloaded image/checksum paths +- checksum and `gzip -t` results +- selected whole-disk device, model, serial when available, and size +- explicit confirmation that the target is a whole disk, not a partition +- flash command summary and post-flash sync/eject result + +### `clawdie.iso.validation.v1` + +Use for static or mounted-image validation on the FreeBSD build host. Include: + +- image path and mount device/slices inspected +- SDDM, `clawdie-live-gpu`, `mdo`, CLI, seed-slice, no-blank, power, and panel + asset checks +- validation limitations, especially that mounted inspection is not graphical + hardware proof + +### `clawdie.iso.hardware.v1` + +Use for real-machine live USB reports. Include: + +- hardware model, BIOS/UEFI version when collected, CPU, GPU, network, audio, + input summary +- `/var/log/clawdie-live-gpu.log` outcome +- GL renderer, SDDM/XFCE status, power/no-blank status +- `hw-report` output path and public `hw-probe` URL if the operator uploaded it +- operator-observed pass/fail notes for touchpad, Wi-Fi, audio, and display + +### `clawdie.iso.package-audit.v1` + +Use for package-list hygiene. Include: + +- package list file audited +- package category (`boot-critical`, `operator-workflow`, `diagnostic`, or + `candidate-to-defer`) +- package size and flat size from the FreeBSD package database or archive + metadata +- reason kept and deferral risk + +## Handoff expectations + +- Skills should print the manifest path and a concise summary when they finish. +- If a workflow is manual-only, write the manifest from the collected facts before + handing off to another role. +- Raw logs stay in `tmp/` or with the published artifact; markdown handoffs should + quote only the exact failure lines needed for follow-up. +- Build, publish, and mounted validation remain FreeBSD-owner workflows. Flashing + remains Hermes-owned. Live hardware proof remains operator/Codex hardware + validation, not static inspection. diff --git a/firstboot/shell-deploy.sh b/firstboot/shell-deploy.sh index d4bab8e..30feb8c 100755 --- a/firstboot/shell-deploy.sh +++ b/firstboot/shell-deploy.sh @@ -152,7 +152,7 @@ clawdie_shell_deploy_upgrade() { mkdir -p "$STAGING_DIR" if ! tar -xzf "$CLAWDIE_TARBALL" -C "$STAGING_DIR" --strip-components=1 2>/dev/null; then - # Try without --strip-components (Codeberg archives have a top-level dir) + # Try without --strip-components (Forgejo archives have a top-level dir) tar -xzf "$CLAWDIE_TARBALL" -C "$(dirname "$STAGING_DIR")" 2>/dev/null || { log_msg "[deploy] ERROR: Failed to extract upgrade tarball" return 1 diff --git a/live/operator-session/autostart/clawdie-xfce-visuals-guard.desktop b/live/operator-session/autostart/clawdie-xfce-visuals-guard.desktop new file mode 100644 index 0000000..1a10853 --- /dev/null +++ b/live/operator-session/autostart/clawdie-xfce-visuals-guard.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Name=Clawdie XFCE Visual Guard +Comment=Re-apply Clawdie live USB theme, icon, and wallpaper settings +Exec=/usr/local/bin/clawdie-xfce-visuals-guard.sh +OnlyShowIn=XFCE; +X-GNOME-Autostart-enabled=true +Terminal=false diff --git a/live/operator-session/clawdie-xfce-session-inner b/live/operator-session/clawdie-xfce-session-inner index addc8de..e35619c 100644 --- a/live/operator-session/clawdie-xfce-session-inner +++ b/live/operator-session/clawdie-xfce-session-inner @@ -7,7 +7,7 @@ echo "=== $(date -u '+%Y-%m-%dT%H:%M:%SZ') clawdie-xfce-session-inner start ===" PANEL_TEMPLATE_ROOT="/usr/local/share/clawdie-iso/panel-skel" PANEL_TEMPLATE_CONFIG="${PANEL_TEMPLATE_ROOT}/.config" -PANEL_STAMP="${HOME}/.config/clawdie/xfce-panel-seeded-v2" +PANEL_STAMP="${HOME}/.config/clawdie/xfce-panel-seeded-v3" ensure_seeded_panel_profile() { mkdir -p "${HOME}/.config/clawdie" @@ -22,6 +22,7 @@ ensure_seeded_panel_profile() { if [ -f "$PANEL_STAMP" ] && \ [ -f "$_panel_xml" ] && \ grep -q 'whiskermenu' "$_panel_xml" 2>/dev/null && \ + grep -q 'clawdie-start' "$_panel_xml" 2>/dev/null && \ [ -d "$_panel_launcher_dir2" ] && \ [ -d "$_panel_launcher_dir3" ] && \ [ -d "$_panel_launcher_dir4" ]; then diff --git a/live/operator-session/clawdie-xfce-visuals-guard.sh b/live/operator-session/clawdie-xfce-visuals-guard.sh new file mode 100755 index 0000000..97a38e2 --- /dev/null +++ b/live/operator-session/clawdie-xfce-visuals-guard.sh @@ -0,0 +1,87 @@ +#!/bin/sh +# Best-effort live-session visual guard for XFCE. +# +# XFCE may create monitor-specific desktop keys only after xfdesktop starts, and +# some panel plugins are stricter about themed icon names than absolute paths. +# Re-assert the operator USB visual contract after login without failing the +# session if a component is missing. + +LOG="${HOME}/.clawdie-xfce-visuals-guard.log" +WALLPAPER="/usr/local/share/clawdie-iso/wallpapers/clawdie-operator-bg.png" +START_ICON="clawdie-start" + +log() { + printf '%s %s\n' "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$*" >>"$LOG" 2>/dev/null || true +} + +set_xfconf() { + _channel="$1" + _property="$2" + _type="$3" + _value="$4" + + command -v xfconf-query >/dev/null 2>&1 || return 0 + xfconf-query -c "$_channel" -p "$_property" -s "$_value" >/dev/null 2>&1 || \ + xfconf-query -c "$_channel" -p "$_property" -n -t "$_type" -s "$_value" >/dev/null 2>&1 || true +} + +apply_theme() { + set_xfconf xsettings /Net/ThemeName string Greybird + set_xfconf xsettings /Net/IconThemeName string Papirus + set_xfconf xsettings /Net/CursorTheme string DMZ-White + set_xfconf xsettings /Net/CursorSize int 24 + set_xfconf xsettings /Gtk/FontName string "Noto Sans 11" + set_xfconf xsettings /Gtk/MonospaceFontName string "Hack 11" +} + +apply_panel() { + set_xfconf xfce4-panel /plugins/plugin-1/button-icon string "$START_ICON" + set_xfconf xfce4-panel /plugins/plugin-1/show-button-icon bool true + set_xfconf xfce4-panel /plugins/plugin-1/show-button-title bool true + set_xfconf xfce4-panel /panels/panel-1/size uint 40 + set_xfconf xfce4-panel /panels/panel-1/icon-size uint 2 + set_xfconf xfce4-panel /plugins/plugin-8/square-icons bool true +} + +apply_wallpaper() { + [ -f "$WALLPAPER" ] || { + log "wallpaper missing: $WALLPAPER" + return 0 + } + command -v xfconf-query >/dev/null 2>&1 || return 0 + + _bases="$(xfconf-query -c xfce4-desktop -l 2>/dev/null | awk '/\/last-image$/ { sub(/\/last-image$/, ""); print }')" + if [ -z "$_bases" ]; then + _bases='/backdrop/screen0/monitor0/workspace0 +/backdrop/screen0/monitorDefault/workspace0' + fi + + printf '%s\n' "$_bases" | while IFS= read -r _base; do + [ -n "$_base" ] || continue + set_xfconf xfce4-desktop "${_base}/last-image" string "$WALLPAPER" + set_xfconf xfce4-desktop "${_base}/image-path" string "$WALLPAPER" + set_xfconf xfce4-desktop "${_base}/image-style" int 5 + set_xfconf xfce4-desktop "${_base}/image-show" bool true + set_xfconf xfce4-desktop "${_base}/color-style" int 0 + done + + if command -v xfdesktop >/dev/null 2>&1; then + xfdesktop --reload >/dev/null 2>&1 || true + fi +} + +run_once() { + log "applying XFCE visual guard" + apply_theme + apply_panel + apply_wallpaper +} + +# Run more than once because xfdesktop/panel may create monitor/plugin state +# after XDG autostart begins. +sleep 3 +run_once +sleep 7 +run_once +sleep 15 +run_once diff --git a/live/operator-session/hw-report b/live/operator-session/hw-report index 335cd02..33f0836 100755 --- a/live/operator-session/hw-report +++ b/live/operator-session/hw-report @@ -180,6 +180,7 @@ run_shell_capture dmesg-hardware-filter "dmesg | egrep -i 'drm|kms|amdgpu|i915|r run_shell_capture dmesg-boot "for f in /var/run/dmesg.boot; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" run_shell_capture xorg-var-logs "for f in /var/log/Xorg.*.log*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" run_shell_capture xorg-user-logs "for f in /home/clawdie/.local/share/xorg/Xorg.*.log*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" +run_shell_capture xsession-errors "for f in /home/clawdie/.xsession-errors /home/clawdie/.xsession-errors.old; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" run_shell_capture var-log-messages "for f in /var/log/messages*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; case \"\$f\" in *.gz) zcat \"\$f\";; *.bz2) bzcat \"\$f\";; *.xz) xzcat \"\$f\";; *.zst) zstdcat \"\$f\";; *) cat \"\$f\";; esac; echo; done" run_shell_capture sddm-log-files "for f in /var/log/sddm.log; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" run_shell_capture sddm-config "for f in /usr/local/etc/sddm.conf /usr/local/etc/sddm.conf.d/*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" @@ -191,7 +192,7 @@ run_if_present ifconfig ifconfig-a -a run_if_present netstat netstat-rn -rn run_shell_capture resolver-state "ls -l /etc/resolv.conf 2>/dev/null || true; readlink /etc/resolv.conf 2>/dev/null || true; cat /etc/resolv.conf 2>/dev/null || true" run_shell_capture wlan-devices "sysctl net.wlan.devices" -run_shell_capture rc-conf-live "grep -E '^(hostname|kld_list|sshd_enable|tailscaled_enable|avahi_daemon_enable|pf_enable|sddm_enable|webcamd_enable|powerdxx_enable|clawdie_live_|performance_cx_lowest|economy_cx_lowest|dumpdev_enable)' /etc/rc.conf || true" +run_shell_capture rc-conf-live "grep -E '^(hostname|kld_list|sshd_enable|tailscaled_enable|avahi_daemon_enable|pf_enable|sddm_enable|webcamd_enable|powerdxx_enable|colibri_daemon_enable|clawdie_live_|performance_cx_lowest|economy_cx_lowest|dumpdev_enable)' /etc/rc.conf || true" run_if_present service service-enabled -e run_if_present sysctl sysctl-hw hw @@ -244,6 +245,7 @@ run_shell_if_present usbhid-dump usbhid-dump-version "usbhid-dump --help 2>&1 | run_if_present cat clawdie-live-gpu-log /var/log/clawdie-live-gpu.log run_if_present cat clawdie-noblank-guard-log /home/clawdie/.clawdie-noblank-guard.log +run_if_present cat clawdie-xfce-visuals-guard-log /home/clawdie/.clawdie-xfce-visuals-guard.log run_if_present cat clawdie-touchpad-guard-log /home/clawdie/.clawdie-touchpad-guard.log run_if_present cat sndstat /dev/sndstat run_if_present mixer mixer-s -s @@ -254,9 +256,15 @@ run_shell_capture input-device-nodes "ls -l /dev/input /dev/input/* /dev/uhid* / run_if_present xset xset-q q run_shell_if_present xfconf-query xfce4-power-manager "xfconf-query -c xfce4-power-manager -l -v 2>/dev/null || true" -run_shell_if_present xfconf-query xfce4-panel-plugins "xfconf-query -c xfce4-panel -p /plugins/plugin-11 2>/dev/null; xfconf-query -c xfce4-panel -p /plugins/plugin-13 2>/dev/null" +run_shell_if_present xfconf-query xfce4-panel "xfconf-query -c xfce4-panel -l -v 2>/dev/null || true" +run_shell_if_present xfconf-query xfce4-desktop "xfconf-query -c xfce4-desktop -l -v 2>/dev/null || true" +run_shell_if_present xfconf-query xsettings "xfconf-query -c xsettings -l -v 2>/dev/null || true" run_shell_if_present xfconf-query xfce4-pointers "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xfconf-query -c pointers -l -v 2>/dev/null || xfconf-query -c pointers -l -v 2>/dev/null || true" run_shell_capture xfce-perchannel-xml "for f in /home/clawdie/.config/xfce4/xfconf/xfce-perchannel-xml/*; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" +run_shell_capture xfce-panel-launchers "find /home/clawdie/.config/xfce4/panel -maxdepth 4 -type f -print -exec sed -n '1,80p' {} \\; 2>/dev/null || true" +run_shell_capture icon-theme-dirs "find /usr/local/share/icons -maxdepth 4 -type f \( -name 'icon-theme.cache' -o -name 'clawdie-start.*' \) -print 2>/dev/null || true" +run_shell_capture clawdie-iso-assets "find /usr/local/share/clawdie-iso -maxdepth 4 -type f -ls 2>/dev/null || true; for f in /usr/local/share/clawdie-iso/build-manifest.json; do [ -e \"\$f\" ] || continue; echo \"===== \$f =====\"; cat \"\$f\"; echo; done" +run_shell_capture colibri-service-state "service colibri_daemon status 2>&1 || true; egrep -n '^(command|command_args|procname)=' /usr/local/etc/rc.d/colibri_daemon 2>/dev/null || true; sysrc -n colibri_daemon_enable 2>/dev/null || true" if [ -f /home/clawdie/.Xauthority ]; then run_shell_if_present xinput xinput-list "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority xinput list 2>/dev/null || true" run_shell_if_present xinput xinput-list-props "DISPLAY=:0 XAUTHORITY=/home/clawdie/.Xauthority sh -c 'for id in \$(xinput list --id-only 2>/dev/null); do echo \"===== device \$id =====\"; xinput list-props \"\$id\"; echo; done' || true" diff --git a/live/operator-session/panel-skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml b/live/operator-session/panel-skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml index 1c021c5..f72b289 100644 --- a/live/operator-session/panel-skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml +++ b/live/operator-session/panel-skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-panel.xml @@ -23,8 +23,10 @@ - + @@ -35,7 +37,6 @@ - @@ -44,7 +45,7 @@ - + @@ -91,10 +92,6 @@ - - - - diff --git a/runner/README.md b/runner/README.md index 50340bd..e72b60a 100644 --- a/runner/README.md +++ b/runner/README.md @@ -42,24 +42,24 @@ cd /home/clawdie/clawdie-iso && sudo ./build.sh && sudo ./scripts/publish.sh ## Future: Forgejo Actions (push-triggered CI/CD) When the ISO build is stable and you want push-triggered rebuilds, add a -self-hosted Forgejo runner on the controlplane. Codeberg runs Forgejo — no -new account needed. +self-hosted Forgejo runner on the controlplane. `code.smilepowered.org` is the +source of truth; Codeberg is only the public mirror. ### Install runner ```sh pkg install forgejo-runner -# or fetch binary from codeberg.org/forgejo/runner/releases +# or fetch binary from the upstream Forgejo runner releases ``` ### Register -1. Codeberg → `Clawdie/Clawdie-ISO` → Settings → Actions → Runners → Create Runner → copy token +1. Forgejo → `clawdie/clawdie-iso` → Settings → Actions → Runners → Create Runner → copy token 2. Run: ```sh forgejo-runner register \ - --url https://codeberg.org \ + --url https://code.smilepowered.org \ --token \ --name clawdie-build \ --labels freebsd \ diff --git a/scripts/build-and-log.sh b/scripts/build-and-log.sh index dc529e6..7bf7347 100755 --- a/scripts/build-and-log.sh +++ b/scripts/build-and-log.sh @@ -146,7 +146,7 @@ cat > "${HTML_LATEST}" << HTMLEOF Clawdie. diff --git a/scripts/stage-colibri-iso.sh b/scripts/stage-colibri-iso.sh index 3839259..e0f5d86 100755 --- a/scripts/stage-colibri-iso.sh +++ b/scripts/stage-colibri-iso.sh @@ -20,7 +20,7 @@ SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) REPO_ROOT=$(CDPATH= cd -- "${SCRIPT_DIR}/.." && pwd) COLIBRI_REPO=${COLIBRI_REPO:-"${REPO_ROOT}/../colibri"} COLIBRI_ARTIFACT_DIR=${COLIBRI_ARTIFACT_DIR:-"${COLIBRI_REPO}/target/release"} -COLIBRI_STAGE_ENABLE=${COLIBRI_STAGE_ENABLE:-YES} +COLIBRI_STAGE_ENABLE=${COLIBRI_STAGE_ENABLE:-NO} COLIBRI_STAGE_INCLUDE_TUI=${COLIBRI_STAGE_INCLUDE_TUI:-1} COLIBRI_COST_MODE=${COLIBRI_COST_MODE:-smart} @@ -30,7 +30,9 @@ ETC_DIR="${DESTDIR}/usr/local/etc/colibri" DB_DIR="${DESTDIR}/var/db/colibri" RUN_DIR="${DESTDIR}/var/run/colibri" LOG_DIR="${DESTDIR}/var/log/colibri" +NEWSYSLOG_DIR="${DESTDIR}/usr/local/etc/newsyslog.conf.d" RC_SOURCE="${COLIBRI_REPO}/packaging/freebsd/colibri_daemon.in" +NEWSYSLOG_SOURCE="${COLIBRI_REPO}/packaging/freebsd/newsyslog-colibri.conf" require_file() { if [ ! -f "$1" ]; then @@ -53,7 +55,8 @@ copy_bin() { } require_file "${RC_SOURCE}" -mkdir -p "${BIN_DIR}" "${RC_DIR}" "${ETC_DIR}" "${DB_DIR}" "${RUN_DIR}" "${LOG_DIR}" +require_file "${NEWSYSLOG_SOURCE}" +mkdir -p "${BIN_DIR}" "${RC_DIR}" "${ETC_DIR}" "${NEWSYSLOG_DIR}" "${DB_DIR}" "${RUN_DIR}" "${LOG_DIR}" copy_bin colibri-daemon copy_bin colibri @@ -64,6 +67,15 @@ if [ "${COLIBRI_STAGE_INCLUDE_TUI}" != "0" ] && [ -x "${COLIBRI_ARTIFACT_DIR}/co fi install -m 0555 "${RC_SOURCE}" "${RC_DIR}/colibri_daemon" +install -m 0644 "${NEWSYSLOG_SOURCE}" "${NEWSYSLOG_DIR}/colibri.conf" + +if ! grep -q '^command="/usr/sbin/daemon"' "${RC_DIR}/colibri_daemon" || \ + ! grep -q '^procname="/usr/sbin/daemon"' "${RC_DIR}/colibri_daemon" || \ + ! grep -q -- '-o .*colibri_daemon_program' "${RC_DIR}/colibri_daemon"; then + echo "ERROR: staged colibri_daemon rc.d script does not supervise colibri-daemon with daemon(8)" >&2 + echo " Update COLIBRI_REPO (${COLIBRI_REPO}) before building; the live USB must not block boot in rc.d." >&2 + exit 66 +fi cat > "${ETC_DIR}/rc.conf.sample" < "${ETC_DIR}/README.iso" <<'EOF' Colibri ISO staging notes ========================= -The ISO build creates the colibri user/group and enables the rc.d service -according to build.cfg. Runtime validation: +The ISO build creates the colibri user/group and stages the rc.d service. +Current operator USB builds keep the daemon disabled at boot unless explicitly +overridden in build.cfg, so Colibri cannot block SDDM/XFCE startup. Runtime +validation: service colibri_daemon start colibri status diff --git a/scripts/write-artifact-manifest.sh b/scripts/write-artifact-manifest.sh index e2a6948..b439a26 100755 --- a/scripts/write-artifact-manifest.sh +++ b/scripts/write-artifact-manifest.sh @@ -140,8 +140,16 @@ _gz_size="$(file_size "${_gz}")" _branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)" _commit="$(git rev-parse --short HEAD 2>/dev/null || echo unknown)" +_repo_dirty="null" +if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null; then + _repo_dirty="false" +elif git rev-parse --git-dir >/dev/null 2>&1; then + _repo_dirty="true" +fi _host="$(hostname 2>/dev/null || echo unknown)" _written_at="$(date -u '+%Y-%m-%dT%H:%M:%SZ')" +_run_stamp="$(date -u '+%Y%m%dT%H%M%SZ')" +_run_id="${_run_stamp}-${_stem##*/}" _freebsd="$(freebsd-version -kru 2>/dev/null | tr '\n' ' ' | sed 's/[[:space:]]*$//')" _builder="${BUILT_BY:-Codex ISO Builder}" _build_command="${BUILD_COMMAND:-unknown}" @@ -159,11 +167,20 @@ fi _tmp="${_manifest}.tmp.$$" cat > "${_tmp}" < "${_tmp}" <.json +tmp/colibri/iso-flash/latest.json +``` + +Schema: `clawdie.iso.flash.v1`. See `docs/ISO-MANIFESTS.md`. + +## 1. Select the publish manifest + +Set one of these: + +```sh +MANIFEST_URL="https://osa.smilepowered.org/downloads/iso/.manifest.json" +``` + +or: + +```sh +MANIFEST_PATH="tmp/output/.manifest.json" +``` + +## 2. Download artifacts + +For a URL-based handoff: + +```sh +mkdir -p tmp/flash-downloads +curl -fL -o tmp/flash-downloads/publish.manifest.json "$MANIFEST_URL" +``` + +Read the manifest and download the `image_url` and `sha256_url` it names. If +`jq` is available: + +```sh +IMAGE_URL="$(jq -r .image_url tmp/flash-downloads/publish.manifest.json)" +SHA_URL="$(jq -r .sha256_url tmp/flash-downloads/publish.manifest.json)" +curl -fL -O --output-dir tmp/flash-downloads "$IMAGE_URL" +curl -fL -O --output-dir tmp/flash-downloads "$SHA_URL" +``` + +## 3. Verify checksum and gzip integrity + +```sh +cd tmp/flash-downloads +sha256sum -c "$(basename "$SHA_URL")" +gzip -t "$(basename "$IMAGE_URL")" +cd - +``` + +If the checksum file is in FreeBSD `sha256(1)` format, compare manually: + +```sh +sha256sum tmp/flash-downloads/*.img.gz +cat tmp/flash-downloads/*.img.gz.sha256 +``` + +## 4. Identify the whole-disk target + +On Linux: + +```sh +lsblk -o NAME,TYPE,SIZE,MODEL,SERIAL,TRAN,RM,MOUNTPOINTS +``` + +Unmount any mounted partitions from the selected removable disk. Confirm the +whole-disk path with the operator before writing. + +## 5. Flash + +Example for Linux, replacing `/dev/sdX` with the confirmed whole disk: + +```sh +gzip -dc tmp/flash-downloads/.img.gz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync +sync +``` + +## 6. Emit flash manifest + +Record pass/fail checks, the artifact URLs, selected target disk facts, flash +command summary, and completion time in `clawdie.iso.flash.v1`. Print the +manifest path and a one-line summary for Colibri ingestion. diff --git a/skills/iso-hardware-report-ingest/SKILL.md b/skills/iso-hardware-report-ingest/SKILL.md new file mode 100644 index 0000000..e6d78f1 --- /dev/null +++ b/skills/iso-hardware-report-ingest/SKILL.md @@ -0,0 +1,72 @@ +--- +name: iso-hardware-report-ingest +description: Ingest real-machine live USB hw-report evidence into a structured Colibri hardware manifest without treating static inspection as hardware proof. +--- + +# iso-hardware-report-ingest + +Use this skill after the operator or Codex ISO Builder collects live USB evidence +from real hardware. It produces a `clawdie.iso.hardware.v1` manifest for Colibri +and dashboard consumers. + +## Manifest output + +Write the result to: + +```sh +tmp/colibri/iso-hardware/.json +tmp/colibri/iso-hardware/latest.json +``` + +Schema: `clawdie.iso.hardware.v1`. See `docs/ISO-MANIFESTS.md`. + +## Inputs to collect from the live USB + +Prefer files copied from the live session over paraphrased observations: + +```sh +hw-report > /tmp/clawdie-hw-report.txt +pciconf -lv > /tmp/clawdie-pciconf-lv.txt +ifconfig -a > /tmp/clawdie-ifconfig-a.txt +cat /var/log/clawdie-live-gpu.log > /tmp/clawdie-live-gpu.log +``` + +When debugging GUI/input/audio issues, also collect the relevant exact command +output named in `PLAN-OPERATOR-USB-NEXT.md`, for example: + +```sh +xinput list +xfconf-query -c pointers -lv +cat /dev/sndstat +sysctl hw.snd.default_unit +mixer +``` + +If `hw-probe` upload is intentionally run, record only the public probe URL in +the manifest. Do not upload private operator data without approval. + +## Ingest checklist + +Record these as manifest checks or evidence fields: + +- machine vendor/model and firmware version when available +- CPU model +- GPU PCI IDs, selected KMS module, and reason from `clawdie-live-gpu.log` +- GL renderer if collected +- SDDM login result and XFCE session result +- internal display and external display behavior if tested +- touchpad, keyboard, webcam, audio, Wi-Fi, and USB Ethernet observations +- Tailscale status if it was part of the test +- no-blank/power behavior observed during the session +- image filename or commit shown by the live build manifest + +## Finish + +Write a concise summary such as: + +```text +AMD ASUS UX325UA: pass for SDDM/XFCE/AMD KMS/USB Ethernet/webcam; touchpad needs follow-up. +``` + +Attach paths to raw captured files under `logs` or `outputs`. Keep the manifest +small enough for Colibri to ingest directly. diff --git a/skills/iso-package-audit/SKILL.md b/skills/iso-package-audit/SKILL.md new file mode 100644 index 0000000..f069852 --- /dev/null +++ b/skills/iso-package-audit/SKILL.md @@ -0,0 +1,80 @@ +--- +name: iso-package-audit +description: Categorize operator USB package-list entries, capture package size/flat-size evidence on FreeBSD, and emit a Colibri package-audit manifest. +--- + +# iso-package-audit + +Use this skill for Track B package-list hygiene. It classifies package-list +entries and records size evidence before any removal is proposed. Do not remove +packages during the audit commit. + +## Manifest output + +Write the result to: + +```sh +tmp/colibri/iso-package-audit/.json +tmp/colibri/iso-package-audit/latest.json +``` + +Schema: `clawdie.iso.package-audit.v1`. See `docs/ISO-MANIFESTS.md`. + +## Categories + +Use exactly one primary category per package: + +- `boot-critical` — kernel/firmware/X/SDDM/network/power pieces needed for the + live USB to boot and present a usable session. +- `operator-workflow` — tools the operator intentionally uses from the live USB, + such as browser, CLIs, terminal/editor, or remote access. +- `diagnostic` — hardware/debug/reporting tools such as `btop`, `hw-probe`, + `dmidecode`, or graphics/audio diagnostics. +- `candidate-to-defer` — rarely used or replaceable packages that may be removed + later after build/hardware evidence supports it. + +## FreeBSD evidence commands + +Run on the FreeBSD build host with the target package branch configured. Fetch +before reporting repo state: + +```sh +git fetch origin +git status --short --branch +git rev-parse --short HEAD +``` + +For installed packages on a mounted image or host package DB: + +```sh +pkg info -s +pkg info -f | egrep '^(Name|Version|Installed size|Flat size)' +``` + +For packages present only in the offline repo, inspect package metadata from the +archive under `tmp/packages` and record the exact command used. + +## Audit output expectations + +For each package-list entry, record: + +- package name +- package-list file path and line number when practical +- category +- package archive size and flat/installed size +- reason kept +- deferral risk if categorized as `candidate-to-defer` +- evidence command or metadata source + +If editing a package list, add comments only. Do not remove packages in the same +change as the first audit pass. + +## Finish + +Write the `clawdie.iso.package-audit.v1` manifest and a concise human summary +with totals per category and total size by category. If markdown package-list +comments were edited, run: + +```sh +./scripts/check-format.sh +``` diff --git a/skills/iso-publish/SKILL.md b/skills/iso-publish/SKILL.md index de8d205..7803370 100644 --- a/skills/iso-publish/SKILL.md +++ b/skills/iso-publish/SKILL.md @@ -18,6 +18,14 @@ public download target. - Public webroot: `/usr/local/www/osa/downloads/iso` - Public base URL: `https://osa.smilepowered.org/downloads/iso` +## Manifest contract + +`scripts/write-artifact-manifest.sh` writes the canonical +`clawdie.iso.publish.v1` manifest beside the image as +`tmp/output/.manifest.json`. Hermes consumes that file for +`iso-flash-verify`; Colibri can ingest it directly. See +`docs/ISO-MANIFESTS.md` for shared fields and handoff rules. + ## Preconditions Run from the repo root on the FreeBSD host. Use one command at a time. diff --git a/skills/iso-validate-image/SKILL.md b/skills/iso-validate-image/SKILL.md new file mode 100644 index 0000000..ec88251 --- /dev/null +++ b/skills/iso-validate-image/SKILL.md @@ -0,0 +1,80 @@ +--- +name: iso-validate-image +description: Inspect a freshly built Clawdie operator USB image or mounted root to validate static runtime contracts and emit a Colibri validation manifest. +--- + +# iso-validate-image + +Use this skill on the FreeBSD build host after an image exists and the operator +has assigned mounted-image validation. This is static validation only; it does +not replace real hardware proof that SDDM/XFCE/input/audio work. + +## Manifest output + +Write the result to: + +```sh +tmp/colibri/iso-validation/.json +tmp/colibri/iso-validation/latest.json +``` + +Schema: `clawdie.iso.validation.v1`. See `docs/ISO-MANIFESTS.md`. + +## Preconditions + +Run from the repo root on FreeBSD. Fetch before reporting repo state: + +```sh +git fetch origin +git status --short --branch +git rev-parse --short HEAD +ls -lh tmp/output +``` + +If an image is already mounted under `tmp/cache/mnt`, inspect it cautiously. If +mount state is stale or unclear, use `iso-build-cleanup` before retrying. + +## Validation checklist + +Record each item as a named check in the manifest: + +- `/etc/rc.conf` enables `sddm`. +- `/etc/rc.conf` enables `clawdie_live_gpu`. +- `/etc/rc.conf` enables `powerdxx` and the expected no-blank power/session + policy files are present. +- `/usr/local/bin/mdo` exists and is executable; `sudo` is not required by live + operator-facing paths. +- Operator CLIs expected by the current plan are present (`pi`, `codex`, and any + intentionally retained package-list CLIs). +- `/usr/local/share/clawdie-iso/build-manifest.json` exists inside the image. +- `CLAWDIESEED` slice 3 exists when inspecting the full disk image. +- `clawdie-live-gpu` and hardware report scripts are present and executable. +- Intel and AMD KMS modules/firmware expected by the package lists are present; + NVIDIA packages are staged/offline but not forced to load by default. +- XFCE panel/session assets referenced by the live session are present. +- Colibri binaries and `colibri_daemon` rc.d script are present when + `FEATURE_COLIBRI=YES` was used. + +## Suggested inspection commands + +Use exact device names from `mdconfig`/`gpart` on the build host; do not paste +these blindly if another build is active. + +```sh +IMG="tmp/output/.img" +md=$(mdconfig -a -t vnode -f "$IMG") +gpart show -p "/dev/$md" +``` + +Mount the root partition read-only when possible, then inspect files under the +mountpoint. Clean up the md device before finishing. + +## Finish + +Write a `clawdie.iso.validation.v1` manifest with: + +- image path and checksum/manifest inputs when available +- mount devices and mountpoint used +- pass/fail status for each checklist item +- cleanup status for unmounts and `mdconfig -d` +- an explicit limitation note: mounted validation is not graphical hardware proof