sunfish-a16-rom — Spec Kit project dump for external review Generated: 2026-08-09T11:09:19+02:00 Path: /home/aventura/Workspaces/sunfish-a16-rom Spec Kit CLI: specify 0.16.1 │ ================================================================================ DIRECTORY TREE (project-owned; runtime .cursor/.specify scripts omitted) ================================================================================ ./ AGENTS.md docs/ docs/README.md .gitignore README.md .specify/ .specify/.gitignore .specify/init-options.json .specify/integration.json .specify/memory/ .specify/memory/constitution.md .specify/memory/.constitution-template.json specs/ specs/001-development-environment/ specs/001-development-environment/spec.md specs/002-axp-reference-capture/ specs/002-axp-reference-capture/spec.md specs/003-lineage-23-vanilla-build/ specs/003-lineage-23-vanilla-build/spec.md specs/README.md ================================================================================ FILE CONTENTS ================================================================================ -------------------------------------------------------------------------------- FILE: README.md -------------------------------------------------------------------------------- # sunfish-a16-rom Personal LineageOS 23.2 / Android 16 custom ROM project for Google Pixel 4a (`sunfish`). This repository is the Spec Kit / documentation home for the project. It is **not** a SSYSTEMS / buildout-saar project. ## Staging note Until `rom-dev01` and Gitea exist, this path is the laptop bootstrap workspace: `/home/aventura/Workspaces/sunfish-a16-rom` Canonical development later moves to Gitea repositories and working trees on `rom-dev01`. The laptop remains Cursor Remote SSH + adb/fastboot. ## Quick links - Constitution: `.specify/memory/constitution.md` - Agent rules: `AGENTS.md` - Specs: `specs/README.md` - Scope notes: `docs/README.md` ## Spec Kit Upstream Spec Kit (`specify` CLI) with Cursor integration. Do not install SSYSTEMS `ops-salt` / company constitutions into this tree. -------------------------------------------------------------------------------- FILE: AGENTS.md -------------------------------------------------------------------------------- # AGENTS.md — sunfish-a16-rom How agents must work in **this** repository. Global project rules live in `.specify/memory/constitution.md`. Per-feature requirements live in `specs/*/spec.md`. Do not duplicate those documents here. ## Scope - This project is **independent of SSYSTEMS**. - Do **not** apply SSYSTEMS `AGENTS.md`, Redmine, `r{ticket}_*` branches, company GitLab/MR workflows, or company Spec Kit conventions. - Do **not** modify PVE / `pm-test01` / company Salt infrastructure from this repository. `rom-dev01` is assumed to already exist when host work begins. ## Sources of truth 1. **Constitution** (`.specify/memory/constitution.md`) — global project rules. 2. **Feature `spec.md`** — requirements for the active feature. 3. Upstream / primary sources for LineageOS/AOSP, GrapheneOS, AXP.OS, DivestOS, KernelSU, microG, and related projects — prefer these over secondary blogs or guesses. ## Working rules - Do not invent unresolved technical decisions; investigate them in the relevant feature spec (or create/clarify that spec first). - Prefer small, attributable, reversible changes. - Never commit secrets, private keys, proprietary Google APKs, phone dumps with credentials/identifiers, `.repo`, `out/`, or ccache. - Large Android trees and builds belong on `rom-dev01`, not on the laptop. - Keep commits and patches source-attributed; do not dump opaque megapatches. ## Spec Kit workflow Typical order: `/speckit-specify` → `/speckit-plan` → `/speckit-tasks` → implement. Regenerate plan/tasks after meaningful `spec.md` edits. -------------------------------------------------------------------------------- FILE: .gitignore -------------------------------------------------------------------------------- # sunfish-a16-rom ## Git .DS_Store *.swp *~ .idea/ .vscode/ # Spec Kit local state (also ignored under .specify/) .specify/feature.json # Secrets / keys *.jks *.keystore *.pk8 *.x509.pem **/release-keys/ **/signing-keys/ **/*private* # Proprietary / device captures (store on rom-dev01, not Git) **/*.apk **/*.apkm **/*.xapk **/phonesky* **/Phonesky* **/bugreport* **/reference/raw/ # Android build trees (must live on rom-dev01) .repo/ out/ ccache/ /.ccache/ # Local env .env .env.* -------------------------------------------------------------------------------- FILE: .specify/init-options.json -------------------------------------------------------------------------------- { "ai": "cursor-agent", "ai_skills": true, "feature_numbering": "sequential", "here": true, "integration": "cursor-agent", "script": "sh", "speckit_version": "0.16.1" } -------------------------------------------------------------------------------- FILE: .specify/memory/constitution.md -------------------------------------------------------------------------------- # sunfish-a16-rom Constitution Project: Android 16 custom ROM for Google Pixel 4a (`sunfish`). This project builds a maintainable custom ROM based on LineageOS 23.2 / Android 16 for sunfish. The primary goal is functionality and application compatibility first, followed by security/privacy hardening. The project must remain debuggable and reproducible throughout development. This constitution is specific to `sunfish-a16-rom`. It does **not** inherit SSYSTEMS, company GitLab, Redmine, or buildout-saar governance. **Version**: 0.1.0 | **Ratified**: 2026-08-09 | **Last Amended**: 2026-08-09 ## Core Principles ### I. Independence from SSYSTEMS governance This is a personal project. Code, Spec Kit, documentation, Git hosting, and workflow are owned by this project. Do not apply SSYSTEMS `AGENTS.md`, Redmine tickets, `r{ticket}_*` branch rules, mandatory company MRs, production-read-only company policy, client conventions, company GitLab, or corporate CI unless an explicit later decision says otherwise. `pm-test01` (or any company hypervisor) may host `rom-dev01` with permission. That is infrastructure only. It is **not** part of this project's logical architecture or governance. ### II. Spec-as-source For each feature, `specs/NNN-*/spec.md` is the only human-edited requirements source. `plan.md` and `tasks.md` are derived artifacts and must be regenerated after meaningful spec changes (`/speckit-plan`, `/speckit-tasks`). Unresolved technical decisions must be investigated in the relevant feature spec. Do not invent implementation details in the constitution, commits, or agent improvisation. ### III. Functionality first, hardening second Compatibility with the known-good AXP.OS 22 workflow on this sunfish device is the MVP gate. Hardening must not knowingly break that baseline without the regression being isolated, documented, and reversible. ### IV. Small, attributable, reversible changes Prefer minimal patches with clear upstream attribution. Never change several high-risk subsystems at once when the result cannot be attributed to one change. Keep a known-good flashable build for each completed stage. ### V. Prefer native, auditable ROM functionality Prefer ROM-native features over LSPosed, Zygisk, or root modules when a feature can reasonably be implemented in the ROM. Do not make unrestricted signature spoofing a general platform capability. ## Core architecture - **Base ROM**: LineageOS 23.2 / Android 16 for sunfish. - **Base kernel / device stack**: the stack compatible with that LineageOS 23.2 sunfish build. - Do **not** substitute an old GrapheneOS, stock Android 13, or unrelated prebuilt kernel image. - Port applicable historical GrapheneOS sunfish kernel hardening into the current kernel where still relevant. - Port applicable security/privacy patches from AXP.OS and DivestOS. - Use modern GrapheneOS Android 16 implementations as the preferred reference for framework-level hardening where they can be cleanly adapted. - Use AXP.OS as the principal compatibility reference (microG, patched Phonesky/Google Play, signature spoofing, call recording, privacy behaviour). - Use msg-GrapheneOS only as a reference for concepts such as KernelSU/SukiSU integration, SUSFS, root-on-boot modes, signing, and OTA design. ### Reference source order | Role | Source | |------|--------| | Base | LineageOS 23.2 | | Compatibility / privacy behaviour | AXP.OS | | Modern + historical sunfish hardening | GrapheneOS | | Upstream/historical patches behind AXP | DivestOS | DivestOS is a recognised reference, not a fourth ROM base. ## Compatibility baseline The current working AXP.OS 22 installation on this sunfish device is the compatibility baseline. The new ROM must reproduce at minimum: - working microG; - working patched Google Play / Phonesky; - working push notifications; - Insular managed profile; - Yuh working inside Insular; - Swissquote working inside Insular; - application installation and updates through patched Google Play; - banking applications running without root privileges. **Yuh** and **Swissquote** inside Insular are hard-gates of the compatibility MVP. **N26** and **Revolut** are later optional targets and must not block the MVP. Exact package versions, signatures, Magisk/DenyList state, UIDs, and related inventory belong in `002-axp-reference-capture`. Do not invent those values here. ## Google compatibility stack Expected package architecture: - `com.google.android.gms` = microG Services Core - `com.google.android.gsf` = GSF Proxy - `com.android.vending` = patched Google Play / Phonesky Do not install FakeStore or microG Companion if it conflicts with the real patched `com.android.vending`. Patched Phonesky must be integrated as a privileged system application with the required permission / default-permission XML configuration. Signature spoofing must be native, restricted to explicitly authorized packages/signers, and auditable. It must not depend on LSPosed. microG and patched Phonesky must continue working when optional root/Zygisk-style functionality is unavailable. Phonesky is an external/proprietary input. Do not commit Google proprietary APKs to Git. `004-microg-phonesky-integration` defines the reproducible obtain → patch → sign → priv-app procedure. Phonesky signing strategy must be decided before shipping an updatable Play Store build. Concrete spoofing implementation is decided in `005-restricted-signature-spoofing` after studying LineageOS 23.2, microG, and AXP. Prefer package/signer-restricted support over an open generic fake-signature permission. ## Banking / Insular workflow Preserve the known-good AXP workflow as the initial compatibility test: 1. Download the banking application without opening it. 2. Ensure the application receives no root and an appropriate clean/unmounted environment. 3. Clone/install it into the Insular work profile. 4. First launch occurs inside Insular. 5. Patched Google Play is also available inside Insular. 6. If the banking app requires a Play Store update, perform that update from inside the work profile. 7. Re-test login, biometrics, push, confirmations, and reboot behaviour. Insular should initially remain an ordinary user application for easier testing and upgrades. It may later become a normal preinstalled system app, but not a privileged app unless a concrete audited requirement exists. Managed Mainland must remain optional and disabled by default. microG, GSF Proxy, and patched Phonesky should eventually be automatically available in managed profiles. ## Root architecture Use KernelSU-Next as the initial root implementation. sunfish uses a non-GKI Linux 4.14 kernel; KernelSU must be integrated into the exact kernel built with the ROM. Required properties: - root is explicitly granted only to approved applications; - banking applications never receive root; - module mounts can be removed from selected application processes; - required `path_umount()` support/backport for the old kernel must be verified; - managed-profile UIDs must be tested independently from owner-profile UIDs. Do not assume a GUI toggle proves module unmounting works; it must be tested. During the first POC of `007-kernelsu-sunfish`, evaluate a version compatible with non-GKI 4.14; once functional, pin an exact tag/commit. Reproducible builds must record that revision. KernelSU updates are deliberate tested changes, not automatic upgrades. SUSFS is optional and only after KernelSU and application profiles work. Do not introduce Zygisk or LSPosed in the initial architecture unless a feature cannot reasonably be implemented natively. An optional boot mode with root unavailable may be implemented later as a diagnostic/fallback mechanism. ## Features integrated directly in the ROM Prefer native ROM functionality for: - unrestricted call recording independent of region (Dialer / CarrierConfig / overlay behaviour derived from AXP.OS / iodéOS references); - user-configurable framework option allowing screenshots/screen capture where apps set `FLAG_SECURE`; - configurable hosts/DNS/privacy support; - automatic reboot after configurable inactivity; - configurable automatic Wi-Fi/Bluetooth shutdown where practical. Do not require LSPosed for call recording or `FLAG_SECURE`. ## Hardening strategy Hardening is incremental. Every significant hardening change must: - be isolated in a comprehensible commit; - document its upstream/reference source; - remain revertible; - pass boot and basic hardware tests; - pass the compatibility regression suite before being accepted. Preferred source order for modern framework hardening: 1. modern GrapheneOS Android 16 implementation; 2. AXP.OS / DivestOS implementation; 3. historical GrapheneOS sunfish implementation where hardware-specific. Do not attempt to emulate hardware protections unsupported by the Pixel 4a. Never blindly copy patches; establish what problem they solve, whether Android 16 / LineageOS already solves it, and whether they remain applicable to sunfish. ## Build targets and signing - Development target: `userdebug`. - Release target: `user` (when signing / AVB / release work lands). - Early phases: development/test-keys. - Project-owned platform/release/AVB keys: introduced in `011-signing-avb-ota` after a stable functional ROM exists. - Exception: any key that must remain stable early for updateability (especially patched Phonesky signing) must be decided before distributing an updatable first version. Development initially uses an unlocked bootloader. After the ROM is stable: - generate dedicated ROM signing keys; - implement reproducible release signing; - configure Android Verified Boot with project-owned keys; - support factory/recovery images and OTA generation; - test bootloader relocking with the custom trust chain. KernelSU compiled into a project-signed kernel is compatible with the project signing model; do not treat root presence itself as an AVB failure. Private signing material must never be committed to Git. OTA is considered architecturally so doors stay open, but is not implemented and does not block early builds. Real OTA/signing/AVB work belongs to `011-signing-avb-ota`. ## Host boundary: rom-dev01 is a prerequisite Provisioning of the Proxmox VM, public IP selection, Hetzner/vswitch details, PVE lifecycle, and SSYSTEMS Salt `saltenv=base` bootstrap are **out of scope** for this repository. Assume once development starts on the host: - `rom-dev01` exists; - Ubuntu Server 24.04 LTS is installed; - one reachable public IPv4 address (public NIC only; no required `10.100.67.0/18` NIC); - SSH administration works; - SSYSTEMS base provisioning is complete. This project must not manage `pm-test01`, company Salt states, or company governance from this repository. ### Capacity assumptions (do not oversize builds) Initial host capacity to plan around: - 6 vCPU - 52 GB RAM - 2 TB disk (expandable if required) - 32 GB VM swap Builds must support conservative parallelism and tolerate swap when required. Do not assume additional resources are available. ### Project account Do not hard-code laptop admin usernames as architectural requirements. After the host exists, the project may create/use a dedicated account: - `android-build` for Android source trees and builds. ### Laptop vs host roles Laptop: - Cursor UI / Remote SSH client; - adb / fastboot workstation; - Pixel physically attached for flashing/testing; - small local checkouts where useful. `rom-dev01`: - Android source trees, `.repo`, `out/`, ccache; - Gitea, Semaphore, Ansible; - build scripts, logs, artifacts under `/srv/rom/`. Do not design the normal workflow around remote USB passthrough. ## Tooling ownership inside this project Once `rom-dev01` exists: - **Ansible** (+ Semaphore UI) owns ROM workflow: sync, patches, builds, cleanup, manifest capture, artifact collection, publication. - Semaphore must not hide undocumented build behaviour and must not be exposed directly to the Internet; access via existing network/SSH constraints. - Gitea is private project Git hosting on the VM; not company GitLab. - The first LineageOS build should be performed manually before fully automating the workflow. Salt used by SSYSTEMS to create the VM remains outside this project. This repo does not encode company Salt VM creation. ## Git / Gitea model Use a private Gitea instance on `rom-dev01` with multiple repositories, not one giant monorepo. Preserve Android/`repo` natural layout. Fork only repositories that this project actually modifies. Initial repositories: - `sunfish-rom-manifest` - `sunfish-rom-build` - `sunfish-rom-patches` Later, only when needed: kernel fork, `frameworks/base`, Settings, Dialer, vendor/config. Do not commit: - `.repo`; - `out/`; - ccache; - complete upstream Android source trees; - private signing keys (including Phonesky signing keys); - personal phone dumps containing credentials or identifiers; - proprietary Google APKs. Initially a single developer. Do not design multi-developer permissions/CI until needed. Artifacts initially live under `/srv/rom/artifacts/` and are copied with `rsync` to the laptop for flashing. Significant releases may later use Gitea Releases (ROM ZIP, needed images, hashes, manifest, build metadata). Intermediate build outputs are not published. ## Reproducibility Every meaningful build must capture at least: - exact manifest; - source revisions; - project patch revisions; - build variant; - relevant configuration; - SHA-256 hashes; - compressed build log. Prefer small, source-attributed commits over large opaque patch dumps. ## Development stages Progress in this order unless a documented technical dependency requires otherwise: 1. Capture the current working AXP.OS installation as a compatibility reference (`002`) — **mandatory before experimental flashes** (single daily-driver device). 2. Build and boot vanilla LineageOS 23.2 for sunfish (`003`). 3. Integrate microG, GSF Proxy, patched Phonesky, and restricted native signature spoofing (`004`–`005`). 4. Validate Insular, Yuh, and Swissquote compatibility (`006`). 5. Integrate KernelSU-Next and verified module unmount behaviour (`007`). 6. Native call recording and configurable `FLAG_SECURE` (`008`–`009`). 7. Additional ROM features / privacy controls (`010`). 8. Signing, AVB, OTA (`011`). 9. Incremental userspace then kernel hardening (`012`–`013`). 10. Optional later: SUSFS, alternative KernelSU, root-disabled boot, extra banking apps. Before the first experimental flash: document official sunfish factory images and a known recovery path (during `002`). `001-development-environment` starts **after** `rom-dev01` exists. It specifies the ROM development environment on that host (packages, `android-build`, repo/git, ccache, `/srv/rom`, Gitea, Semaphore, Ansible, Spec Kit, Remote SSH workflow). It does **not** specify Proxmox VM creation. ## Testing rule Never change several high-risk subsystems simultaneously when the result cannot be attributed to one change. Regression testing should include, as applicable to the stage: boot; encryption/PIN; calls/mobile data; Wi-Fi; Bluetooth; GPS; camera; audio; NFC; sensors; microG Self-Check; Google Play login/install/update; push; Insular work profile; Yuh; Swissquote; biometrics; banking confirmations; reboot; KernelSU application profiles where applicable. ## Project identity The result is a LineageOS-based custom ROM with selected compatibility, privacy, and hardening features. It must not be presented as official GrapheneOS, LineageOS, AXP.OS, DivestOS, or iodéOS. Public marketing/ROM brand naming is deferred and must not contaminate repository, spec, or architecture names. The technical project name remains `sunfish-a16-rom`. ## Spec Kit and documentation language Primary technical documentation and the constitution are written in English. Personal notes may be Spanish. Do not maintain duplicated bilingual docs. Use a clean upstream Spec Kit. Do not copy SSYSTEMS Spec Kit constitutions, company project-create flows, or company runtime configuration. Create feature specs only when ready to work them. Keep a non-binding roadmap in `specs/README.md` for later features; do not create empty stub directories for all future numbers in advance. ## Governance - This constitution supersedes conflicting informal notes for project rules. - Feature requirements live in `spec.md` files; amend those rather than overloading this document with implementation detail. - Amendments to this constitution require an explicit documented change and version/date bump. - `AGENTS.md` explains agent working rules for this repository only; it must not duplicate this constitution. -------------------------------------------------------------------------------- FILE: .specify/.gitignore -------------------------------------------------------------------------------- # Machine-local Spec Kit state — not meant to be shared. # Managed by the Specify CLI; safe to edit (your changes are preserved on refresh). # Local pointer to the current feature directory. Rewritten every time you # switch features, so it is per-checkout state rather than something to share. feature.json # Per-machine extension config overrides. extensions/*/local-config.yml -------------------------------------------------------------------------------- FILE: docs/README.md -------------------------------------------------------------------------------- # Documentation Project rules: `.specify/memory/constitution.md` Agent rules: `../AGENTS.md` Feature specs: `../specs/` ## Host boundary `rom-dev01` (Ubuntu 24.04, public IPv4, SSH) is provisioned **outside** this project (SSYSTEMS Salt `saltenv=base` / PVE). This repository must not specify or automate Proxmox VM creation, public IP selection, or company Salt states. Feature `001-development-environment` starts from an already-available host. ## Planned Gitea repositories (on rom-dev01) - `sunfish-rom-manifest` - `sunfish-rom-build` - `sunfish-rom-patches` Plus forks only when modification requires them (kernel, frameworks/base, Settings, Dialer, vendor/config). -------------------------------------------------------------------------------- FILE: specs/README.md -------------------------------------------------------------------------------- # Feature Specifications Numbered feature specs for `sunfish-a16-rom`. ## Structure ```text specs/ └── NNN-short-name/ ├── spec.md # Only human-maintained requirements source ├── plan.md # Derived — regenerate after spec changes ├── tasks.md # Derived — regenerate after spec changes └── … ``` ## Numbering - Three-digit, sequential: `001-…`, `002-…` - Short name: lowercase, hyphen-separated - Create a feature directory only when ready to specify/implement it ## Spec-as-source 1. Edit requirements only in `spec.md`. 2. Run `/speckit-plan` and `/speckit-tasks` to regenerate derived artifacts. 3. Implementation follows the active feature; do not invent decisions missing from the constitution or the active `spec.md`. ## Active / next features | Dir | Intent | |-----|--------| | `001-development-environment` | ROM build host env on existing `rom-dev01` (not VM creation) | | `002-axp-reference-capture` | Capture daily-driver AXP.OS 22 baseline before experimental flashes | | `003-lineage-23-vanilla-build` | First vanilla LOS 23.2 build → flash → boot → basic hardware | ## Roadmap (non-binding) Later features are created only when prior work supplies enough information. Numbers may shift; this list is guidance, not stubs: | # | Theme | |---|--------| | 004 | microG + GSF Proxy + patched Phonesky | | 005 | Restricted native signature spoofing | | 006 | Insular / banking compatibility baseline (Yuh, Swissquote hard-gates) | | 007 | KernelSU-Next on sunfish 4.14 | | 008 | Native call recording | | 009 | Configurable FLAG_SECURE / screen capture | | 010 | Privacy / ROM features | | 011 | Signing / AVB / OTA | | 012 | Userspace hardening | | 013 | Kernel hardening | ## New feature ```text /speckit-specify ``` -------------------------------------------------------------------------------- FILE: specs/001-development-environment/spec.md -------------------------------------------------------------------------------- # Feature Specification: Development environment on rom-dev01 **Feature Branch**: `001-development-environment` **Created**: 2026-08-09 **Status**: Draft **Input**: Provision the ROM development environment on an already-existing `rom-dev01` host and establish the laptop ↔ VM ↔ Pixel workflow defined by the project constitution. ## Context / non-goals **Assumed already true before this feature starts:** - `rom-dev01` exists (Ubuntu Server 24.04 LTS); - one reachable public IPv4 address (public NIC only); - SSH administration works; - SSYSTEMS base provisioning (`saltenv=base`) is complete. **Explicitly out of scope:** - Proxmox / `pm-test01` VM creation; - public subnet/IP selection; - company Salt states, Redmine, or SSYSTEMS governance; - LineageOS source sync or first ROM build (see `003`); - AXP capture (see `002`). ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Reachable ROM build host workspace (Priority: P1) As the developer, I can SSH from my laptop into `rom-dev01` and use a dedicated `android-build` account with a documented home/workspace layout for Android work. **Why this priority**: Without a stable host account and layout, no later build feature can proceed. **Independent Test**: SSH as the project build user, create a file under the documented workspace, confirm ownership and paths. **Acceptance Scenarios**: 1. **Given** `rom-dev01` is up, **When** I connect via SSH from the laptop, **Then** authentication succeeds without requiring this project to change PVE/network provisioning. 2. **Given** SSH works, **When** the `android-build` account is provisioned, **Then** it exists with a documented home and build-related directories. 3. **Given** the account exists, **When** I inspect `/srv/rom` (or the agreed layout), **Then** directories for sources, artifacts, logs, and tooling are present with clear ownership. --- ### User Story 2 - Android build toolchain prerequisites (Priority: P1) As the developer, the host has the packages and tools needed to sync and build LineageOS for sunfish (repo, git, git-lfs, JDK, build deps, ccache), sized for 6 vCPU / 52 GB RAM / 32 GB swap. **Why this priority**: Vanilla LOS build (`003`) depends on this. **Independent Test**: `repo`/`git`/`ccache` respond; documented package set is installed; ccache directory exists and is writable by `android-build`. **Acceptance Scenarios**: 1. **Given** `android-build` session, **When** I run `repo --version` and `git --version`, **Then** both succeed. 2. **Given** build dependencies are installed, **When** I check ccache config and cache dir, **Then** ccache is usable by `android-build`. 3. **Given** constrained host resources, **When** build parallelism defaults are documented, **Then** they are conservative (not assuming 16 vCPU / 64 GB). --- ### User Story 3 - Project Git and orchestration services (Priority: P2) As the developer, private Gitea and Semaphore (over Ansible) run on `rom-dev01` for project repos and ROM workflow orchestration, without exposing those UIs unnecessarily to the public Internet. **Why this priority**: Needed before multi-repo ROM automation; can follow basic toolchain if sequenced. **Independent Test**: Gitea serves locally/over SSH tunnel; initial empty repos `sunfish-rom-manifest`, `sunfish-rom-build`, `sunfish-rom-patches` exist or are documented to create; Semaphore can run a trivial Ansible playbook. **Acceptance Scenarios**: 1. **Given** Gitea is installed, **When** I access it via the approved path (SSH tunnel or existing access policy), **Then** I can create/browse private project repositories. 2. **Given** Ansible is installed, **When** Semaphore is configured, **Then** it drives Ansible without hiding undocumented build steps. 3. **Given** public IP exists, **When** reviewing listening services, **Then** Gitea/Semaphore are not required to be open to the whole Internet for normal operation. --- ### User Story 4 - Laptop remains a thin client (Priority: P2) As the developer, Cursor Remote SSH uses `rom-dev01` as the heavy workspace; the Pixel stays USB-attached to the laptop; artifacts are `rsync`'d for flashing. **Why this priority**: Enforces the disk/space strategy and flashing model. **Independent Test**: Documented Remote SSH workflow; sample artifact path `/srv/rom/artifacts` syncs to the laptop with `rsync`. **Acceptance Scenarios**: 1. **Given** Cursor on the laptop, **When** I open the project via Remote SSH, **Then** I edit/build on `rom-dev01` without keeping `.repo`/`out` on the laptop. 2. **Given** a dummy artifact in `/srv/rom/artifacts`, **When** I `rsync` it to the laptop, **Then** the file arrives for local `adb`/`fastboot` use. 3. **Given** the Pixel is attached to the laptop, **When** following the workflow docs, **Then** no USB passthrough to the VM is required. --- ### Edge Cases - Host reboots: services and mount/layout expectations are documented. - Disk pressure on 2 TB: cleanup conventions for `out/` and old artifacts. - SSH admin user ≠ `android-build`: project must not hard-depend on laptop usernames (`aventura` / `ubuntu`). ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: Provide dedicated `android-build` account and documented workspace. - **FR-002**: Install Android/LineageOS build prerequisites and ccache. - **FR-003**: Create `/srv/rom` layout (sources, artifacts, logs, tooling) or document an equivalent and use it consistently. - **FR-004**: Install and configure private Gitea for project repositories. - **FR-005**: Install Ansible; configure Semaphore as UI over Ansible for ROM workflow (initially may only prove a smoke playbook). - **FR-006**: Document Cursor Remote SSH + `rsync` artifact + laptop adb/fastboot workflow. - **FR-007**: Document conservative build parallelism defaults for 6 vCPU / 52 GB / swap 32 GB. - **FR-008**: Ensure Spec Kit project for `sunfish-a16-rom` is available on the host (clone/sync from this staging repo or Gitea once published). ### Key Entities - **rom-dev01**: pre-existing Ubuntu 24.04 build host. - **android-build**: project build account. - **/srv/rom**: canonical on-host data layout. - **Gitea / Semaphore / Ansible**: project-owned services on the VM. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: From a clean SSH session as `android-build`, toolchain commands required for `003` are available without further ad-hoc package hunting. - **SC-002**: `/srv/rom/artifacts` (or documented equivalent) is writable and used as the artifact handoff point to the laptop. - **SC-003**: Gitea hosts (or is ready to host) the three initial empty project repos without using company GitLab. - **SC-004**: Written workflow doc allows a cold start: SSH → workspace → (later) build → rsync → flash on laptop-attached Pixel. - **SC-005**: No playbook or doc in this feature creates or reconfigures the Proxmox VM itself. -------------------------------------------------------------------------------- FILE: specs/002-axp-reference-capture/spec.md -------------------------------------------------------------------------------- # Feature Specification: AXP.OS reference capture **Feature Branch**: `002-axp-reference-capture` **Created**: 2026-08-09 **Status**: Draft **Input**: Capture the current daily-driver AXP.OS 22 installation on sunfish as a compatibility and recovery reference **before** any experimental ROM flashes. ## Context / non-goals - The Pixel 4a (`sunfish`) in use is the **same** daily-driver device. There is no second development phone yet. - Therefore this capture is **mandatory** before `003` experimental flashes. - Do **not** invent exact package versions, signatures, Magisk module lists, or UIDs in the constitution; this feature produces that inventory. - Do not commit dumps containing credentials, tokens, or personal identifiers to Git. Store sensitive captures on `rom-dev01` under a restricted path (or encrypted offline media if absolutely required). ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Recoverable known-good baseline (Priority: P1) As the developer, I can restore or reinstall back to a known-good AXP-compatible state using documented factory images, recovery path, and captured reference data if an experimental flash fails. **Why this priority**: Single device; bricking daily workflow is unacceptable. **Independent Test**: Written recovery procedure reviewed end-to-end; factory image URLs/versions recorded; unlock/fastboot state documented. **Acceptance Scenarios**: 1. **Given** the current unlocked bootloader device, **When** I document unlock/fastboot/`getprop` identity, **Then** device codename is confirmed `sunfish` and build identity is recorded. 2. **Given** official Google sunfish factory images, **When** I record the exact image set and flashing commands, **Then** a known stock recovery path exists on paper before any custom flash. 3. **Given** capture artifacts stored safely, **When** I attempt an experimental flash later, **Then** I still have enough information to return to a usable baseline. --- ### User Story 2 - Compatibility inventory (Priority: P1) As the developer, I have a structured inventory of the working AXP stack that later features (`004`–`006`) must reproduce. **Why this priority**: Defines the MVP compatibility target. **Independent Test**: Inventory document/checklist complete for the mandatory sections below; no section left as “unknown” without an explicit reason. **Acceptance Scenarios**: 1. **Given** AXP 22 running, **When** I collect `getprop` and build fingerprints, **Then** exact ROM/build identifiers are stored. 2. **Given** the device, **When** I inventory packages for microG, GSF Proxy, Phonesky/`com.android.vending`, Insular, Yuh, Swissquote, **Then** package names, versions, paths, and signing cert fingerprints are recorded. 3. **Given** Magisk/root is present, **When** I capture Magisk version, modules, DenyList (or equivalent), and relevant policies, **Then** root-related behaviour affecting banking apps is documented. 4. **Given** Insular work profile, **When** I capture users/UIDs/profile state and note Yuh/Swissquote install locations, **Then** the banking workflow baseline is documented without requiring login secrets in Git. --- ### User Story 3 - Safe artifact handling (Priority: P2) As the developer, captures that may contain personal data never enter Git; only redacted summaries and checklists are committed to the Spec Kit / docs repos. **Why this priority**: Privacy and constitution compliance. **Independent Test**: `.gitignore` / docs state what is committed vs host-only; sample redacted summary exists in-repo. **Acceptance Scenarios**: 1. **Given** raw bugreports/pulls/APKs, **When** stored, **Then** they live outside Git (e.g. `/srv/rom/reference/axp/` on `rom-dev01`). 2. **Given** the in-repo summary, **When** reviewed, **Then** it contains versions/hashes/workflow steps but not passwords, session tokens, or full personal dumps. --- ### Edge Cases - Device encrypt/PIN: document without storing the PIN. - Play Store / Phonesky APK: may be copied to restricted host storage for later `004`; never committed. - Partial capture: do not proceed to experimental flash until P1 acceptance scenarios pass. ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: Record device identity (`getprop`, fingerprint, security patch, bootloader unlock state). - **FR-002**: Document official sunfish factory image version and recovery/ reflash procedure. - **FR-003**: Inventory microG, GSF Proxy, Phonesky, Insular, Magisk, modules, DenyList/policies, users/UIDs, Yuh, Swissquote (versions, paths, cert hashes). - **FR-004**: Document the banking workflow used today (download without open → Insular → first launch in work profile → Play updates in profile). - **FR-005**: Store raw artifacts off-Git; commit only redacted reference docs. - **FR-006**: Gate: no experimental custom ROM flash until this feature’s P1 criteria are met. ### Key Entities - **AXP baseline**: known-good daily-driver state. - **Reference bundle**: host-local capture directory. - **Redacted summary**: in-repo documentation derived from the bundle. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: A checklist shows all P1 inventory sections completed or explicitly deferred with justification. - **SC-002**: Factory-image recovery path is written and reviewed before `003` flash attempts. - **SC-003**: Yuh/Swissquote presence and Insular relationship are documented well enough to define pass/fail for `006`. - **SC-004**: Git history contains no proprietary Phonesky APK and no personal credential-bearing dumps. -------------------------------------------------------------------------------- FILE: specs/003-lineage-23-vanilla-build/spec.md -------------------------------------------------------------------------------- # Feature Specification: LineageOS 23.2 vanilla build for sunfish **Feature Branch**: `003-lineage-23-vanilla-build` **Created**: 2026-08-09 **Status**: Draft **Input**: Produce the first vanilla LineageOS 23.2 / Android 16 build for `sunfish`, copy images to the laptop, flash, and verify boot plus basic hardware — with no microG, KernelSU, or hardening yet. ## Context / non-goals **Prerequisites:** - `001-development-environment` sufficiently complete to sync/build; - `002-axp-reference-capture` P1 complete (single daily-driver device). **Out of scope for this feature:** - microG / Phonesky / signature spoofing; - KernelSU / SUSFS / Magisk parity; - call recording, FLAG_SECURE toggles, privacy extras; - project signing / AVB / OTA implementation; - Graphene/AXP/Divest patch ports. Build target: **`userdebug`** with development/test-keys. ## User Scenarios & Testing *(mandatory)* ### User Story 1 - Reproducible vanilla sync & build (Priority: P1) As the developer, I can sync LineageOS 23.2 for sunfish on `rom-dev01` and complete a build that emits flashable images, with manifest/revisions recorded. **Why this priority**: Establishes the real base ROM. **Independent Test**: Build finishes; artifact paths listed; manifest revision document stored under `/srv/rom` with hashes. **Acceptance Scenarios**: 1. **Given** `android-build` on `rom-dev01`, **When** I sync the LOS 23.2 sunfish source via `repo`, **Then** the tree matches a documented manifest revision. 2. **Given** the synced tree, **When** I build `userdebug` for sunfish with conservative parallelism, **Then** the build completes without requiring project patches beyond LOS-needed device/kernel trees. 3. **Given** a successful build, **When** I collect outputs, **Then** images/ zip needed to flash sunfish are in `/srv/rom/artifacts` (or documented path) with SHA-256 hashes and a compressed build log. --- ### User Story 2 - Flash from laptop (Priority: P1) As the developer, I `rsync` artifacts to the laptop and flash the Pixel 4a over USB using fastboot/adb, following the recovery notes from `002` if something fails. **Why this priority**: Closes the loop on the thin-client workflow. **Independent Test**: Device boots the new build; `getprop` shows LineageOS / expected fingerprints (not AXP). **Acceptance Scenarios**: 1. **Given** artifacts on the laptop, **When** I flash per documented steps, **Then** the device boots into the vanilla LOS build. 2. **Given** a failed flash/boot, **When** I follow `002` recovery docs, **Then** I can return to a usable baseline. --- ### User Story 3 - Basic hardware smoke test (Priority: P1) As the developer, after first boot I verify essential radios and peripherals well enough to trust this build as the clean base for later features. **Why this priority**: A boot-only “success” that breaks telephony/Wi-Fi is not a usable base. **Independent Test**: Checklist pass for items below on the vanilla build. **Acceptance Scenarios**: 1. **Given** first boot completed, **When** I test calls/mobile data, Wi-Fi, Bluetooth, GPS, camera, audio, NFC, sensors, encryption/PIN, **Then** each either works or is logged as a blocking defect with evidence. 2. **Given** smoke results, **When** deciding to proceed to `004`, **Then** no unresolved P1 hardware blockers remain (or they are explicitly accepted with rationale). --- ### Edge Cases - Build disk/oom with 52 GB + swap: document job `-j` and failure recovery (`out/` cleanup). - Partial artifact set: do not flash until required partitions/images are present and hashed. - Do not install Magisk/KernelSU “just to test” in this feature. ## Requirements *(mandatory)* ### Functional Requirements - **FR-001**: Sync LineageOS 23.2 sources for sunfish using a pinned manifest revision. - **FR-002**: Build `userdebug` images with test-keys / default LOS signing for this stage. - **FR-003**: Record manifest, revisions, build variant, config, hashes, and compressed log for the successful build. - **FR-004**: Publish artifacts to `/srv/rom/artifacts` and document `rsync` + flash procedure. - **FR-005**: Boot sunfish on the vanilla build and run the basic hardware checklist. - **FR-006**: Keep tree free of microG/Phonesky/KernelSU/hardening patches intended for later features. ### Key Entities - **Vanilla LOS build**: clean base artifact set. - **Build metadata**: manifest + hashes + log bundle. - **Smoke checklist**: hardware/regression minimum for this stage. ## Success Criteria *(mandatory)* ### Measurable Outcomes - **SC-001**: One successful sunfish `userdebug` build exists with recorded metadata and hashes. - **SC-002**: Device boots that build after laptop-side flash. - **SC-003**: Basic hardware checklist is completed and stored. - **SC-004**: No dependency on LSPosed/Magisk modules for this stage’s success. - **SC-005**: This build is tagged/kept as a known-good flashable baseline for regression when later features break the device. ================================================================================ NOTES FOR REVIEWER ================================================================================ - This dump intentionally excludes Spec Kit runtime (.cursor/skills, .specify/scripts, templates, workflows). Those come from upstream `specify init`. - rom-dev01 / Proxmox / SSYSTEMS Salt VM provisioning is OUT OF SCOPE for this project. - Feature 001 starts from an already-existing Ubuntu 24.04 host. - Features 004–013 exist only as a non-binding roadmap in specs/README.md. - Language: constitution and technical docs in English; this dump header may be bilingual.