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.
