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