AXP Magisk resurrection track: Speckit 009 port AXP/LOS22 to LOS23.

Ship Magisk like GOLDEN; KernelSU optional recycle only; parallel to sunfish-a16-rom standby.
This commit is contained in:
sunfish-admin committed 2026-09-16 21:56:22 +00:00
commit 12d2179c20
150 files changed
+26263

No files matched your search

+580
View File
@@ -0,0 +1,580 @@
# sunfish-a16-rom Constitution
Project: Android 16 custom ROM for Google Pixel 4a (`sunfish`) —
**AXP.OS Magisk resurrection** track (`AXP_Resurection`).
This project resurrects AXP.OS Pro capability on LineageOS 23.2 / Android 16
for sunfish (Magisk like GOLDEN). Functionality and application compatibility
first, then hardening. The project must remain debuggable and reproducible.
This constitution is specific to `AXP_Resurection`. Sibling `sunfish-a16-rom`
is the KernelSU standby track. It does **not** inherit SSYSTEMS, company
GitLab, Redmine, or buildout-saar governance.
**Version**: 0.3.0 | **Ratified**: 2026-08-09 | **Last Amended**: 2026-09-16
## 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 workflow on this sunfish device is the
MVP gate. Hardening must not knowingly break that baseline without the
regression being isolated, documented, and reversible.
**AXP.OS Pro parity intent:** the product goal is to reproduce **AXP.OS Pro**
functionality, except features that are obsolete, incompatible with LineageOS
23.2 / Android 16 / sunfish, or deliberately substituted (for example Magisk →
KernelSU-Next; AXP backup tooling → NeoBackup as an external user tool).
`docs/axp-pro-parity.md` and `docs/hardening-backlog.md` are **non-normative**
product/backlog trackers. A row becomes a requirement only when promoted into a
feature `spec.md`. For an active feature, this constitution plus that feature's
`spec.md` remain authoritative if a backlog row conflicts.
### 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. (Last GrapheneOS sunfish line was
**Android 13** — useful as historical reference only; GOLDEN today runs
**AXP on Android 15**, which is a different stack.)
- Use modern GrapheneOS Android 16 implementations as the preferred reference
for framework-level hardening where they can be cleanly adapted.
- Use modern GrapheneOS **kernel** hardening as a technique/reference source as
well: identify the security property provided by current implementations and
evaluate whether an equivalent can be safely adapted or backported to the
LineageOS sunfish 4.14 kernel. Do **not** directly transplant patches that
depend on newer GKI/kernel/hardware facilities.
- Audit the AXP.OS sunfish kernel patch stack, including AXP-specific changes as
well as patches inherited from DivestOS, GrapheneOS or upstream. Prefer the
original upstream source when provenance can be established and avoid applying
duplicate/equivalent fixes already present in LineageOS.
- Port applicable security/privacy patches from AXP.OS and DivestOS.
- 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
There are **two** Pixel 4a (`sunfish`) devices — see `docs/device-roles.md`:
- **GOLDEN** — daily-driver AXP.OS with working banks/microG/Phonesky/Insular;
**do not** flash experimental project ROMs on it.
- **LAB** — dedicated flash/test device; all experimental images go here.
The GOLDEN AXP installation is the live compatibility **oracle** (essential
state documented in `002`; may be re-queried via `adb` later). Broader product
intent is AXP.OS Pro feature parity per `docs/axp-pro-parity.md`.
The new ROM must reproduce at minimum (MVP hard gates):
- 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.
### MVP levels
| Level | Through | Meaning |
|-------|---------|---------|
| **Compatibility MVP** | `007` | microG, patched Phonesky, managed profile, Yuh and Swissquote PASS, Play install/update; banking apps never receive root |
| **Daily-driver MVP** | `010` | Compatibility MVP plus accepted KernelSU integration, native call recording, FLAG_SECURE and accepted usability/privacy features |
`007` owns banking acceptance. A rootless snapshot of our current ROM is recorded
before adding root; PASS is not a prerequisite. `006` is deferred. Root is not
accepted unless both Yuh and Swissquote pass on the tested stack. If experiments
fail, keep the feature incomplete or withdraw root; do not claim compatibility.
Signing/AVB (`011`) repeats banking regression; hardening follows in `012`–`013`.
Island is the current LAB managed-profile tool; historical Insular references
remain valid as reference workflows, not a requirement to install both tools.
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 golden banking flow as the initial compatibility
test (exact package/process names from `002`):
1. Install the banking application via **Aurora Store**.
2. **Do not open** the application.
3. Add it to Magisk DenyList **before** the first process start (include
relevant processes, not only the package name).
4. Clone/install it into the Island work profile (GOLDEN measured tool).
5. First launch occurs inside Island.
6. Patched Google Play is also available inside Island.
7. If the banking app requires a Play Store update, perform that update from
inside the work profile.
8. 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
**Ship root for this track (`AXP_Resurection` / `009`): Magisk**, matching
AXP.OS / GOLDEN (newest Magisk stable that works on sunfish / LOS 23.2;
AXP-like preinstalled but not fully activated layout; DenyList-class hiding
so banking apps never receive root).
KernelSU-Next / SusFS work from the sibling `sunfish-a16-rom` track remains
**out of ship here**. Existing functional KernelSU kernels MAY be recycled
for debug/reference only (`009` FR-016) and MUST NOT gate Magisk acceptance.
Required properties:
- root is explicitly granted only as Magisk intends (owner-approved apps);
- banking applications never receive root (DenyList-class);
- managed-profile UIDs must be tested independently from owner-profile UIDs;
- Magisk version pins follow newest-stable-then-pin policy (fetch fresh
upstreams; never ship from shallow/stale host copies).
Do not introduce Zygisk or LSPosed for ROM features that can be native
(spoofing, call recording, FLAG_SECURE). Magisk modules only where AXP/GOLDEN
parity truly requires them.
An optional boot mode with root unavailable may be implemented later as a
diagnostic/fallback mechanism.
### Relationship to sibling KernelSU track
The `sunfish-a16-rom` workspace/repo keeps the earlier KernelSU / split
roadmap on standby. This constitution applies only to **AXP_Resurection**.
Do not silently reintroduce KernelSU as the default ship root in this tree.
## Features integrated directly in the ROM
Prefer native ROM functionality for:
- unrestricted call recording independent of region. Use AXP.OS / EXTENDROM /
iodéOS as **behavioural and implementation references**, but re-investigate
Android 16 / LineageOS 23.2 Dialer, CarrierConfig, and framework paths before
porting. Do not assume AXP's older (e.g. Android 11/13) restriction-toggle
overlays apply unchanged to Android 16 (`008`);
- native configurable `FLAG_SECURE` override (`009`):
- Android's normal `FLAG_SECURE` behaviour remains the **default**;
- user-selectable **global** override only (no per-app lists);
- covers screenshots and screen recording/capture;
- no LSPosed, Zygisk, or root-module dependency;
- 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`.
`FLAG_SECURE` override is a **project-specific** requirement (not an AXP Pro
catalog feature). Track it under project-specific additions in
`docs/axp-pro-parity.md`, not as AXP parity.
## 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.
Document EOL limits in `013` / hardening work: patches we can backport in-tree
versus proprietary vendor/modem firmware we cannot replace. Never blindly copy
patches; establish what problem they solve, whether Android 16 / LineageOS
already solves it, and whether they remain applicable to sunfish.
Candidate ideas live in non-normative `docs/hardening-backlog.md` until promoted
into a feature spec.
## 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.
`userdebug` is the default development build. Banking compatibility failures
observed on `userdebug` must **not** be considered definitive until retested on
a `user` / release-like test build where build type or test-key state may affect
application behaviour. Final production signing, AVB, and relocking still belong
to `011`, which must re-run the full Yuh + Swissquote regression on the
really signed/relocked ROM.
Experimental flashing happens **only on LAB** and requires an unlocked
bootloader on that device. LAB and GOLDEN lock/bootloader state are measured in
`002`; if LAB is locked, unlocking LAB is a prerequisite before the first `003`
flash. Never unlock/wipe/flash GOLDEN for project experiments. 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. Public certificates
(e.g. `*.x509.pem`) may be versioned when useful for documentation/reproducibility.
Any signing key whose identity must remain stable across updates (Phonesky,
platform/release, AVB, OTA, etc.) must have an **encrypted/offline backup**
before the first build that depends on that key is distributed or adopted as a
baseline.
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.
### Isolation posture (guest)
Goal: keep `rom-dev01` as isolated as practical from SSYSTEMS internal
infrastructure while accepting that the public vSwitch/VLAN may be shared with
other lab/gateway VMs.
Required posture from the ROM project's perspective:
- **Public NIC only** — no additional NIC on SSYSTEMS internal networks
(e.g. `10.100.67.0/18`) unless a later documented exception appears.
- **No dependency** on internal SSYSTEMS services for normal ROM work: internal
DNS, LDAP/SSO, company VPN, company GitLab, NFS/CIFS to corporate storage,
or company Zabbix as a required path.
- **Project UIs** (Gitea, Semaphore) must not need to be exposed to the whole
Internet; prefer localhost / SSH tunnel / existing tight SSH access.
- **Guest firewall** should favour default-deny inbound beyond SSH administration
and should block or avoid unnecessary traffic toward known SSYSTEMS internal
ranges once those ranges are known to the operator.
- **DNS** for day-to-day project use should not require SSYSTEMS internal
resolvers.
- Sharing the **public** VLAN/subnet with gateway VMs is acceptable and does not
by itself place this project under SSYSTEMS product governance.
- Hypervisor/storage (`pm-test01`) remain unavoidable physical hosting; they are
not a license to couple the guest into internal ops services.
Concrete public IPs, PVE bridges, and company Salt firewall templates stay
outside this repository. Feature `001` implements/verifies the guest-side
posture on the already-provisioned host.
### 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-a16-rom` — Spec Kit, constitution, roadmap, global documentation
(this meta repository; laptop staging is temporary until Gitea exists)
- `sunfish-rom-manifest` — repo manifests
- `sunfish-rom-build` — scripts / Ansible / Semaphore / build tooling
- `sunfish-rom-patches` — patchsets / tracking
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.
Project-owned Gitea repositories must have an **off-VM backup or mirror**. The
build VM must not be the only copy of project history (laptop clones, Borg, or
another agreed target are acceptable).
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. Document the GOLDEN AXP oracle and label GOLDEN vs LAB (`002`) — essential
capture + verify Yuh/Swissquote on GOLDEN; **no** NeoBackup/wipe of GOLDEN.
2. Build and boot vanilla LineageOS 23.2 on **LAB only** (`003`).
3. Integrate microG, GSF Proxy, patched Phonesky, and restricted native
signature spoofing on LAB (`004`–`005`).
4. Record current rootless LAB banking outcomes in `007` preflight; defer `006`.
5. Integrate KernelSU-Next and verified module unmount on LAB (`007`), followed
by optional SUSFS and evaluated attestation experiments. Both banks must PASS
to accept root and the Compatibility MVP.
6. Native call recording and configurable `FLAG_SECURE` (`008`–`009`).
7. Remaining AXP Pro usability/privacy features (`010`; matrix spans `004`–`013`,
see non-normative `docs/axp-pro-parity.md`).
8. Signing, AVB, OTA + full banking regression on signed/relocked **LAB** ROM
(`011`).
9. Incremental userspace then kernel hardening (`012`–`013`; candidates in
non-normative `docs/hardening-backlog.md`).
10. Optional later: alternative KernelSU, root-disabled boot, extra
banking apps.
Before stressing LAB: document official Google factory-image **emergency rescue
for LAB** (`002`/`003`). GOLDEN remains a live AXP reference — not something we
wipe and rebuild for day-to-day bring-up. NeoBackup is optional personal
preference only, **not** a project gate.
`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.
For `005-restricted-signature-spoofing`: first verify what LineageOS 23.2 already
provides for restricted microG spoofing; extend only as needed for patched
Phonesky — do not assume a from-scratch spoofing stack.
## 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.
- `docs/axp-pro-parity.md` and `docs/hardening-backlog.md` are non-normative
until promoted into a feature spec.
- 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.
### Amendment 0.2.0 — 2026-09-15
Owner-authorized remediation of C1/C2: defer the rootless PASS gate, retain a
measured pre-root snapshot, and assign both-bank acceptance to `007`. This
changes sequencing, not LAB-only protection or the prohibition on banking root.
### Amendment 0.2.1 — 2026-09-15
Upstream freshness for root stack and similar deps: integrate from newest
compatible stable/tagged upstream (full git history), verify version codes
against the matching manager **before** long builds; pin only after LAB works.
Triggered by stale shallow ReSukiSU mirror yielding `KSU_VERSION=30701`.