Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 239 lines 9.0 kB view raw view rendered
1# FedAC Native Score 2 3`fedac/native` ships a USB-bootable kernel image with embedded initramfs and pieces. 4 5## Definition Of Shipped 6 7All of the following must be true: 8 91. `build/vmlinuz` is rebuilt from current `HEAD`. 102. Release is uploaded to CDN (`upload-release.sh`). 113. CDN metadata and hash verify. 124. Running devices can detect the new version and enter update flow. 135. At least one target medium (USB/internal EFI) is flashed and readback-verified. 14 15## Release Procedure 16 17### Default path: remote OTA via oven (preferred) 18 19OTAs are built remotely on `oven.aesthetic.computer`. After landing 20fedac/native/ changes on `origin/main`, the oven git poller auto-triggers 21a build — but you can also trigger and observe explicitly: 22 23```bash 24ac-os oven # Trigger remote OTA build for HEAD (or push to main) 25ac-os oven status # Show oven build queue + last builds 26ac-os oven watch # Tail logs for the active oven build (SSE) 27ac-os oven cancel # Cancel the active oven job 28``` 29 30**This is the path agents should use.** Do NOT run `ac-os upload` to ship an 31OTA — that is the legacy local-build-and-push path; it requires a clean tree 32and has historically clobbered uncommitted work via auto-stash. The oven 33flow is the source of truth for `releases.aesthetic.computer/os/`. 34 35### Local commands (rarely needed) 36 37```bash 38ac-os build # Build binary + initramfs + kernel locally 39ac-os flash # Build + flash USB 40ac-os upload # Local-build + push to OTA CDN (NOT for routine OTAs — use `ac-os oven`) 41ac-os flash+upload # Build + flash + upload 42``` 43 44`ac-os` is the preferred path for real devices. It layers user-local credentials 45and repo context into the initramfs on top of the base image: 46 47- Claude OAuth state, when present locally 48- GitHub PAT, when `gh auth token` succeeds 49- Tangled SSH identity, when `ssh -G knot.aesthetic.computer` resolves a local key 50 51### Manual steps 52 53```bash 54cd fedac/native 55 56# 1) Build image 57bash scripts/build-and-flash.sh --skip-binary 58sha256sum build/vmlinuz 59 60# 2) Publish CDN release (updates latest.version/latest.sha256/releases.json) 61bash scripts/upload-release.sh build/vmlinuz 62 63# 3) Verify CDN state 64curl -fsSL https://releases.aesthetic.computer/os/native-notepat-latest.version 65curl -fsSL https://releases.aesthetic.computer/os/native-notepat-latest.sha256 66curl -fsSL https://releases.aesthetic.computer/os/releases.json | jq '.latest' 67``` 68 69## Credentials & Secrets 70 71- **DO Spaces (OTA upload)**: `aesthetic-computer-vault/fedac/native/upload.env.gpg` 72 - GPG-encrypted with Jeffrey's key (`77E1473C0FF13AB2`) 73 - Decrypt: `gpg --decrypt aesthetic-computer-vault/fedac/native/upload.env.gpg > /tmp/upload.env` 74 - Contains: `DO_SPACES_KEY`, `DO_SPACES_SECRET` 75- **GPG private key**: `.tmp-key-jeffrey-private.asc` (in repo root, gitignored) 76- **Handle colors API**: `https://aesthetic.computer/.netlify/functions/handle-colors` (public, no auth) 77 78## Device Repo Access 79 80- The on-device working tree lives at `/mnt/ac-repo`. 81- On WiFi connect, AC Native clones or pulls from the public GitHub HTTPS mirror: 82 - `https://github.com/whistlegraph/aesthetic-computer.git` 83- If a Tangled SSH key was baked at build time, the repo is also configured so: 84 - `origin` fetches from GitHub 85 - `origin` push mirrors to `git@knot.aesthetic.computer:aesthetic.computer/core` 86 - `origin` also pushes to the GitHub mirror 87 - `tangled` points directly at the knot remote 88- If no Tangled key is baked, the repo stays GitHub-only for pushes. 89 90## Update Signal Expectations 91 92- Native notepat checks `native-notepat-latest.version` on WiFi connect and periodic background checks. 93- When remote version differs from local `system.version`, UI shows update availability and emits audible notification. 94- Download+flash uses: 95 - `system.fetchBinary(...)` -> `/tmp/vmlinuz.new` 96 - `system.flashUpdate(...)` -> boot EFI partition 97 - `system.reboot()` after successful flash 98 99## USB Flash Methods 100 101### Method 1: build-and-flash.sh (full pipeline) 102 103Builds binary, packs initramfs, compiles kernel, partitions + flashes USB. 104 105```bash 106cd fedac/native 107bash scripts/build-and-flash.sh --flash /dev/sdX 108# Options: --skip-kernel (reuse existing vmlinuz), --skip-binary (reuse ac-native) 109``` 110 111Requires privileged access to block devices. In devcontainer, `sfdisk`/`mkfs` may lack permissions. 112 113### Method 2: Docker privileged container (from devcontainer) 114 115When the devcontainer can't directly access block devices, use the Docker host: 116 117```bash 118# 1. Build binary and initramfs inside devcontainer 119cd fedac/native 120make CC=gcc # builds build/ac-native 121bash scripts/build-and-flash.sh --skip-kernel --skip-binary # rebuilds initramfs only 122 123# 2. Rebuild kernel to embed new initramfs (uses cached objects, fast) 124cd build/linux-6.14.2 125make -j$(nproc) bzImage 126cp arch/x86/boot/bzImage ../vmlinuz 127 128# 3. Flash via privileged Docker container (host path: /home/me/aesthetic-computer) 129sudo docker run --rm --privileged \ 130 -v /home/me/aesthetic-computer/fedac/native/build:/build:ro \ 131 -v /dev:/dev \ 132 fedora:41 bash -c ' 133 dnf install -y -q dosfstools util-linux 134 DISK=/dev/sdX 135 umount ${DISK}1 2>/dev/null || true 136 sfdisk --force $DISK <<EOF 137label: gpt 138type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, size=512M 139EOF 140 sleep 1 141 mkfs.vfat -F 32 -n ACBOOT ${DISK}1 142 mkdir -p /mnt/efi && mount ${DISK}1 /mnt/efi 143 mkdir -p /mnt/efi/EFI/BOOT 144 cp /build/vmlinuz /mnt/efi/EFI/BOOT/BOOTX64.EFI 145 sync && sleep 1 && sync 146 sha256sum /mnt/efi/EFI/BOOT/BOOTX64.EFI /build/vmlinuz 147 umount /mnt/efi 148' 149``` 150 151**Key detail**: devcontainer workspace is at `/workspaces/aesthetic-computer` but the host path is `/home/me/aesthetic-computer`. Docker bind mounts must use the host path. 152 153### Method 3: Reflash existing USB (no repartition) 154 155If USB already has an EFI partition, skip partitioning: 156 157```bash 158sudo docker run --rm --privileged \ 159 -v /home/me/aesthetic-computer/fedac/native/build:/build:ro \ 160 -v /dev:/dev \ 161 fedora:41 bash -c ' 162 dnf install -y -q dosfstools 163 mount /dev/sdX1 /mnt 164 cp /build/vmlinuz /mnt/EFI/BOOT/BOOTX64.EFI 165 sync && sleep 1 && sync 166 sha256sum /mnt/EFI/BOOT/BOOTX64.EFI /build/vmlinuz 167 umount /mnt 168' 169``` 170 171### Verification 172 173Always verify SHA256 match between source vmlinuz and flashed BOOTX64.EFI: 174 175```bash 176sha256sum build/vmlinuz # local 177# Must match the sha256sum printed inside the docker container 178``` 179 180### Device node creation 181 182If `lsblk` shows the USB but `/dev/sdX` doesn't exist in the devcontainer: 183 184```bash 185sudo mknod /dev/sda b 8 0 186sudo mknod /dev/sda1 b 8 1 187``` 188 189## OTA Update Hardening (2026-03-11) 190 191Critical fixes applied to the OTA flash path: 192 1931. **posix_fadvise instead of drop_caches**: `drop_caches=3` was destroying tmpfs-backed source file pages. Now uses `POSIX_FADV_DONTNEED` on only the destination file. 1942. **Fresh mount for flash**: Always mounts EFI partition at `/tmp/efi` instead of reusing `/mnt` (which may lack `EFI/BOOT/`). 1953. **EFI directory validation**: Aborts flash if `EFI/BOOT/` not found on mounted partition. 1964. **Source file pre-flight**: Validates source exists and is >1MB before copying. 1975. **Double sync with delay**: `syncfs` + `sync` + 500ms sleep + `sync` before verify and before reboot, giving vfat write-back time to flush. 1986. **Error logging**: syncfs failures, mount failures, and device detection logged with errno. 199 200## Next Features 201 202- **Multitouch input**: Track touch slots in `input.c` (MT protocol B), 203 expose multiple simultaneous touch points to JS pieces via `act({ event })`. 204 Enables chord playing in notepat and multi-finger gestures on 2-in-1 devices. 205- **Firmware blobs**: Add Realtek (RTW88/RTW89), MediaTek (MT7921/MT7925), 206 and Intel SOF audio firmware to initramfs for runtime driver loading. 207- **@sat hardware validation**: Get `lspci -nn` dump from ARDOR NEO G15 208 to confirm WiFi chip and audio codec, then add matching firmware. 209 210## Architecture 211 212See [internals.md](internals.md) for the full boot sequence and system architecture narrative. 213 214## Operational Checks 215 216- USB logs must be checked on every release candidate: 217 - `ac-native.log` for `[fetch]`, `[fetchBinary]`, `[flash]`, `[verify]`, `[mic]`, `[sample]` 218 - `ac-audio.log` for ALSA/capture diagnostics 219- Any `curl exit=77` or cert-path errors are a release blocker. 220- Any repeated mic open/close race errors are a release blocker. 221- Flash verify must report `OK: N bytes match` — any `MISMATCH` is a release blocker. 222 223## Commits from the Device 224 225When a commit is made directly from a running AC native device (via Claude Code on-device): 226 227- **Prefix**: `[ac-native]` at the start of the commit subject line 228- **Body**: Include `Committed from AC native device.` as the last line 229 230Example: 231``` 232[ac-native] enable CONFIG_TYPEC, UCSI, UCSI_ACPI for USB-C power role swap 233 234Adds USB Type-C connector class support. 235 236Committed from AC native device. 237``` 238 239This distinguishes on-device commits from dev-machine commits in git log.