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:
commit
12d2179c20
150 files changed
+26263
No files matched your search
@@ -0,0 +1,56 @@
|
||||
# Specification Analysis Report — 001-development-environment (re-run)
|
||||
|
||||
**Date**: 2026-08-09
|
||||
**Artifacts**: spec.md, plan.md (I1/I2 synced), tasks.md (T001–T048)
|
||||
**Constitution**: 0.1.5
|
||||
**Mode**: Read-only analysis
|
||||
|
||||
## Findings
|
||||
|
||||
| ID | Category | Severity | Location(s) | Summary | Recommendation |
|
||||
|----|----------|----------|-------------|---------|----------------|
|
||||
| A1 | Ambiguity | LOW | tasks T037 | Semaphore↔canonical repo transport left to implement | Keep; document in runbook at install time |
|
||||
| C1 | Coverage | LOW | tasks T024 | Laptop `adb`/`fastboot --version` without touching Pixel | Keep; useful non-blocking smoke |
|
||||
|
||||
**Resolved since prior analyze:** I1 (SSH vs `sudo -iu` smoke), I2 (P1 list includes pubkey + verify login).
|
||||
|
||||
No CRITICAL or HIGH findings. No constitution MUST violations. No 002/003 / PVE / LOS build / Pixel leakage.
|
||||
|
||||
## Coverage Summary
|
||||
|
||||
| Requirement Key | Has Task? | Task IDs |
|
||||
|-----------------|-----------|----------|
|
||||
| FR-001 … FR-010 | Yes | (unchanged; 100%) |
|
||||
| SC-001 … SC-007 | Yes | (unchanged; 100%) |
|
||||
|
||||
## Constitution Alignment Issues
|
||||
|
||||
None.
|
||||
|
||||
## Unmapped Tasks
|
||||
|
||||
None material (setup / preflight / polish remain support tasks).
|
||||
|
||||
## Metrics
|
||||
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Total Requirements (FR+SC) | 17 |
|
||||
| Total Tasks | 48 |
|
||||
| Coverage % | **100%** |
|
||||
| Ambiguity Count | 1 (LOW, intentional) |
|
||||
| Duplication Count | 0 |
|
||||
| Critical Issues Count | **0** |
|
||||
| High Issues Count | **0** |
|
||||
|
||||
## Next Actions
|
||||
|
||||
**STOP — freeze documentary cycle for `001`.**
|
||||
|
||||
- Do **not** regenerate tasks or re-plan `002`.
|
||||
- Do **not** `/speckit-implement` until `rom-dev01` has working SSH.
|
||||
- When VM exists: implement T001–T048 in order (P1 then P2).
|
||||
|
||||
## Remediation
|
||||
|
||||
No further remediation recommended before freeze.
|
||||
@@ -0,0 +1,186 @@
|
||||
# 001 host runbook — `rom-dev01`
|
||||
|
||||
Living notes for feature `001-development-environment`.
|
||||
|
||||
## Access (laptop → host)
|
||||
|
||||
| Item | Value | Notes |
|
||||
|------|-------|-------|
|
||||
| Project name | `rom-dev01` | Guest hostname set 2026-09-13 |
|
||||
| DNS / IP | **`a16.ssystems.de`** (preferred) / `a15.ssystems.de` → `49.13.104.83` | |
|
||||
| SSH port | **37037** | `:22` closed |
|
||||
| Admin | `root` (**default**) | `ssh a16` / `a16.ssystems.de` / `a16-root` |
|
||||
| Build user | `android-build` (uid/gid **1000**) | `ssh a16-build` (also `rom-dev01`, `a15`) |
|
||||
| Laptop private key | `~/.ssh/id_ed25519_rom_dev01` | also YubiKey PIV in `authorized_keys` |
|
||||
| Client SSH | `docs/ssh/config` | Include from `~/.ssh/config` |
|
||||
| Web UI | `https://a16.ssystems.de/` | nginx + wildcard + HTTP Basic |
|
||||
|
||||
### OpenSSH / Cursor
|
||||
|
||||
```sshconfig
|
||||
Host a16 a16.ssystems.de a16-root
|
||||
HostName 49.13.104.83
|
||||
User root
|
||||
Port 37037
|
||||
IdentityFile ~/.ssh/id_ed25519_rom_dev01
|
||||
IdentitiesOnly yes
|
||||
|
||||
Host a16-build
|
||||
HostName 49.13.104.83
|
||||
User android-build
|
||||
Port 37037
|
||||
IdentityFile ~/.ssh/id_ed25519_rom_dev01
|
||||
IdentitiesOnly yes
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
ssh a16 'whoami; hostname' # root @ rom-dev01
|
||||
ssh a16-build 'whoami' # android-build
|
||||
```
|
||||
### SSH password auth
|
||||
|
||||
Effective `sshd -T`: **`passwordauthentication no`** (Ubuntu
|
||||
`/etc/ssh/sshd_config.d/60-cloudimg-settings.conf` overrides
|
||||
`PasswordAuthentication yes` in main `sshd_config`). Pubkey-only in practice.
|
||||
Do **not** edit Salt-/cloud-managed sshd unless required; current effective
|
||||
policy already matches the desired end state. YubiKey PIN ≠ SSH password.
|
||||
|
||||
## Coexistence with `saltenv=base`
|
||||
|
||||
If a Salt-/base-managed file conflicts with project needs: **stop and report**.
|
||||
Do not silently replace Salt-managed settings.
|
||||
|
||||
Observed: `salt-minion` **inactive**; many company pubkeys already in
|
||||
`/root/.ssh/authorized_keys` (base provision). Project added:
|
||||
`id_ed25519_rom_dev01` + YubiKey PIV for `root` and `android-build`.
|
||||
|
||||
Rollback SSH key: remove the ed25519 line from `authorized_keys` on host;
|
||||
delete laptop `~/.ssh/id_ed25519_rom_dev01` if retiring.
|
||||
|
||||
## Account model
|
||||
|
||||
| Account | Role |
|
||||
|---------|------|
|
||||
| `root` | packages, users, services, firewall observation |
|
||||
| `android-build` | all Android builds, `/srv/rom` writes, Spec Kit meta tree |
|
||||
| future Gitea/Semaphore | least privilege; **never** build Android as root |
|
||||
|
||||
## Paths
|
||||
|
||||
| Path | Purpose | Mode (approx) |
|
||||
|------|---------|----------------|
|
||||
| `/home/android-build/sunfish-a16-rom` | Meta Spec Kit tree | user-owned |
|
||||
| `/srv/rom/src` | Android source trees | `android-build` |
|
||||
| `/srv/rom/references` | Reference archives | `android-build` |
|
||||
| `/srv/rom/tooling` | Host tooling — **not** Spec Kit checkout | `android-build` |
|
||||
| `/srv/rom/ccache` | `CCACHE_DIR` (50G) | `android-build` |
|
||||
| `/srv/rom/artifacts` | Artifact handoff to laptop | `android-build` |
|
||||
| `/srv/rom/logs` | Preflight / toolchain / smoke logs | `android-build` |
|
||||
| `/srv/rom/secrets` | Restricted secrets | `700 root:root` |
|
||||
|
||||
## Preflight summary (2026-09-13)
|
||||
|
||||
Full log: `/srv/rom/logs/preflight/preflight-latest.txt`
|
||||
|
||||
- Ubuntu 24.04.4 LTS / Linux 6.8.0-136-generic
|
||||
- 8 vCPU (host CPU E3-1275 v5), **62 GiB** RAM, **32 GiB** swap (`/swapfile`)
|
||||
- Disk: **1.9T** ext4 on `/` (~2T vda)
|
||||
- NIC: `ens18` only — `49.13.104.83/29`, default via `49.13.104.81` (public-only)
|
||||
- Firewall: ufw inactive; iptables ACCEPT (no flush)
|
||||
- Listening: SSH `0.0.0.0:37037`, systemd-resolved localhost DNS
|
||||
- apt: Ubuntu noble archives
|
||||
|
||||
## Toolchain (US2)
|
||||
|
||||
- Package log: `/srv/rom/logs/toolchain-packages.txt` (LOS wiki sunfish list +
|
||||
`openjdk-17-jdk`, `python-is-python3`)
|
||||
- `repo` in `~/bin/repo` (launcher 2.65)
|
||||
- `CCACHE_DIR=/srv/rom/ccache`, `USE_CCACHE=1`, size **50G**, compression on
|
||||
- Env in `android-build` `.profile` / `.bashrc`
|
||||
- Smoke: `/srv/rom/logs/toolchain-smoke.txt`
|
||||
- **FR-007 / build parallelism (use the HW):** guest has **8 vCPU / ~62 GiB /
|
||||
32 GiB swap**. Default Android builds: **`mka … -j8`** (match vCPU count).
|
||||
Do **not** leave conservative `-j4` unless diagnosing OOM. Watch `load` /
|
||||
`available` RAM; if linking OOMs, drop to `-j6` temporarily — not below
|
||||
without a written reason. Host-side: Proxmox CPU steal can waste cycles;
|
||||
prefer dedicated/pinned vCPUs when practical (outside this repo).
|
||||
Wrapper: `/srv/rom/logs/003-build/run-brunch.sh` (`-j8`).
|
||||
- **nsjail / build sandbox (Ubuntu 24.04):** AppArmor
|
||||
`kernel.apparmor_restrict_unprivileged_userns=1` put nsjail into profile
|
||||
`unprivileged_userns` and DENY `mount`/`setgid` → Soong message
|
||||
`Build sandboxing disabled due to nsjail error`. Fix (scoped, not global
|
||||
sysctl): `/etc/apparmor.d/nsjail-android-build` (`userns` +
|
||||
`flags=(unconfined)` for
|
||||
`/srv/rom/src/lineage/prebuilts/build-tools/linux-{x86,arm64}/bin/nsjail`).
|
||||
Evidence: `/srv/rom/logs/nsjail-apparmor-fix.txt`. Re-probe on next Soong
|
||||
start (current `mka bacon` already started with sandbox off).
|
||||
|
||||
## Thin client / artifacts (US5)
|
||||
|
||||
- Cursor Remote SSH: Host `rom-dev01` →
|
||||
`/home/android-build/sunfish-a16-rom` as `android-build`
|
||||
- Dummy rsync: host `/srv/rom/artifacts/dummy-001.txt` → laptop
|
||||
`Workspaces/sunfish-a16-rom/.local-artifacts/` (gitignored path preferred)
|
||||
- Pixel USB: **adb/fastboot on laptop only**; no USB passthrough to VM
|
||||
|
||||
## Gitea / Ansible / Semaphore
|
||||
|
||||
Independent of SSYSTEMS Salt/GitLab. All on `rom-dev01`.
|
||||
|
||||
| Service | Bind | Public URL |
|
||||
|---------|------|------------|
|
||||
| nginx | `0.0.0.0:80/443` | TLS + HTTP Basic gate |
|
||||
| Gitea 1.27.3 | `127.0.0.1:3000` | https://a16.ssystems.de/ |
|
||||
| Semaphore 2.19.12 | `127.0.0.1:3001` | https://a16.ssystems.de/semaphore/ |
|
||||
| Ansible | host CLI | core 2.16.3 |
|
||||
|
||||
- Site: `/etc/nginx/sites-available/a16.ssystems.de`
|
||||
- TLS: company wildcard `*.ssystems.de` (Sectigo) at
|
||||
`/etc/nginx/ssl/ssystems.de/{fullchain,privkey}.pem`
|
||||
Source (laptop, not in this repo):
|
||||
`buildout-saar-docker/salt/srv/files/etc/pki/tls/{certs,private}/wildcard_.ssystems.de-*`
|
||||
- HTTP Basic: `/etc/nginx/.htpasswd` — credentials on host only:
|
||||
`/srv/rom/secrets/web-htpasswd.txt` (user `sunfish`)
|
||||
- Unit: `gitea.service` — data `/var/lib/gitea`, config `/etc/gitea/app.ini`
|
||||
(`ROOT_URL=https://a16.ssystems.de/`)
|
||||
- Unit: `semaphore.service` — data `/var/lib/semaphore`, config `/etc/semaphore/config.json`
|
||||
(`web_host=https://a16.ssystems.de/semaphore`, `web_root=/semaphore`)
|
||||
nginx: `location /semaphore/` → `proxy_pass` **without** trailing URI
|
||||
(must preserve `/semaphore` prefix or UI assets 404 → blank page)
|
||||
- App secrets (host only, never Git): `/srv/rom/secrets/gitea-admin.txt`,
|
||||
`/srv/rom/secrets/semaphore-admin.txt`
|
||||
- Admin user (both apps): `sunfish-admin` (after nginx Basic)
|
||||
- Git transport: **HTTPS via nginx** (Gitea still `DISABLE_SSH=true`; no public `:2222`)
|
||||
- Repos (private): `sunfish-admin/{sunfish-a16-rom,sunfish-rom-manifest,sunfish-rom-build,sunfish-rom-patches}`
|
||||
- Automation tree: `/home/android-build/sunfish-rom-build` (not inside Spec Kit meta)
|
||||
- Semaphore project `sunfish-rom` template `env-smoke` clones **canonical**
|
||||
`sunfish-rom-build` from Gitea and runs `ansible/smoke.yml` unprivileged
|
||||
- Evidence: `/srv/rom/logs/ansible-smoke.txt`, `/srv/rom/logs/semaphore-smoke.txt`
|
||||
- Off-VM mirrors (laptop): `/home/aventura/Archives/sunfish-rom-mirrors/*.git`
|
||||
- No SSH tunnels needed for UIs anymore
|
||||
|
||||
### Accounts (reminder)
|
||||
|
||||
- **root**: install packages/services only
|
||||
- **android-build**: Android builds, meta + automation working trees
|
||||
- **git** / **semaphore**: service users for Gitea / Semaphore
|
||||
- Do **not** build Android as root (LOS/AXP practice)
|
||||
|
||||
## Isolation checklist
|
||||
|
||||
- [x] Public NIC only (`ens18` /29) — no internal SSYSTEMS NIC required
|
||||
- [x] App backends remain loopback (`:3000` / `:3001`); only nginx is public
|
||||
- [x] Workflow uses public DNS `a16.ssystems.de` + SSH port 37037 (no VPN)
|
||||
- [x] Gitea/Semaphore behind nginx HTTPS + HTTP Basic (`htpasswd`)
|
||||
|
||||
## Off-VM mirror
|
||||
|
||||
- Laptop: `/home/aventura/Archives/sunfish-rom-mirrors/*.git`
|
||||
- Host: `/srv/rom/artifacts/gitea-mirrors/` (token stays on host; laptop only rsyncs)
|
||||
|
||||
## Handoff
|
||||
|
||||
**`001` complete → proceed to `002` (AXP reference capture).**
|
||||
Do **not** start LineageOS `repo sync` / build as part of `001`.
|
||||
@@ -0,0 +1,781 @@
|
||||
001 plan review pack — for ChatGPT
|
||||
Generated: 2026-08-09T12:23:59+02:00
|
||||
Constitution: 0.1.5 | Active: specs/001-development-environment
|
||||
|
||||
================================================================================
|
||||
FILE: specs/001-development-environment/plan.md
|
||||
================================================================================
|
||||
|
||||
# Implementation Plan: Development environment on rom-dev01
|
||||
|
||||
**Branch**: `001-development-environment` | **Date**: 2026-08-09 | **Spec**: [spec.md](./spec.md)
|
||||
|
||||
**Input**: Feature specification from `/specs/001-development-environment/spec.md`
|
||||
|
||||
**Mode**: Documentation/design only until `rom-dev01` exists with working SSH.
|
||||
No implementation, host mutation, or Android sync/build in this planning phase.
|
||||
|
||||
## Summary
|
||||
|
||||
Feature `001` prepares an already-existing Ubuntu 24.04 host (`rom-dev01`) as the
|
||||
ROM development environment: unprivileged `android-build` account, `/srv/rom`
|
||||
layout, Lineage/AOSP host toolchain + ccache, Spec Kit meta-repo bootstrap,
|
||||
private Gitea (four repos) with off-VM Git history mirror, Ansible + Semaphore
|
||||
smoke orchestration, thin-client laptop workflow, and guest isolation posture.
|
||||
|
||||
It does **not** create the Proxmox VM, sync LineageOS, build Android, or touch
|
||||
the Pixel. Those belong to human Salt/PVE prep (`rom-dev01` prerequisite) and
|
||||
features `002`/`003`+.
|
||||
|
||||
**Unlocks**: after P1, host is usable for work; after P2, Gitea is canonical and
|
||||
orchestration smoke works → ready for `002` then `003`.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Bash / Ansible YAML; Ubuntu Server 24.04 LTS on host;
|
||||
Spec Kit docs in Markdown (English).
|
||||
|
||||
**Primary Dependencies**: apt packages per current LineageOS/AOSP host build
|
||||
docs at implementation time; `repo`; `git` + `git-lfs`; `ccache`; Gitea;
|
||||
Ansible; Semaphore UI; OpenSSH.
|
||||
|
||||
**Storage**: Host filesystem paths under `/srv/rom/` (no project-owned LVM/fstab
|
||||
changes). Secrets directory restricted/empty in `001`.
|
||||
|
||||
**Testing**: Observable shell/service checks (clean-login tool smoke, systemd
|
||||
active, local curl, rsync SHA256, restart survival). No Android instrumentation.
|
||||
|
||||
**Target Platform**: Single VM `rom-dev01` (~6 vCPU / 52 GB RAM / 2 TB /
|
||||
32 GB swap) + thin laptop (Cursor Remote SSH, adb/fastboot, rsync).
|
||||
|
||||
**Project Type**: Infrastructure / host bootstrap for Android ROM development.
|
||||
|
||||
**Performance Goals**: Toolchain available in a clean `android-build` login;
|
||||
services survive restart; no public exposure of Gitea/Semaphore. Build `-j`
|
||||
tuning is **out of scope** (owned by `003`).
|
||||
|
||||
**Constraints**:
|
||||
- VM/PVE/IP/Salt `saltenv=base` provisioning is external; do not fight managed
|
||||
config silently.
|
||||
- Never build Android as root; never `chmod 777`.
|
||||
- Never flush firewall / risk active SSH path.
|
||||
- Do not bind Gitea/Semaphore to `0.0.0.0` without an explicit protected design
|
||||
(default: loopback / non-public + SSH tunnel).
|
||||
- No secrets in Git or build logs.
|
||||
- Do not delete laptop staging tree before Gitea + mirror verified.
|
||||
|
||||
**Scale/Scope**: One developer; four Gitea repos; one smoke Ansible playbook;
|
||||
no distributed CI / registry / Kubernetes.
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
| Gate | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| Independence from SSYSTEMS governance | PASS | No Redmine/GitLab/company MR workflow; no Salt VM creation from this repo |
|
||||
| Spec-as-source | PASS | Plan derived from `001/spec.md` + constitution `0.1.5` |
|
||||
| Parity/hardening docs non-normative | PASS | Not used as requirements for `001` |
|
||||
| Host boundary: VM is prerequisite | PASS | Preconditions assume host exists; non-goals forbid PVE/qm/Salt states |
|
||||
| Isolation posture (guest) | PASS | Public-NIC workflow; UIs not world-exposed; SSH preserved |
|
||||
| No Android trees on laptop | PASS | Thin-client + `/srv/rom` on host |
|
||||
| Secrets not in Git | PASS | Explicit secrets handling |
|
||||
| Magisk/KSU/microG/signing out of `001` | PASS | Listed in DO NOT |
|
||||
| Capacity honesty | PASS | Plan around 6/52/2T/32; parallelism deferred to `003` |
|
||||
|
||||
**Post-design re-check**: PASS — artifacts (`research.md`, `quickstart.md`,
|
||||
operational `data-model.md`) stay inside `001` scope; no invented API contracts.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/001-development-environment/
|
||||
├── plan.md # This file
|
||||
├── research.md # Phase 0
|
||||
├── data-model.md # Operational entities only (no app domain model)
|
||||
├── quickstart.md # Validation / cold-start guide
|
||||
├── contracts/ # N/A for 001 (see contracts/README.md)
|
||||
└── tasks.md # Created later by /speckit-tasks — NOT this command
|
||||
```
|
||||
|
||||
### Host layout (target on rom-dev01)
|
||||
|
||||
```text
|
||||
/srv/rom/
|
||||
├── src/ # future Android trees (empty in 001; no repo sync)
|
||||
├── references/ # future AXP/reference captures (empty OK)
|
||||
├── tooling/ # project scripts / ansible / helper tooling
|
||||
├── ccache/ # CCACHE_DIR for android-build
|
||||
├── artifacts/ # handoff to laptop (dummy file for smoke)
|
||||
├── logs/ # install/bootstrap logs
|
||||
└── secrets/ # restricted; empty; no key generation in 001
|
||||
|
||||
# service data (exact paths chosen at implement time; document them)
|
||||
# e.g. /var/lib/gitea, /etc/gitea, semaphore data dir
|
||||
|
||||
# meta Spec Kit tree (staging copy, then Gitea clone)
|
||||
# e.g. /home/android-build/sunfish-a16-rom and/or /srv/rom/tooling/...
|
||||
```
|
||||
|
||||
### Meta repository content (laptop staging → Gitea)
|
||||
|
||||
```text
|
||||
sunfish-a16-rom/ # Spec Kit + docs (this tree)
|
||||
├── .specify/
|
||||
├── specs/
|
||||
├── docs/
|
||||
├── AGENTS.md
|
||||
└── …
|
||||
```
|
||||
|
||||
Companion empty repos on Gitea (no AOSP trees):
|
||||
`sunfish-rom-manifest`, `sunfish-rom-build`, `sunfish-rom-patches`.
|
||||
|
||||
**Structure Decision**: Infrastructure feature — host paths + Git/service
|
||||
bootstrap. No application `src/` tree inside Spec Kit for `001`.
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
> No constitution violations requiring justification.
|
||||
|
||||
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
||||
|-----------|------------|--------------------------------------|
|
||||
| — | — | — |
|
||||
|
||||
---
|
||||
|
||||
## 1. Summary (expanded)
|
||||
|
||||
`001` makes `rom-dev01` a usable ROM workstation and private Git home without
|
||||
performing ROM builds. Completion means: clean `android-build` toolchain smoke
|
||||
passes; `/srv/rom` owned correctly; Spec Kit tree lives on host; Gitea holds
|
||||
four repos and is canonical; laptop has an off-VM bare mirror; Ansible+Semaphore
|
||||
run one smoke playbook; thin-client + isolation docs/checks pass; no PVE/Salt
|
||||
fight, no Pixel/LOS work.
|
||||
|
||||
## 2. Constitution check / source of truth
|
||||
|
||||
Authoritative for this plan:
|
||||
|
||||
1. `.specify/memory/constitution.md` **v0.1.5**
|
||||
2. `specs/001-development-environment/spec.md`
|
||||
3. `AGENTS.md`
|
||||
|
||||
Non-normative (do not treat as `001` requirements):
|
||||
`docs/axp-pro-parity.md`, `docs/hardening-backlog.md`.
|
||||
|
||||
## 3. Preconditions
|
||||
|
||||
Assume already true before `/speckit-implement`:
|
||||
|
||||
- `rom-dev01` exists (human + SSYSTEMS Salt/PVE)
|
||||
- Ubuntu Server 24.04 LTS
|
||||
- One reachable public IPv4 (public NIC only)
|
||||
- SSH administration works
|
||||
- `saltenv=base` already applied
|
||||
- Capacity approximately: 6 vCPU / 52 GB RAM / 2 TB disk / 32 GB swap
|
||||
|
||||
Do **not** create, resize, or re-IP the VM from this project.
|
||||
|
||||
## 4. Non-goals / boundaries
|
||||
|
||||
**DO NOT** (plan / tasks / implement):
|
||||
|
||||
- create or configure the Proxmox VM; emit `qm`/PVE provisioning;
|
||||
- choose or hard-code the public IPv4;
|
||||
- write SSYSTEMS Salt states; modify `pm-test01`;
|
||||
- assume company internal DNS/VPN/LDAP/GitLab/NFS/Zabbix is required;
|
||||
- start LineageOS `repo sync` or any Android build;
|
||||
- touch/backup/flash the Pixel (NeoBackup belongs to `002`);
|
||||
- introduce microG, Phonesky, KernelSU, Magisk, SUSFS, or hardening;
|
||||
- generate ROM/AVB/Phonesky signing keys;
|
||||
- put `.repo`, `out/`, or ccache on the laptop;
|
||||
- require Ansible on the laptop;
|
||||
- expose Gitea or Semaphore to the public Internet;
|
||||
- design GitLab/Jenkins/Kubernetes/registry/distributed runners;
|
||||
- turn Semaphore into the Android build pipeline yet;
|
||||
- invent an API/data model merely to satisfy a template;
|
||||
- hard-code facts that must be measured on `rom-dev01`;
|
||||
- duplicate requirements owned by `002`/`003`+.
|
||||
|
||||
**Implement-time DO NOT** (operational):
|
||||
|
||||
- run Android builds as root; `chmod 777` project trees;
|
||||
- blindly dist-upgrade; replace apt sources without need;
|
||||
- overwrite Salt/base-managed config silently;
|
||||
- flush firewall/nftables; risk active SSH management path;
|
||||
- bind Gitea/Semaphore to `0.0.0.0` without explicit protected design;
|
||||
- commit passwords/tokens/private keys; plaintext secrets in Ansible in Git;
|
||||
- delete laptop staging before Gitea + mirror verified;
|
||||
- delete/overwrite working data only to fake idempotency;
|
||||
- download full Lineage tree; compile Lineage; connect/flash Pixel;
|
||||
- automate ROM builds through Semaphore yet.
|
||||
|
||||
**Conflict rule**: If base-managed configuration conflicts with project needs,
|
||||
**stop and report** — do not silently replace or fight it; do not “fix”
|
||||
unrelated infrastructure opportunistically.
|
||||
|
||||
## 5. Host preflight (before modifying the host)
|
||||
|
||||
First implement steps are **observational**. Capture and store under
|
||||
`/srv/rom/logs/preflight/` (or create layout first then log):
|
||||
|
||||
- Ubuntu version / kernel
|
||||
- CPU / RAM / swap
|
||||
- filesystem free space (esp. for `/` and future `/srv/rom`)
|
||||
- network interfaces / default route (confirm no required internal NIC)
|
||||
- SSH reachability
|
||||
- existing users / groups
|
||||
- existing firewall (nft/ufw/iptables) summary — **do not flush**
|
||||
- listening ports / services
|
||||
- apt sources summary
|
||||
- hints of Salt/base-managed files if obvious
|
||||
|
||||
Produce a short baseline note in the meta repo docs or `/srv/rom/logs` for later
|
||||
diff. Especially important because `saltenv=base` already touched the machine.
|
||||
|
||||
## 6. Account and permission model
|
||||
|
||||
| Actor | Role |
|
||||
|-------|------|
|
||||
| Existing admin SSH user | packages, systemd, system config, firewall changes (carefully) |
|
||||
| `android-build` | Android sources/builds (later), ccache, artifacts, build tooling; **never** build as root; **no sudo required to compile** |
|
||||
| `gitea` (service user) | Gitea data/config ownership |
|
||||
| `semaphore` (service user/context) | Semaphore data/config ownership |
|
||||
|
||||
Rules:
|
||||
|
||||
- No `chmod -R 777 /srv/rom`
|
||||
- Group memberships only as needed (e.g. `android-build` owns `/srv/rom` trees
|
||||
it writes; services own their state dirs)
|
||||
- Admin elevates only for system packaging/services
|
||||
|
||||
## 7. `/srv/rom` filesystem layout
|
||||
|
||||
Create with explicit owners/modes (exact modes chosen at implement; document):
|
||||
|
||||
```text
|
||||
/srv/rom/
|
||||
├── src/
|
||||
├── references/
|
||||
├── tooling/
|
||||
├── ccache/
|
||||
├── artifacts/
|
||||
├── logs/
|
||||
└── secrets/ # empty, restricted; do not generate keys in 001
|
||||
```
|
||||
|
||||
- Do **not** manage partitions/LVM/fstab from this project.
|
||||
- Do not populate `references/` (that is `002`) or generate secrets.
|
||||
- `artifacts/` must be writable by `android-build` for dummy + later builds.
|
||||
|
||||
## 8. Android host toolchain (no sync/build)
|
||||
|
||||
- Install host packages using **current primary LineageOS/AOSP build
|
||||
documentation at implementation time** (do not freeze a stale 50-package list
|
||||
in this plan).
|
||||
- Record what was installed (log + short note in meta repo / `/srv/rom/logs`).
|
||||
- Ensure `git`, `git-lfs`, `repo`, `python3`, and Java/toolchain prerequisites
|
||||
required by that documentation.
|
||||
- Configure `ccache`: location (`/srv/rom/ccache`), ownership (`android-build`),
|
||||
size cap, environment (`CCACHE_DIR`, etc.). **Not** tied to inventing `-j`
|
||||
from vCPU/RAM here.
|
||||
- FR-007: document capacity (6/52/32) and that **conservative `-j` / OOM tuning
|
||||
belongs to `003`**, with a one-line recommended starting point only if needed
|
||||
for docs — no build execution in `001`.
|
||||
- Smoke from a **clean login**: `sudo -iu android-build` → verify tools; **no
|
||||
`repo sync`**.
|
||||
|
||||
## 9. Spec Kit staging bootstrap (before Gitea)
|
||||
|
||||
Egg/chicken sequence (mandatory):
|
||||
|
||||
```text
|
||||
laptop staging:
|
||||
/home/aventura/Workspaces/sunfish-a16-rom
|
||||
↓ rsync/scp/git bundle (preserve .git)
|
||||
rom-dev01 working copy
|
||||
↓
|
||||
install Gitea
|
||||
↓
|
||||
create empty Gitea repo sunfish-a16-rom
|
||||
↓
|
||||
push meta repo
|
||||
↓
|
||||
create sunfish-rom-manifest, sunfish-rom-build, sunfish-rom-patches
|
||||
↓
|
||||
Gitea becomes canonical remote
|
||||
```
|
||||
|
||||
Do **not** assume `git clone https://gitea...` before Gitea exists.
|
||||
Do **not** delete laptop staging until Gitea push + off-VM mirror verified.
|
||||
|
||||
## 10. Gitea
|
||||
|
||||
- Install on `rom-dev01` with persistent data dirs and systemd unit.
|
||||
- Default access: **loopback / non-public bind + SSH tunnel** from laptop
|
||||
(decision fixed for `001` unless implement discovers a hard conflict — then
|
||||
stop/report).
|
||||
- Create admin credentials with restricted local storage; never commit secrets.
|
||||
- Verify: service active; local curl succeeds; direct public Internet access to
|
||||
UI **not** required / not open.
|
||||
|
||||
## 11. Canonical Git transition
|
||||
|
||||
Repos:
|
||||
|
||||
1. `sunfish-a16-rom` (meta Spec Kit/docs) — push existing history
|
||||
2. `sunfish-rom-manifest` — empty
|
||||
3. `sunfish-rom-build` — empty (future Ansible/scripts home)
|
||||
4. `sunfish-rom-patches` — empty
|
||||
|
||||
Document remotes for host + laptop clones. Company GitLab must not be used.
|
||||
|
||||
## 12. Off-VM Git mirror (P2)
|
||||
|
||||
First implementation (sufficient for `001` SC-007):
|
||||
|
||||
```text
|
||||
Gitea repos → bare mirrors on laptop (or equivalent off-VM path)
|
||||
```
|
||||
|
||||
Borg / full Gitea disaster recovery is **later**, not required to close `001`.
|
||||
Requirement is **Git history** redundancy, not VM image backup.
|
||||
|
||||
## 13. Ansible bootstrap (P2)
|
||||
|
||||
- Install Ansible on `rom-dev01` for **project environment** automation.
|
||||
- Keep playbooks in meta repo or `sunfish-rom-build` once created.
|
||||
- No plaintext secrets in Git (use local ansible vault / restricted files outside
|
||||
Git if needed in `001` — prefer deferred secrets).
|
||||
|
||||
## 14. Semaphore bootstrap (P2)
|
||||
|
||||
- Install Semaphore as UI over Ansible.
|
||||
- Same exposure model as Gitea (loopback/tunnel).
|
||||
- First integration: **small localhost/environment smoke playbook only** —
|
||||
prove Semaphore can run Ansible. **Not** Android build pipeline.
|
||||
|
||||
## 15. Isolation / firewall / service exposure
|
||||
|
||||
Keep guest isolation posture from constitution/`001` spec:
|
||||
|
||||
- Public NIC only for project workflow
|
||||
- Gitea/Semaphore not world-exposed
|
||||
- Document firewall/DNS expectations
|
||||
|
||||
Implementation safety:
|
||||
|
||||
- never flush/replace existing firewall blindly;
|
||||
- never close current SSH path before a tested replacement;
|
||||
- keep a rollback path;
|
||||
- prefer additive allow rules.
|
||||
|
||||
## 16. Laptop thin-client workflow
|
||||
|
||||
Document and smoke:
|
||||
|
||||
1. Cursor Remote SSH → host workspace as `android-build` (or documented path)
|
||||
2. Dummy artifact in `/srv/rom/artifacts` → `rsync` to laptop → SHA256 match
|
||||
3. adb/fastboot remain on laptop; Pixel USB on laptop; no USB passthrough design
|
||||
|
||||
## 17. Verification matrix (FR/SC → evidence)
|
||||
|
||||
| ID | Implementation focus | Observable verification |
|
||||
|----|----------------------|-------------------------|
|
||||
| FR-001 | Create `android-build` + home/workspace docs | `id android-build`; login shell works |
|
||||
| FR-002 | LOS/AOSP host deps + ccache | clean-shell: `git`, `repo`, `ccache -s`, etc. |
|
||||
| FR-003 | `/srv/rom` tree + ownership | `namei -l` / `stat` shows owners; writable artifacts |
|
||||
| FR-004 | Gitea + four repos | local UI/API; four repos listed |
|
||||
| FR-005 | Ansible + Semaphore smoke | Semaphore runs smoke playbook successfully |
|
||||
| FR-006 | Thin-client docs | doc exists; Remote SSH + rsync smoke done |
|
||||
| FR-007 | Capacity / defer `-j` to `003` | short doc records 6/52/32 and defers build jobs |
|
||||
| FR-008 | Spec Kit on host | tree present; after P2, cloned/pushed via Gitea |
|
||||
| FR-009 | Isolation posture | checklist: NIC, binds, firewall notes; SSH still works |
|
||||
| FR-010 | Off-VM Git mirror | laptop bare mirror of four repos once |
|
||||
| SC-001 | Toolchain smoke | clean `android-build` session has tools for later `003` |
|
||||
| SC-002 | Artifacts handoff | dummy file rsync SHA256 match |
|
||||
| SC-003 | Four Gitea repos | listed on Gitea; not company GitLab |
|
||||
| SC-004 | Cold-start workflow doc | quickstart path SSH→workspace→(later build)→rsync→flash |
|
||||
| SC-005 | No PVE management | no qm/PVE playbooks in repo/tasks evidence |
|
||||
| SC-006 | Isolation checklist | passes without requiring VPN/internal DNS |
|
||||
| SC-007 | Mirror demonstrated | off-VM mirror exists and was verified once |
|
||||
|
||||
## 18. Handoff
|
||||
|
||||
**`001` complete** means environment ready for `002` (phone capture) and later
|
||||
`003` (LOS vanilla build) — **not** “start building Lineage now”.
|
||||
|
||||
Do not begin `/speckit-plan` for `002`/`003` until `001` doc cycle + implement
|
||||
are done (avoid document saturation).
|
||||
|
||||
## P1 / P2 sequencing
|
||||
|
||||
### P1 — host usable without Gitea
|
||||
|
||||
1. Host preflight baseline
|
||||
2. Create `android-build`
|
||||
3. Create `/srv/rom` + permissions
|
||||
4. Install build prerequisites (current LOS/AOSP docs)
|
||||
5. `repo` / `git` / `git-lfs` / ccache config
|
||||
6. Copy laptop staging meta repo to host (preserve `.git`)
|
||||
7. Clean-shell toolchain smoke
|
||||
8. Cursor Remote SSH smoke
|
||||
9. Dummy artifact → rsync → laptop (SHA256)
|
||||
|
||||
### P2 — reproducible / comfortable
|
||||
|
||||
1. Install Gitea (loopback/tunnel)
|
||||
2. Create four repos
|
||||
3. Push meta repo; set Gitea canonical
|
||||
4. Off-VM bare mirrors on laptop
|
||||
5. Install Ansible
|
||||
6. First smoke playbook
|
||||
7. Install Semaphore
|
||||
8. Run smoke playbook from Semaphore
|
||||
9. Isolation / access / firewall validation (SSH-safe)
|
||||
10. Service restart (+ reboot survival where practical)
|
||||
|
||||
Finish P2 before formally starting `002`.
|
||||
|
||||
## Phase outputs
|
||||
|
||||
| Artifact | Role |
|
||||
|----------|------|
|
||||
| [research.md](./research.md) | Decisions: Gitea/Semaphore access, mirror, deps source, ccache |
|
||||
| [data-model.md](./data-model.md) | Operational entities only |
|
||||
| [quickstart.md](./quickstart.md) | Cold-start validation |
|
||||
| [contracts/](./contracts/) | N/A |
|
||||
|
||||
Next command after human review of these files: `/speckit-tasks` (still no VM).
|
||||
Then `/speckit-analyze`. Stop before `/speckit-implement` until SSH to
|
||||
`rom-dev01` works.
|
||||
|
||||
================================================================================
|
||||
FILE: specs/001-development-environment/research.md
|
||||
================================================================================
|
||||
|
||||
# Research: 001-development-environment
|
||||
|
||||
Phase 0 decisions for planning. Implementation may refine versions using live
|
||||
primary docs on `rom-dev01`.
|
||||
|
||||
## R1 — Gitea access model
|
||||
|
||||
**Decision**: Bind Gitea to loopback (or other non-public address) and access via
|
||||
SSH local port forward from the laptop. Do not require public HTTPS exposure.
|
||||
|
||||
**Rationale**: Constitution/`001` require private project Git without unnecessary
|
||||
Internet exposure; single developer; SSH already required for admin/Remote SSH.
|
||||
|
||||
**Alternatives considered**:
|
||||
- Public HTTPS + firewall allowlist — rejected for `001` (more moving parts;
|
||||
accidental exposure risk).
|
||||
- VPN-only bind — rejected as a *required* path (may exist externally; project
|
||||
must not depend on company VPN).
|
||||
|
||||
## R2 — Semaphore access model
|
||||
|
||||
**Decision**: Same as Gitea — loopback/non-public + SSH tunnel. First job is a
|
||||
localhost/environment smoke playbook only.
|
||||
|
||||
**Rationale**: Semaphore is orchestration UI, not a public portal; Android build
|
||||
pipeline is explicitly out of scope for `001`.
|
||||
|
||||
**Alternatives considered**: Public Semaphore — rejected. Full ROM pipeline in
|
||||
Semaphore — deferred past `003` manual first build.
|
||||
|
||||
## R3 — Off-VM Git history backup
|
||||
|
||||
**Decision**: Laptop-side **bare mirrors** of the four Gitea repos for `001`
|
||||
(SC-007). Borg/full Gitea DR later.
|
||||
|
||||
**Rationale**: Spec requires off-VM copy of project Git history, not a complete
|
||||
backup platform. Simplest path that meets SC-007.
|
||||
|
||||
**Alternatives considered**: Borg-only — optional later. Second server — not
|
||||
needed for `001`.
|
||||
|
||||
## R4 — Lineage/AOSP host dependencies
|
||||
|
||||
**Decision**: At implement time, follow **current primary LineageOS / AOSP host
|
||||
build documentation** for Ubuntu; record installed package set in logs. Do not
|
||||
freeze a long package list in the plan.
|
||||
|
||||
**Rationale**: Dependency lists drift; stale pins cause false confidence.
|
||||
|
||||
**Alternatives considered**: Copy a historical package list from blogs —
|
||||
rejected.
|
||||
|
||||
## R5 — `repo` installation source
|
||||
|
||||
**Decision**: Install Google's `repo` launcher via the method recommended by
|
||||
current Lineage/AOSP docs (typically curl to `~/bin/repo` or distro package if
|
||||
still adequate); verify `repo --version` as `android-build`.
|
||||
|
||||
**Rationale**: Align with upstream bring-up docs used for `003`.
|
||||
|
||||
## R6 — ccache policy vs build parallelism
|
||||
|
||||
**Decision**: `001` configures `CCACHE_DIR=/srv/rom/ccache` (or equivalent),
|
||||
ownership for `android-build`, and a disk size cap. Document host capacity
|
||||
(6 vCPU / 52 GB / 32 GB swap). **Defer `-j` / OOM tuning to `003`.**
|
||||
|
||||
**Rationale**: ccache is storage/env; parallel link/compile jobs belong to the
|
||||
first real build feature.
|
||||
|
||||
**Alternatives considered**: Encoding `-j$(nproc)` defaults in `001` — rejected
|
||||
as premature and confusing with FR-007 (document capacity; don't run builds).
|
||||
|
||||
## R7 — Meta-repo bootstrap before Gitea
|
||||
|
||||
**Decision**: Copy laptop staging Git tree to host first (rsync/scp/bundle
|
||||
preserving `.git`), install Gitea, create repos, push, then mark Gitea
|
||||
canonical. Keep laptop staging until mirror verified.
|
||||
|
||||
**Rationale**: Avoid chicken/egg `git clone` against non-existent Gitea.
|
||||
|
||||
## R8 — Coexistence with `saltenv=base`
|
||||
|
||||
**Decision**: Preflight + stop/report on conflicts with base-managed config.
|
||||
Project Ansible may manage **project** paths/services; must not silently rewrite
|
||||
Salt-owned system policy.
|
||||
|
||||
**Rationale**: Host is dual-touched (SSYSTEMS base then project). Fighting Salt
|
||||
causes flapping.
|
||||
|
||||
## R9 — data-model / contracts
|
||||
|
||||
**Decision**: No application domain model or HTTP API contracts for `001`.
|
||||
Operational entities only in `data-model.md`. `contracts/` marked N/A.
|
||||
|
||||
**Rationale**: Infrastructure bootstrap feature; inventing APIs would be template
|
||||
noise.
|
||||
|
||||
================================================================================
|
||||
FILE: specs/001-development-environment/data-model.md
|
||||
================================================================================
|
||||
|
||||
# Data model (operational): 001-development-environment
|
||||
|
||||
This is **not** an application domain model. It records host/Git/service
|
||||
entities for planning clarity. No ORM, no API schemas.
|
||||
|
||||
## Entities
|
||||
|
||||
### Host (`rom-dev01`)
|
||||
|
||||
| Field | Notes |
|
||||
|-------|-------|
|
||||
| OS | Ubuntu 24.04 LTS (precondition) |
|
||||
| Capacity | ~6 vCPU / 52 GB / 2 TB / 32 GB swap |
|
||||
| Network | Public IPv4 NIC; no required internal NIC |
|
||||
| Management | External Salt `saltenv=base` + project config |
|
||||
|
||||
### Account `android-build`
|
||||
|
||||
| Field | Notes |
|
||||
|-------|-------|
|
||||
| Type | Unprivileged login user |
|
||||
| Owns | `/srv/rom/{src,references,tooling,ccache,artifacts,logs}` (as documented) |
|
||||
| Must not | Need root to compile; own Gitea/Semaphore system dirs |
|
||||
|
||||
### Path root `/srv/rom`
|
||||
|
||||
| Child | Purpose | Populated in 001? |
|
||||
|-------|---------|-------------------|
|
||||
| `src/` | Future Android trees | Empty (no sync) |
|
||||
| `references/` | Future AXP/reference | Empty |
|
||||
| `tooling/` | Scripts/ansible helpers | Partial OK |
|
||||
| `ccache/` | CCACHE_DIR | Yes (dir + env) |
|
||||
| `artifacts/` | Laptop handoff | Dummy file for smoke |
|
||||
| `logs/` | Bootstrap/preflight logs | Yes |
|
||||
| `secrets/` | Restricted placeholder | Empty; no keygen |
|
||||
|
||||
### GiteaInstance
|
||||
|
||||
| Field | Notes |
|
||||
|-------|-------|
|
||||
| Bind | Loopback / non-public |
|
||||
| Repos | `sunfish-a16-rom`, `sunfish-rom-manifest`, `sunfish-rom-build`, `sunfish-rom-patches` |
|
||||
| Canonical | Yes after first successful push of meta repo |
|
||||
|
||||
### GitMirror (off-VM)
|
||||
|
||||
| Field | Notes |
|
||||
|-------|-------|
|
||||
| Location | Laptop bare mirrors (initial) |
|
||||
| Scope | All four project repos |
|
||||
| Success | At least one verified mirror cycle |
|
||||
|
||||
### AnsibleController / SemaphoreInstance
|
||||
|
||||
| Field | Notes |
|
||||
|-------|-------|
|
||||
| Host | `rom-dev01` |
|
||||
| First job | Environment smoke playbook |
|
||||
| Exposure | Same private access model as Gitea |
|
||||
|
||||
## Relationships
|
||||
|
||||
```text
|
||||
AdminSSH ──manages──► Host packages/systemd/firewall
|
||||
android-build ──writes──► /srv/rom (build-related trees)
|
||||
GiteaInstance ──hosts──► four Repositories
|
||||
Laptop ──mirrors──► Repositories (bare)
|
||||
SemaphoreInstance ──runs──► Ansible smoke playbook on Host
|
||||
Laptop Cursor ──RemoteSSH──► Host workspace
|
||||
Laptop ──rsync──► /srv/rom/artifacts (pull)
|
||||
```
|
||||
|
||||
## State transitions (meta Git)
|
||||
|
||||
1. `laptop-staging-only`
|
||||
2. `copied-to-host` (pre-Gitea)
|
||||
3. `gitea-canonical` (push complete)
|
||||
4. `mirrored-off-vm` (SC-007)
|
||||
|
||||
Do not destroy state (1) until (3) and (4) succeed.
|
||||
|
||||
================================================================================
|
||||
FILE: specs/001-development-environment/quickstart.md
|
||||
================================================================================
|
||||
|
||||
# Quickstart / validation: 001-development-environment
|
||||
|
||||
Use after `/speckit-implement` on a real `rom-dev01`. Until the VM exists, treat
|
||||
this as the acceptance script shape.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- SSH to `rom-dev01` as admin works
|
||||
- You are ready to create `android-build` and `/srv/rom` (P1)
|
||||
- Laptop has `rsync`, `ssh`, Cursor Remote SSH
|
||||
|
||||
## P1 validation path
|
||||
|
||||
### 1. Preflight captured
|
||||
|
||||
```bash
|
||||
# On host (admin) — exact commands filled at implement time
|
||||
# Expect: Ubuntu 24.04, disk/RAM/swap notes, firewall summary saved
|
||||
```
|
||||
|
||||
### 2. Switch to build user
|
||||
|
||||
```bash
|
||||
sudo -iu android-build
|
||||
pwd # documented workspace
|
||||
```
|
||||
|
||||
### 3. Toolchain smoke (clean shell)
|
||||
|
||||
```bash
|
||||
git --version
|
||||
git lfs version
|
||||
repo --version
|
||||
python3 --version
|
||||
ccache -s
|
||||
# plus java/other tools required by current LOS/AOSP host docs
|
||||
```
|
||||
|
||||
Expected: all commands succeed without sudo.
|
||||
|
||||
### 4. Layout
|
||||
|
||||
```bash
|
||||
namei -l /srv/rom /srv/rom/artifacts /srv/rom/ccache
|
||||
touch /srv/rom/artifacts/.write_test && rm /srv/rom/artifacts/.write_test
|
||||
```
|
||||
|
||||
### 5. Meta repo present on host (pre-Gitea OK)
|
||||
|
||||
```bash
|
||||
# path documented at implement — must contain .git and specs/
|
||||
test -d /path/to/sunfish-a16-rom/.git
|
||||
test -f /path/to/sunfish-a16-rom/specs/001-development-environment/spec.md
|
||||
```
|
||||
|
||||
### 6. Cursor Remote SSH
|
||||
|
||||
From laptop: open host workspace; edit a trivial file; confirm it is on the VM
|
||||
disk (not only local).
|
||||
|
||||
### 7. Artifact rsync smoke
|
||||
|
||||
On host:
|
||||
|
||||
```bash
|
||||
echo '001-smoke' > /srv/rom/artifacts/dummy-001.txt
|
||||
sha256sum /srv/rom/artifacts/dummy-001.txt
|
||||
```
|
||||
|
||||
On laptop:
|
||||
|
||||
```bash
|
||||
rsync -avz USER@ROM_DEV01:/srv/rom/artifacts/dummy-001.txt ./
|
||||
sha256sum ./dummy-001.txt # must match
|
||||
```
|
||||
|
||||
## P2 validation path
|
||||
|
||||
### 8. Gitea private access
|
||||
|
||||
```bash
|
||||
# SSH tunnel example (ports chosen at implement):
|
||||
# ssh -L 3000:127.0.0.1:3000 USER@ROM_DEV01
|
||||
# curl -fsS http://127.0.0.1:3000/ → success via tunnel
|
||||
```
|
||||
|
||||
Confirm UI not relied upon as public Internet service.
|
||||
|
||||
### 9. Four repositories
|
||||
|
||||
In Gitea: `sunfish-a16-rom`, `sunfish-rom-manifest`, `sunfish-rom-build`,
|
||||
`sunfish-rom-patches`. Meta repo history visible after push.
|
||||
|
||||
### 10. Off-VM mirror
|
||||
|
||||
On laptop: bare clones/mirrors of all four; `git fsck` or fetch succeeds.
|
||||
|
||||
### 11. Semaphore smoke
|
||||
|
||||
Semaphore runs the environment smoke playbook successfully (localhost/host
|
||||
check only — not Android build).
|
||||
|
||||
### 12. Restart survival
|
||||
|
||||
```bash
|
||||
sudo systemctl restart gitea # unit names as installed
|
||||
sudo systemctl restart <semaphore>
|
||||
# optional: reboot when safe; confirm SSH + services return
|
||||
```
|
||||
|
||||
### 13. Isolation checklist
|
||||
|
||||
- No required internal NIC for workflow
|
||||
- Gitea/Semaphore binds documented as non-public
|
||||
- SSH still works after firewall changes
|
||||
- Day-to-day docs do not require company VPN/internal DNS
|
||||
|
||||
## Done means
|
||||
|
||||
`001` complete → start **`002`** (AXP capture / NeoBackup).
|
||||
Do **not** start Lineage `repo sync` / build as part of `001` success.
|
||||
|
||||
================================================================================
|
||||
FILE: specs/001-development-environment/contracts/README.md
|
||||
================================================================================
|
||||
|
||||
# Contracts: N/A for 001
|
||||
|
||||
Feature `001-development-environment` is host/Git/service bootstrap.
|
||||
|
||||
It does **not** expose a project-owned HTTP API, CLI contract for external
|
||||
consumers, or IPC schema that needs `contracts/` files.
|
||||
|
||||
Service access is operational (SSH tunnel to Gitea/Semaphore UIs) and is
|
||||
documented in `plan.md` / `quickstart.md` instead.
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
001 tasks review pack — for ChatGPT
|
||||
Generated: 2026-08-09T12:30:10+02:00
|
||||
|
||||
================================================================================
|
||||
FILE: specs/001-development-environment/tasks.md
|
||||
================================================================================
|
||||
|
||||
# Tasks: Development environment on rom-dev01
|
||||
|
||||
**Input**: Design documents from `/specs/001-development-environment/`
|
||||
|
||||
**Prerequisites**: plan.md (required), spec.md, research.md, data-model.md,
|
||||
quickstart.md, contracts/ (N/A)
|
||||
|
||||
**Tests**: Observational verify steps embedded in tasks (no separate TDD suite).
|
||||
|
||||
**Organization**: Setup → Foundational (preflight) → User stories by priority →
|
||||
Polish. **Do not run these tasks until `rom-dev01` SSH works.** Generating this
|
||||
file is documentation-only.
|
||||
|
||||
**Canonical paths**:
|
||||
- Meta Spec Kit tree: `/home/android-build/sunfish-a16-rom`
|
||||
- Data root: `/srv/rom/`
|
||||
- Automation repo (after Gitea): `sunfish-rom-build` (not the meta repo)
|
||||
|
||||
## Format: `[ID] [P?] [Story] Description`
|
||||
|
||||
- **[P]**: Can run in parallel (different files, no incomplete dependencies)
|
||||
- **[Story]**: US1…US5 from spec.md
|
||||
- Every task includes a path and an observable verify hint
|
||||
|
||||
## Path Conventions
|
||||
|
||||
Host paths are absolute on `rom-dev01`. Docs/logs also land under
|
||||
`/home/android-build/sunfish-a16-rom/docs/` or `/srv/rom/logs/` as noted.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Setup (docs readiness — can be done on laptop before VM)
|
||||
|
||||
- [ ] T001 Confirm active feature is `specs/001-development-environment` via `.specify/feature.json` and that constitution is `0.1.5` in `.specify/memory/constitution.md`
|
||||
- [ ] T002 [P] Create host-facing doc stub `docs/001-host-runbook.md` in meta repo (preflight results, paths, Gitea tunnel notes — fill during implement)
|
||||
- [ ] T003 [P] Create FR/SC evidence checklist stub `docs/001-verification-matrix.md` mapping each FR-*/SC-* from `specs/001-development-environment/spec.md` to blank evidence fields
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Foundational (blocking — host preflight before stories)
|
||||
|
||||
**Goal**: Observe `rom-dev01` without fighting `saltenv=base`; abort on conflict.
|
||||
|
||||
- [ ] T004 On `rom-dev01` as admin, capture preflight baseline into `/srv/rom/logs/preflight/` (create `/srv/rom/logs` with safe perms if needed): Ubuntu/kernel, CPU/RAM/swap, disk free, interfaces/routes, users, firewall summary (**do not flush**), listening ports, apt sources → also summarize in `docs/001-host-runbook.md`
|
||||
- [ ] T005 Record coexistence rule in `docs/001-host-runbook.md`: if base-managed config conflicts with project needs, **stop and report**; do not silently replace Salt-managed settings
|
||||
- [ ] T006 Verify SSH admin path still works after any read-only inspection; note rollback contacts/commands in `docs/001-host-runbook.md`
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: User Story 1 — Reachable build workspace (P1)
|
||||
|
||||
**Story goal**: `android-build` exists with documented workspace; `/srv/rom` owned correctly; meta tree at fixed path.
|
||||
|
||||
**Independent test**: `sudo -iu android-build` works; `/srv/rom/artifacts` writable; `/home/android-build/sunfish-a16-rom` contains Spec Kit tree (after T012).
|
||||
|
||||
### Implementation
|
||||
|
||||
- [ ] T007 [US1] Create unprivileged user `android-build` with home `/home/android-build` (admin); document uid/gid in `docs/001-host-runbook.md`
|
||||
- [ ] T008 [US1] Create `/srv/rom/{src,references,tooling,ccache,artifacts,logs,secrets}` with ownership for `android-build` on writable trees; `secrets/` restricted/empty — document modes in `docs/001-host-runbook.md`
|
||||
- [ ] T009 [US1] Verify: `namei -l /srv/rom /srv/rom/artifacts` and `sudo -iu android-build touch /srv/rom/artifacts/.write_test` succeeds; no `chmod 777`
|
||||
- [ ] T010 [US1] Document account model (admin vs `android-build` vs service users) in `docs/001-host-runbook.md` — never build Android as root
|
||||
- [ ] T011 [US1] Copy laptop staging Git tree to `/home/android-build/sunfish-a16-rom` preserving `.git` (rsync/scp/bundle); verify `test -f /home/android-build/sunfish-a16-rom/specs/001-development-environment/spec.md`
|
||||
- [ ] T012 [US1] Ensure `/srv/rom/tooling` is **not** used as Spec Kit checkout; note distinction in `docs/001-host-runbook.md`
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: User Story 2 — Android host toolchain (P1)
|
||||
|
||||
**Story goal**: Clean-login toolchain ready for later `003` (no `repo sync` / build).
|
||||
|
||||
**Independent test**: `sudo -iu android-build` → `git`, `git lfs`, `repo`, `python3`, `ccache -s`, and LOS-doc Java/prereqs succeed.
|
||||
|
||||
### Implementation
|
||||
|
||||
- [ ] T013 [US2] As admin, install host packages per **current** primary LineageOS/AOSP Ubuntu build documentation; record exact package list in `/srv/rom/logs/toolchain-packages.txt`
|
||||
- [ ] T014 [US2] Install/configure `repo` for `android-build` per current docs; verify `sudo -iu android-build repo --version`
|
||||
- [ ] T015 [US2] Ensure `git` + `git-lfs` for `android-build`; verify `sudo -iu android-build git lfs version`
|
||||
- [ ] T016 [US2] Configure ccache: `CCACHE_DIR=/srv/rom/ccache`, ownership `android-build`, size cap; document env in `/home/android-build/.bashrc` or `/home/android-build/.profile` and `docs/001-host-runbook.md`
|
||||
- [ ] T017 [US2] Verify: `sudo -iu android-build ccache -s` shows configured cache dir
|
||||
- [ ] T018 [US2] Document FR-007 capacity (6 vCPU / 52 GB / 32 GB swap) and **defer `-j`/OOM tuning to `003`** in `docs/001-host-runbook.md` — do not run a Lineage build
|
||||
- [ ] T019 [US2] Clean-shell toolchain smoke checklist executed; paste command outputs into `/srv/rom/logs/toolchain-smoke.txt` and tick FR-002/SC-001 in `docs/001-verification-matrix.md`
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: User Story 5 — Laptop thin client (P1/P2 overlap — do after US1–US2)
|
||||
|
||||
**Story goal**: Cursor Remote SSH + artifact rsync proven; Pixel stays on laptop USB.
|
||||
|
||||
**Independent test**: Remote SSH edit on host; dummy artifact SHA256 matches after rsync.
|
||||
|
||||
### Implementation
|
||||
|
||||
- [ ] T020 [US5] Document Cursor Remote SSH → `/home/android-build/sunfish-a16-rom` in `docs/001-host-runbook.md` and `specs/001-development-environment/quickstart.md` (update if needed)
|
||||
- [ ] T021 [US5] Create `/srv/rom/artifacts/dummy-001.txt` as `android-build`; record `sha256sum` in `/srv/rom/logs/rsync-smoke.txt`
|
||||
- [ ] T022 [US5] From laptop, `rsync` dummy artifact; verify SHA256 match; record laptop path in `/srv/rom/logs/rsync-smoke.txt` and `docs/001-verification-matrix.md` (SC-002)
|
||||
- [ ] T023 [US5] Document adb/fastboot-on-laptop / no USB passthrough rule in `docs/001-host-runbook.md` (SC-004 partial)
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: User Story 3 — Gitea, Ansible, Semaphore, off-VM mirror (P2)
|
||||
|
||||
**Story goal**: Private Gitea with four repos; canonical meta remote; laptop pull mirrors; unprivileged Semaphore smoke via Ansible in `sunfish-rom-build`.
|
||||
|
||||
**Independent test**: Four repos on Gitea; meta history pushed; laptop `git clone --mirror` works; Semaphore runs unprivileged smoke.
|
||||
|
||||
### Implementation
|
||||
|
||||
- [ ] T024 [US3] Install Gitea on `rom-dev01` with systemd + persistent data; bind UI to loopback/non-public; document unit/paths in `docs/001-host-runbook.md`
|
||||
- [ ] T025 [US3] Store Gitea admin credentials only in restricted host location under `/srv/rom/secrets/` or service-native secret path — **never** commit to Git; document location (not secrets) in `docs/001-host-runbook.md`
|
||||
- [ ] T026 [US3] Verify: local `curl` to Gitea UI succeeds; confirm not relying on public Internet exposure; record bind address in `docs/001-host-runbook.md`
|
||||
- [ ] T027 [US3] Document Git transport chosen after host inspection (HTTP via SSH tunnel and/or tunneled Git SSH); **do not** open public `:2222` or blindly edit `saltenv=base` sshd — write choice in `docs/001-host-runbook.md`
|
||||
- [ ] T028 [US3] Create Gitea repos: `sunfish-a16-rom`, `sunfish-rom-manifest`, `sunfish-rom-build`, `sunfish-rom-patches`
|
||||
- [ ] T029 [US3] Push `/home/android-build/sunfish-a16-rom` history to Gitea `sunfish-a16-rom`; set `origin` to Gitea; verify remote in that directory
|
||||
- [ ] T030 [US3] Seed minimal structure in `sunfish-rom-build` for Ansible (e.g. `ansible/` playbooks path) — **not** inside Spec Kit meta repo
|
||||
- [ ] T031 [US3] Install Ansible on `rom-dev01`; document version in `docs/001-host-runbook.md`
|
||||
- [ ] T032 [US3] Add unprivileged smoke playbook in `sunfish-rom-build` (gather_facts + asserts for `/srv/rom`, `android-build`, toolchain); **no become/sudo secrets**
|
||||
- [ ] T033 [US3] Run smoke playbook successfully via `ansible-playbook` CLI as documented non-root/project user; log output to `/srv/rom/logs/ansible-smoke.txt`
|
||||
- [ ] T034 [US3] Install Semaphore; bind like Gitea (loopback/tunnel); no public exposure; document in `docs/001-host-runbook.md`
|
||||
- [ ] T035 [US3] Wire Semaphore to run the **same unprivileged** smoke playbook only; execute once successfully; evidence in `/srv/rom/logs/semaphore-smoke.txt` (FR-005)
|
||||
- [ ] T036 [US3] From **laptop**, create bare mirrors with `git clone --mirror` for all four repos (laptop initiates connection); run `git remote update` + `git fsck`; document mirror paths in `docs/001-host-runbook.md` (FR-010/SC-007)
|
||||
- [ ] T037 [US3] Confirm laptop staging `/home/aventura/Workspaces/sunfish-a16-rom` is **retained** until T029+T036 verified; only then optionally mark staging as non-canonical in `docs/001-host-runbook.md`
|
||||
|
||||
---
|
||||
|
||||
## Phase 7: User Story 4 — Guest isolation (P2)
|
||||
|
||||
**Story goal**: Isolation checklist passes without breaking SSH.
|
||||
|
||||
**Independent test**: Public-NIC-only workflow; UIs non-public; SSH still works; no VPN/internal DNS required in docs.
|
||||
|
||||
### Implementation
|
||||
|
||||
- [ ] T038 [US4] Document interfaces/routes: project workflow requires only public NIC — `docs/001-host-runbook.md` + evidence in `docs/001-verification-matrix.md` (SC-006)
|
||||
- [ ] T039 [US4] Apply isolation/firewall guidance **additively** if needed: never flush nftables/iptables; never close active SSH before tested alternative; record before/after in `/srv/rom/logs/firewall-notes.txt`
|
||||
- [ ] T040 [US4] Re-verify Gitea/Semaphore binds remain non-public; SSH admin + tunnel still work — update `docs/001-verification-matrix.md` FR-009/SC-006
|
||||
- [ ] T041 [US4] Confirm day-to-day runbook does not require SSYSTEMS VPN/internal DNS/LDAP/GitLab/NFS/Zabbix — `docs/001-host-runbook.md`
|
||||
|
||||
---
|
||||
|
||||
## Phase 8: Polish & cross-cutting
|
||||
|
||||
- [ ] T042 [P] Fill all FR-*/SC-* evidence rows in `docs/001-verification-matrix.md` (including SC-005: no PVE/qm/Salt VM tasks were performed)
|
||||
- [ ] T043 [P] Align `specs/001-development-environment/quickstart.md` with final ports/paths/tunnel commands actually used
|
||||
- [ ] T044 Restart Gitea (+ Semaphore) via systemd; confirm recovery; optional reboot when safe; note results in `/srv/rom/logs/restart-smoke.txt`
|
||||
- [ ] T045 Declare handoff in `docs/001-host-runbook.md`: **`001` complete → proceed to `002`**, do not start Lineage sync/build
|
||||
- [ ] T046 Ensure no secrets/tokens landed in `/home/android-build/sunfish-a16-rom` or `sunfish-rom-build` Git history (`git grep` / review)
|
||||
|
||||
---
|
||||
|
||||
## Dependencies & story order
|
||||
|
||||
```text
|
||||
Phase 1 (laptop docs)
|
||||
↓
|
||||
Phase 2 preflight (host)
|
||||
↓
|
||||
US1 workspace + /srv/rom + meta copy
|
||||
↓
|
||||
US2 toolchain ──────────────┐
|
||||
↓ │
|
||||
US5 thin-client smokes ←───┘ (needs artifacts + meta path)
|
||||
↓
|
||||
US3 Gitea → repos → Ansible in sunfish-rom-build → Semaphore → laptop mirrors
|
||||
↓
|
||||
US4 isolation hardening/validation
|
||||
↓
|
||||
Polish / handoff → STOP (wait was already for implement; next feature 002)
|
||||
```
|
||||
|
||||
**MVP (minimum useful host)**: complete through US2 + US5 (T007–T023) even if Gitea delayed — but **formal `001` done** requires P2 (US3+US4+polish) per plan.
|
||||
|
||||
## Parallel opportunities
|
||||
|
||||
- T002/T003 on laptop before VM
|
||||
- After T008: T010 docs can parallel T011 copy if disk ready
|
||||
- T013–T015 package/`repo`/`git-lfs` partly serial (apt) then T016 ccache
|
||||
- T042/T043 polish docs in parallel after evidence exists
|
||||
|
||||
## FR/SC coverage map
|
||||
|
||||
| ID | Tasks |
|
||||
|----|-------|
|
||||
| FR-001 | T007–T010 |
|
||||
| FR-002 | T013–T017, T019 |
|
||||
| FR-003 | T008–T009, T012 |
|
||||
| FR-004 | T024–T029 |
|
||||
| FR-005 | T030–T035 |
|
||||
| FR-006 | T020–T023 |
|
||||
| FR-007 | T018 |
|
||||
| FR-008 | T011, T029 |
|
||||
| FR-009 | T038–T041 |
|
||||
| FR-010 | T036–T037 |
|
||||
| SC-001 | T019 |
|
||||
| SC-002 | T021–T022 |
|
||||
| SC-003 | T028–T029 |
|
||||
| SC-004 | T020, T023, T045 |
|
||||
| SC-005 | T005, T042 |
|
||||
| SC-006 | T038–T041 |
|
||||
| SC-007 | T036 |
|
||||
|
||||
## Implementation strategy
|
||||
|
||||
1. Do **not** execute host tasks until SSH to `rom-dev01` works.
|
||||
2. After this `tasks.md` is approved: `/speckit-analyze` → STOP.
|
||||
3. `/speckit-implement` follows P1 then P2; stop/report on Salt conflicts.
|
||||
4. Do not plan `002` until `001` implement + verification complete.
|
||||
|
||||
================================================================================
|
||||
Micro-adjustments applied to plan (summary)
|
||||
================================================================================
|
||||
- Meta path fixed: /home/android-build/sunfish-a16-rom
|
||||
- Ansible in sunfish-rom-build only
|
||||
- Semaphore smoke unprivileged (no sudo secrets)
|
||||
- Off-VM mirror: laptop pull only
|
||||
- No public :2222 / no blind sshd edits; transport documented at implement
|
||||
@@ -0,0 +1,38 @@
|
||||
# 001 verification matrix — FR / SC evidence
|
||||
|
||||
Map each requirement from `specs/001-development-environment/spec.md` to
|
||||
observable evidence. Leave blank until verified on `rom-dev01`.
|
||||
|
||||
## Functional requirements
|
||||
|
||||
| ID | Requirement (short) | Evidence (command/path/doc) | Status |
|
||||
|----|---------------------|-----------------------------|--------|
|
||||
| FR-001 | `android-build` + documented workspace | uid 1000; `/home/android-build/sunfish-a16-rom`; runbook | pass |
|
||||
| FR-002 | Android/LOS prereqs + ccache | `/srv/rom/logs/toolchain-packages.txt` + `toolchain-smoke.txt` | pass |
|
||||
| FR-003 | `/srv/rom` layout | namei + write test artifacts | pass |
|
||||
| FR-004 | Private Gitea for project repos | loopback :3000; 4 private repos; secrets under /srv/rom/secrets/ | pass |
|
||||
| FR-005 | Ansible + Semaphore UI | ansible 2.16.3; Semaphore task env-smoke success | pass |
|
||||
| FR-006 | Cursor Remote SSH + rsync + laptop flash workflow doc | runbook Host `rom-dev01`; rsync smoke; adb on laptop | pass |
|
||||
| FR-007 | Conservative parallelism defaults (~6 vCPU) | measured 8/62/32; `-j` deferred to 003 | pass |
|
||||
| FR-008 | Spec Kit tree on host | `/home/android-build/sunfish-a16-rom` SPEC_OK | pass |
|
||||
| FR-009 | Guest isolation posture | public NIC only; UIs on 127.0.0.1 | pass |
|
||||
| FR-010 | Off-VM backup/mirror of Gitea repos | laptop Archives/sunfish-rom-mirrors/*.git fsck OK | pass |
|
||||
|
||||
## Success criteria
|
||||
|
||||
| ID | Outcome (short) | Evidence | Status |
|
||||
|----|-----------------|----------|--------|
|
||||
| SC-001 | Clean `android-build` SSH has toolchain for `003` | `toolchain-smoke.txt` (git/lfs/repo/ccache/java) | pass |
|
||||
| SC-002 | `/srv/rom/artifacts` writable handoff | dummy-001 SHA256 match laptop `.local-artifacts/` | pass |
|
||||
| SC-003 | Four Gitea repos ready (no company GitLab) | sunfish-admin/* on local Gitea | pass |
|
||||
| SC-004 | Cold-start workflow doc | quickstart.md + host-runbook | pass |
|
||||
| SC-005 | No PVE/VM create/reconfig in this feature | no qm/PVE/Salt VM work in 001 | pass |
|
||||
| SC-006 | Isolation checklist passes | runbook isolation checklist | pass |
|
||||
| SC-007 | Off-VM mirror demonstrated once | rsync bare mirrors + fsck | pass |
|
||||
|
||||
Status values: `pending` | `pass` | `fail` | `blocked`
|
||||
|
||||
## Task cross-check
|
||||
|
||||
Track completion in `specs/001-development-environment/tasks.md`. This matrix
|
||||
is evidence, not a second task list.
|
||||
@@ -0,0 +1,15 @@
|
||||
# 002 gate checklist (handoff → 003)
|
||||
|
||||
Date: 2026-09-13
|
||||
|
||||
| Gate | Status | Evidence |
|
||||
|------|--------|----------|
|
||||
| GOLDEN labeled; do-not-flash | OK | `docs/device-roles.md` — serial `11071JEC203839`; agents must not modify |
|
||||
| LAB labeled | OK | serial `11231JEC207477` (iodé baseline) |
|
||||
| LAB factory rescue doc + verified zip | OK | `docs/002-lab-stock-rescue.md`; host SHA-256 **VERIFY_OK** |
|
||||
| Essential GOLDEN inventory + banking layout | OK | `docs/002-golden-inventory.md` (gaps = re-query; Yuh FAIL documented) |
|
||||
| NeoBackup / wipe GOLDEN | N/A | Not a gate |
|
||||
| FLAG_SECURE / call-record source | Deferred | T021 — re-query GOLDEN later; not blocking `003` vanilla |
|
||||
| Offline AXP archive rsync | In progress | ~18G on host of ~38G laptop; not a flash gate |
|
||||
|
||||
**Handoff:** `002` P1 complete for `003` purposes → flash/build **LAB only**.
|
||||
@@ -0,0 +1,108 @@
|
||||
# GOLDEN inventory (AXP.OS oracle) — redacted
|
||||
|
||||
**Device:** GOLDEN sunfish (main phone) — **DO NOT FLASH / wipe / modify**.
|
||||
**Serial:** `11071JEC203839`
|
||||
**Role:** Live **AXP.OS Pro 22.2 / Android 15** compatibility oracle.
|
||||
**Access:** Non-destructive `adb` only (sampled 2026-09-13).
|
||||
**Raw artifacts:** `/srv/rom/references/axp/golden/2026-09-13/` on `rom-dev01`
|
||||
(includes Magia DenyList screenshots, Yuh logcat; Git = this summary only).
|
||||
|
||||
## Identity (measured)
|
||||
|
||||
| Field | Value |
|
||||
|-------|--------|
|
||||
| Serial | `11071JEC203839` |
|
||||
| Owner user | `Andres` (user 0) |
|
||||
| `ro.build.display.id` | `BP1A.250505.005` |
|
||||
| `ro.build.version.release` | `15` |
|
||||
| `ro.build.version.security_patch` | `2026-03-03` |
|
||||
| AXP / Lineage identity | `ro.lineage.version=22.2-2026.003-sunfish-pro` (`releasetype=PRO`) |
|
||||
| Bootloader | **unlocked** (`flash.locked=0`, `verifiedbootstate=orange`) |
|
||||
| Magisk | Binary **29.0** (`29000`) at `/system_ext/bin/magisk`; UI app named **Magia** |
|
||||
|
||||
## Users / work profile
|
||||
|
||||
| User | Name | Notes |
|
||||
|------|------|-------|
|
||||
| 0 | Andres | Owner |
|
||||
| 10 | Island | Profile owner = `com.oasisfeng.island.fdroid` 6.4.2 |
|
||||
|
||||
After owner’s 2026-09-13 reclone experiment: `com.yuh` and
|
||||
`com.swissquote.android` present on **both** user 0 and user 10
|
||||
(Island reinstall of Yuh `firstInstallTime` user10 ≈ 21:48).
|
||||
|
||||
## Essential packages (measured)
|
||||
|
||||
| Area | Package / path | Version | Notes |
|
||||
|------|----------------|---------|--------|
|
||||
| microG GmsCore | `com.google.android.gms` | **0.3.15.250932** | System base MicrogGmsCore_GH; sig short `73aaa390` |
|
||||
| Phonesky (AXP) | `/system/priv-app/Phonesky_AXP-OS` | **50.2.12-24** | Sig short `e05f779d` |
|
||||
| GSF Proxy | `/system_ext/app/GsfProxy_GH` | `v0.1.0` | |
|
||||
| Island | `com.oasisfeng.island.fdroid` | `6.4.2-d46911c9` | Spec text said “Insular”; measured = **Island** |
|
||||
| Aurora Store | `com.aurora.store` | `4.8.4` | |
|
||||
| Yuh | `com.yuh` | `1.45.11` (vc 535) | See attestation section |
|
||||
| Swissquote | `com.swissquote.android` | `9.9.0` | Owner reports still OK |
|
||||
| Aosmium (AXP) | `org.axpos.aosmium` | `148.0.7778.178` | Not on DenyList |
|
||||
| Magisk modules list | `/data/adb/modules` | — | Not readable without root shell — **re-query** if needed |
|
||||
|
||||
## Magia DenyList (from UI screenshots 2026-09-13)
|
||||
|
||||
Checked packages (package-level; process expand not fully visible in shots):
|
||||
|
||||
| App | Package |
|
||||
|-----|---------|
|
||||
| BBVA Spain | `com.bbva.bbvacontigo` |
|
||||
| BOOM | `com.boom.android.mobile2` |
|
||||
| CieID | `it.ipzs.cieid` |
|
||||
| Device configuration | `android.autoinstalls.config.google.nexus` |
|
||||
| DKB | `com.dkbcodefactory.banking` |
|
||||
| Identifica | `it.sielte.sielteidentify` |
|
||||
| N26 | `de.number26.android` |
|
||||
| Scalable Capital | `capital.scalable.droid` |
|
||||
| Swissquote | `com.swissquote.android` |
|
||||
| Webank | `com.opentecheng.android.webank` |
|
||||
| Wise | `com.transferwise.android` |
|
||||
| Yuh | `com.yuh` |
|
||||
|
||||
Visible unchecked (partial): Aegis, Amarok, Amaze, Aosmium.
|
||||
|
||||
Owner notes: most DenyList banking apps still pass; **Yuh fails** for ~weeks.
|
||||
Extra Magia DenyList/host checks + Island uninstall/reclone did **not** fix Yuh.
|
||||
|
||||
## Compatibility / attestation (observational)
|
||||
|
||||
| Check | Status | Evidence |
|
||||
|-------|--------|----------|
|
||||
| Swissquote | **PASS** (owner report) | Still used; on DenyList |
|
||||
| Other DenyList banks (N26, DKB, …) | **PASS** (owner: “casi todos”) | UI DenyList |
|
||||
| Yuh | **FAIL** — hardware attestation / “certificate is invalid” | Owner UI + logcat ~21:51–21:52 |
|
||||
| Play Integrity token path | Client path still runs | `Finsky requestIntegrityToken() finished for com.yuh`; DroidGuard `pia_attest_e1` for `com.yuh` |
|
||||
| KeyMint / TEE | Errors concurrent with Yuh attempt | `keystore2`: `HARDWARE_TYPE_UNAVAILABLE` (IRPC / `TRUSTED_ENVIRONMENT`); `addRngEntropy` → `DEAD_OBJECT` / KeyMint `-1000` |
|
||||
|
||||
Interpretation for later `006`/`007` (not a GOLDEN fix): DenyList alone is
|
||||
insufficient for Yuh’s hardware-attestation path; KeyMint/TEE remote-provisioning
|
||||
errors correlate with the failure window. Project production root path remains
|
||||
**KernelSU-Next (+ SusFS) or ReSukiSU evaluation** — Magisk/Magia is oracle-only.
|
||||
|
||||
Call recording: GOLDEN Secure dump shows native EXTENDROM
|
||||
`extendrom_call_recording=1` (see `008` — port `er.sh` F_CALLREC, not Magisk
|
||||
RRO). FLAG_SECURE override: not identified as AXP catalog on GOLDEN; project
|
||||
`009` is native DO.
|
||||
|
||||
## Banking layout (oracle)
|
||||
|
||||
Historical target order (AXP workflow; Magisk DenyList → Island):
|
||||
|
||||
1. Aurora Store → install
|
||||
2. Do not open
|
||||
3. Magia DenyList (incl. processes) before first process
|
||||
4. Clone into Island
|
||||
5. First launch in Island
|
||||
6. Phonesky/Play in Island as needed
|
||||
|
||||
Observed: Yuh+Swissquote intended in Island; after 2026-09-13 debug, both also
|
||||
on owner user 0 — clean up is owner’s choice; agents must not uninstall.
|
||||
|
||||
## Policy
|
||||
|
||||
No flash, wipe, Magisk/Magia changes, or app uninstalls by agents — sample only.
|
||||
@@ -0,0 +1,42 @@
|
||||
# LAB baseline (iodé) — measured 2026-09-13
|
||||
|
||||
**Role:** LAB — second sunfish for flashing our ROM.
|
||||
**Serial:** `11231JEC207477`
|
||||
**As found:** iodé / Lineage `7.8-20260902-sunfish`, Android **16**, patch `2026-08-01`.
|
||||
**Bootloader:** locked (`ro.boot.flash.locked=1`).
|
||||
**Policy:** OK to flash/wipe for experiments after factory rescue is in place.
|
||||
|
||||
This is **not** the AXP GOLDEN oracle. Banking apps / Island / microG here are
|
||||
LAB-side copies or leftovers — do not treat as AXP Pro parity evidence.
|
||||
|
||||
## Snapshot (text-only)
|
||||
|
||||
| Item | Value |
|
||||
|------|--------|
|
||||
| `ro.lineage.version` | `7.8-20260902-sunfish` |
|
||||
| `ro.build.version.release` | `16` |
|
||||
| microG GmsCore | `0.3.16.252432` |
|
||||
| FakeStore / vending | `0.3.16.40226` |
|
||||
| GsfProxy | `v0.1.0` |
|
||||
| Island | `6.4.2-d46911c9` (user 10 `myisla`) |
|
||||
| Magisk/KSU | not found |
|
||||
|
||||
Raw logs (moved/copied from early mislabel): host
|
||||
`/srv/rom/references/axp/lab/2026-09-13-iodes-baseline/` when present; else
|
||||
`/srv/rom/references/axp/golden/2026-09-13/` (same content — LAB).
|
||||
|
||||
Factory rescue: [`002-lab-stock-rescue.md`](002-lab-stock-rescue.md).
|
||||
|
||||
## Yuh on LAB (log peek 2026-09-13 ~22:15)
|
||||
|
||||
Launched on **user 0** (not Island). No Magisk. Bootloader **locked**.
|
||||
|
||||
Same core error as GOLDEN within ~4s of open:
|
||||
|
||||
`keystore2`: RKP/IRPC for `TRUSTED_ENVIRONMENT` → `Error::Km(HARDWARE_TYPE_UNAVAILABLE)`
|
||||
|
||||
Also: Yuh loads `libts.so`; SELinux denials probing `getenforce` / `ps` / `/cache` (root-detect style).
|
||||
No Magisk DenyList involved on LAB → failure is **not** “only Magisk visible”.
|
||||
|
||||
Raw: host `…/lab/2026-09-13-iodes-baseline/yuh-2026-09-13/`.
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# LAB stock factory rescue — Pixel 4a (`sunfish`)
|
||||
|
||||
**Scope: LAB only.** Never use these steps on GOLDEN.
|
||||
|
||||
## Source (measured 2026-09-13)
|
||||
|
||||
Google’s public factory listing for sunfish is pruned. The former CDN URL now
|
||||
returns **HTTP 404**:
|
||||
|
||||
`https://dl.google.com/dl/android/aosp/sunfish-tq3a.230805.001.s1-factory-82902ea9.zip`
|
||||
|
||||
Canonical build identity (final Android 13 / TQ3A, widely cross-checked):
|
||||
|
||||
| Field | Value |
|
||||
|-------|--------|
|
||||
| Build | `TQ3A.230805.001.S1` |
|
||||
| File | `sunfish-tq3a.230805.001.s1-factory-82902ea9.zip` |
|
||||
| Size | `2276267484` bytes |
|
||||
| SHA-256 | `82902ea98c80f1a22706279a30d2bc46aa55cbe60703c9a02ba043bd052c6d99` |
|
||||
| Primary index | https://developers.google.com/android/images (sunfish may be empty) |
|
||||
| Fallback (measured) | Internet Archive item [`sunfish-tq3a.230805.001.s1`](https://archive.org/details/sunfish-tq3a.230805.001.s1) |
|
||||
| Cross-check | CalyxOS `vars/sunfish` cites the same URL/hash historically |
|
||||
|
||||
Host storage: `/srv/rom/references/axp/lab/`
|
||||
Download log: `/srv/rom/references/axp/logs/lab-factory-download.txt`
|
||||
|
||||
## Before flashing
|
||||
|
||||
1. Confirm the USB phone is **LAB** (serial/label) — not GOLDEN.
|
||||
2. Backup anything you care about on LAB (full wipe).
|
||||
3. Unlock bootloader only if required and already accepted for LAB.
|
||||
4. Verify zip SHA-256 before `flash-all`.
|
||||
|
||||
```bash
|
||||
sha256sum -c <<<'82902ea98c80f1a22706279a30d2bc46aa55cbe60703c9a02ba043bd052c6d99 sunfish-tq3a.230805.001.s1-factory-82902ea9.zip'
|
||||
```
|
||||
|
||||
## Flash (factory package)
|
||||
|
||||
From an unpacked factory directory on the **laptop** (USB to LAB):
|
||||
|
||||
```bash
|
||||
# device in fastboot; verify serial matches LAB
|
||||
fastboot devices
|
||||
cd /path/to/sunfish-tq3a.230805.001.s1
|
||||
./flash-all.sh # Linux; erases userdata
|
||||
```
|
||||
|
||||
Windows: `flash-all.bat`.
|
||||
`-w` is typically included in Google’s script (data wipe).
|
||||
|
||||
Alternative: https://flash.android.com only if that build remains selectable (LAB only).
|
||||
|
||||
## After flash
|
||||
|
||||
- Confirm LAB boots stock.
|
||||
- Re-unlock / re-setup only as needed for later `003` LOS experiments.
|
||||
- Do **not** relock unless you intend stock-only LAB.
|
||||
|
||||
## Gate
|
||||
|
||||
FR-002 / SC-002: this doc + **SHA-256-verified** zip on host are required before
|
||||
experimental `003` flashes on LAB.
|
||||
@@ -0,0 +1,93 @@
|
||||
# 003 — Build notes (LOS 23.2 sunfish vanilla)
|
||||
|
||||
**Host:** `rom-dev01` as `android-build`
|
||||
**Tree:** `/srv/rom/src/lineage`
|
||||
**Artifacts:** `/srv/rom/artifacts/003-…`
|
||||
**Logs:** `/srv/rom/logs/003-…`
|
||||
**ccache:** `CCACHE_DIR=/srv/rom/ccache` (export in build shell)
|
||||
|
||||
## Parallelism — squeeze the HW
|
||||
|
||||
Guest is **8 vCPU / ~62 GiB**. Policy for this host:
|
||||
|
||||
| Job | Default | Notes |
|
||||
|-----|---------|--------|
|
||||
| `mka bacon` / Soong ninja | **`-j8`** | Match `nproc`; do not leave `-j4` idle |
|
||||
| `repo sync` | `-j8` OK | Network-bound; `-j4` fine if flaky |
|
||||
| OOM during link | try `-j6` | Only then; document why |
|
||||
|
||||
Do **not** pass `-j` to `brunch` (it eats extra args as variant). Use
|
||||
`breakfast` + `mka bacon -j8`, or `/srv/rom/logs/003-build/run-brunch.sh`.
|
||||
|
||||
If `mpstat` shows high **%steal**, the Proxmox host is oversubscribed — fix
|
||||
outside this repo (pin/dedicate vCPUs); guest governors usually unavailable.
|
||||
|
||||
## Manifest (wiki-verified 2026-09-13)
|
||||
|
||||
```bash
|
||||
mkdir -p /srv/rom/src/lineage && cd /srv/rom/src/lineage
|
||||
repo init -u https://github.com/LineageOS/android.git -b lineage-23.2 --git-lfs --no-clone-bundle
|
||||
repo sync -c -j8
|
||||
```
|
||||
|
||||
Primary: https://wiki.lineageos.org/devices/sunfish/build/
|
||||
Branch `lineage-23.2` listed for sunfish.
|
||||
|
||||
## Build (after sync + proprietary blobs)
|
||||
|
||||
```bash
|
||||
export CCACHE_DIR=/srv/rom/ccache
|
||||
export USE_CCACHE=1
|
||||
cd /srv/rom/src/lineage
|
||||
source build/envsetup.sh
|
||||
breakfast sunfish userdebug
|
||||
# extract proprietary blobs: TheMuppets lineage-23.2 → vendor/google/sunfish
|
||||
mka bacon -j8 # do NOT pass -j to brunch; wrapper: /srv/rom/logs/003-build/run-brunch.sh
|
||||
```
|
||||
|
||||
Target expected: `lineage_sunfish-userdebug` (confirm after `breakfast`).
|
||||
|
||||
## Metadata to capture on success
|
||||
|
||||
- `repo manifest -r` → artifacts dir
|
||||
- SHA-256 of zip/images
|
||||
- compressed build log
|
||||
- `-j` used, wall time, host `nproc`/RAM note
|
||||
|
||||
## Status
|
||||
|
||||
- [x] repo init (`/srv/rom/src/lineage`, `lineage-23.2`, 2026-09-13)
|
||||
- [x] repo sync (`finished 2026-09-13T21:27:26Z exit=0`; ~180G; log `/srv/rom/logs/003-sync/sync.log`)
|
||||
- [x] proprietary blobs policy documented (factory base + AXP/GOS diffs later)
|
||||
- [x] TheMuppets `lineage-23.2` synced → `vendor/google/sunfish`
|
||||
- [x] first successful build — `#### build completed successfully` /
|
||||
`END … exit=0` (2026-09-14T13:52:46Z); j8 segment **06:45:43**
|
||||
- [x] artifacts + `repo manifest -r` + SHA-256 + `brunch.log.gz` →
|
||||
`/srv/rom/artifacts/003-vanilla/20260914-lineage-23.2-sunfish/`
|
||||
(rsync → `.local-artifacts/…` on laptop)
|
||||
- [x] flash LAB + smoke (`docs/003-flash-lab.md`) — done 2026-09-14;
|
||||
gate → `004` (`docs/003-gate-handoff.md`)
|
||||
|
||||
## R7 note (vanilla `003`)
|
||||
|
||||
For the first vanilla build: **factory-equivalent blobs only**. AXP/Graphene
|
||||
diffs land in later hardening/compat features — not in the clean baseline.
|
||||
|
||||
## Proprietary blobs (qué son)
|
||||
|
||||
Android open source **no** incluye todo lo que el Pixel necesita para radio,
|
||||
cámara, firmware, etc. Esos binarios cerrados de Google/Qualcomm se llaman
|
||||
**proprietary blobs** (o “vendor blobs”). Sin ellos, `brunch sunfish` no
|
||||
arranca hardware real.
|
||||
|
||||
### Decision (owner 2026-09-13) — no overthink
|
||||
|
||||
| Layer | Approach |
|
||||
|-------|----------|
|
||||
| **Base blobs** | Factory Google / Lineage-equivalent extract (e.g. TheMuppets or `extract-files` from factory) — same hardware binaries stock uses |
|
||||
| **AXP diffs** | Only sunfish-relevant proprietary/packaging diffs from AXP A15 reference |
|
||||
| **GrapheneOS diffs** | Historical **sunfish A13** where still applicable; plus ideas from a **currently supported Pixel** when code is shared and still relevant (sunfish is EOL — do not assume every modern GOS change ports) |
|
||||
|
||||
Do **not** chase exotic blob sets for location quality; NLP/services matter more than swapping vendor GPS blobs.
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# 003 — Flash LAB (vanilla LOS only)
|
||||
|
||||
**LAB serial:** `11231JEC207477`
|
||||
**Never flash:** GOLDEN `11071JEC203839`
|
||||
|
||||
## Artifacts (this build)
|
||||
|
||||
Host: `/srv/rom/artifacts/003-vanilla/20260914-lineage-23.2-sunfish/`
|
||||
Laptop: `.local-artifacts/003-vanilla/20260914-lineage-23.2-sunfish/` (rsynced)
|
||||
|
||||
| File | Role | SHA-256 (prefix) |
|
||||
|------|------|------------------|
|
||||
| `lineage-23.2-20260914-UNOFFICIAL-sunfish.zip` | sideload ROM | `f89edfe1…5852` |
|
||||
| `boot.img` | Lineage recovery (flash to `boot`) | `aaf52d20…aad1` |
|
||||
| `dtbo.img` | required before recovery | `a400e6ae…6327` |
|
||||
| `vbmeta.img` | copied for reference (wiki path uses dtbo+boot) | `b3223b5d…0735` |
|
||||
|
||||
Full digests: `SHA256SUMS` in the same directory. Metadata: `build-metadata.txt`.
|
||||
|
||||
## Owner decisions (2026-09-13)
|
||||
|
||||
- **Unlock / wipe LAB:** allowed when needed for first custom flash.
|
||||
- **Stock factory on LAB:** not desired as a planned OS (rescue zip stays on
|
||||
disk for emergencies only).
|
||||
- **Banking hard-gate focus:** **Yuh** (+ Swissquote); Revolut is **not** a
|
||||
hard-gate.
|
||||
- Vanilla `003` only — no microG / KSU / GApps add-ons on first flash.
|
||||
|
||||
## Wiki note (firmware)
|
||||
|
||||
Upstream LOS install wiki asks for **stock Android 13** firmware before first
|
||||
install. LAB currently runs custom A16 (iodé). For this project we flash
|
||||
vanilla LOS over LAB as approved; if radio/modem misbehaves after smoke, use
|
||||
`docs/002-lab-stock-rescue.md` then re-flash — **never GOLDEN**.
|
||||
|
||||
## Before every fastboot/adb command
|
||||
|
||||
```bash
|
||||
adb devices -l
|
||||
fastboot devices
|
||||
# serial must be 11231JEC207477 only
|
||||
```
|
||||
|
||||
```bash
|
||||
ART="$HOME/Workspaces/sunfish-a16-rom/.local-artifacts/003-vanilla/20260914-lineage-23.2-sunfish"
|
||||
cd "$ART"
|
||||
sha256sum -c SHA256SUMS
|
||||
```
|
||||
|
||||
## Unlock (first custom flash)
|
||||
|
||||
Unlocking **wipes** LAB — owner-approved.
|
||||
|
||||
```bash
|
||||
adb -s 11231JEC207477 reboot bootloader
|
||||
fastboot -s 11231JEC207477 devices
|
||||
fastboot -s 11231JEC207477 flashing unlock # confirm on device
|
||||
```
|
||||
|
||||
## Flash (LOS wiki sunfish path)
|
||||
|
||||
```bash
|
||||
cd "$ART"
|
||||
fastboot -s 11231JEC207477 flash dtbo dtbo.img
|
||||
fastboot -s 11231JEC207477 reboot bootloader
|
||||
fastboot -s 11231JEC207477 flash boot boot.img
|
||||
# device menu → Recovery
|
||||
# Recovery → Factory reset → Format data
|
||||
# Apply update → Apply from ADB
|
||||
adb -s 11231JEC207477 sideload lineage-23.2-20260914-UNOFFICIAL-sunfish.zip
|
||||
# Reboot system now (no GApps / no add-ons for vanilla 003)
|
||||
```
|
||||
|
||||
Unofficial zip: recovery may warn about signature — expected; proceed only if
|
||||
hashes match `SHA256SUMS`.
|
||||
|
||||
## After first boot
|
||||
|
||||
```bash
|
||||
adb -s 11231JEC207477 shell getprop ro.lineage.version
|
||||
adb -s 11231JEC207477 shell getprop ro.build.display.id
|
||||
# expect lineage 23.2 / sunfish UNOFFICIAL — not AXP, not iodé
|
||||
```
|
||||
|
||||
Then complete `docs/003-smoke-lab.md`.
|
||||
|
||||
## Failure
|
||||
|
||||
Use [`002-lab-stock-rescue.md`](002-lab-stock-rescue.md) only as **emergency**
|
||||
brick recovery. Do not touch GOLDEN.
|
||||
@@ -0,0 +1,33 @@
|
||||
# 003 gate checklist (handoff → 004)
|
||||
|
||||
**Date:** 2026-09-14
|
||||
**Device:** LAB `11231JEC207477` only (GOLDEN untouched)
|
||||
|
||||
## Naming (owner clarification)
|
||||
|
||||
- **LAB target ROM:** Android **16** / LineageOS **23.2**
|
||||
- **GOLDEN:** AXP Pro on Android **15** — reference/read only
|
||||
- Do **not** treat “A15” as a synonym for Android 16
|
||||
|
||||
## Build / flash
|
||||
|
||||
| Item | Status | Evidence |
|
||||
|------|--------|----------|
|
||||
| Vanilla LOS build | pass | `#### build completed successfully` / `exit=0` 2026-09-14T13:52:46Z |
|
||||
| Artifacts + SHA-256 + manifest -r | pass | `/srv/rom/artifacts/003-vanilla/20260914-lineage-23.2-sunfish/` + laptop `.local-artifacts/…` |
|
||||
| Unlock + flash LAB | pass | `unlocked: yes`; sideload `Total xfer: 1.00x` |
|
||||
| Identity | pass | `ro.lineage.version=23.2-20260914-UNOFFICIAL-sunfish`; no iodé/AXP props |
|
||||
| SELinux / encrypt | pass | Enforcing; `encrypted` |
|
||||
| P1 hardware smoke | pass | adb + owner confirmation of main functions 2026-09-14 |
|
||||
|
||||
## Notes (non-blocking)
|
||||
|
||||
- Public **test-keys** banner — expected until `011`
|
||||
- `verifiedbootstate=orange` / unlocked — expected
|
||||
- Vendor security patch **2023-09-05** — EOL Pixel; document further in `013`
|
||||
- Titan M `libnos_datagram` during recovery wipe — ignore; install status 0
|
||||
- Platform ASB for this baseline: trust Lineage merges (`ro.build.version.security_patch=2026-09-01`); no separate CVE audit in `003`
|
||||
|
||||
## Gate
|
||||
|
||||
**`003` complete → proceed to `004` (microG + GSF Proxy + patched Phonesky) on LAB only.**
|
||||
@@ -0,0 +1,67 @@
|
||||
# 003 — LAB smoke checklist (vanilla LOS 23.2)
|
||||
|
||||
Device serial: `11231JEC207477`
|
||||
Build: `lineage-23.2-20260914-UNOFFICIAL-sunfish`
|
||||
Zip SHA-256: `f89edfe1fba7062eb8f8e3cea5012f209fefe587bf447cf4f83a7017812e5852`
|
||||
Date: 2026-09-14
|
||||
|
||||
Status: `pass` / `fail` / `skip` + short evidence.
|
||||
|
||||
## Identity (adb 2026-09-14)
|
||||
|
||||
| Prop | Value |
|
||||
|------|--------|
|
||||
| `ro.lineage.version` | `23.2-20260914-UNOFFICIAL-sunfish` |
|
||||
| `ro.build.flavor` | `lineage_sunfish-userdebug` |
|
||||
| `ro.build.display.id` | `BP4A.251205.006 test-keys` |
|
||||
| Slot | `_a` (install was on `b`; post-update active `_a`) |
|
||||
| Prior ROM props | none (no iodé / AXP / microG) |
|
||||
|
||||
## P1
|
||||
|
||||
| Item | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| Boots to UI | pass | owner + adb up ~7 min |
|
||||
| Encryption / PIN | pass | `ro.crypto.state=encrypted` (set PIN in setup) |
|
||||
| SELinux Enforcing | pass | `getenforce` → Enforcing |
|
||||
| Android security patch | pass | `2026-09-01` |
|
||||
| Vendor security patch / baseline | pass | `2023-09-05` (EOL Pixel vendor train — expected) |
|
||||
| SIM detection | pass | `gsm.sim.state=LOADED`, operator Movistar |
|
||||
| Mobile data | pass | owner 2026-09-14 — main functions OK |
|
||||
| Phone calls | pass | owner 2026-09-14 |
|
||||
| SMS | pass | owner 2026-09-14 |
|
||||
| Wi-Fi | pass | connected `Pixel_1216` |
|
||||
| Bluetooth | pass | owner 2026-09-14 |
|
||||
| GPS | pass | owner 2026-09-14 |
|
||||
| Camera(s) | pass | owner 2026-09-14 |
|
||||
| Audio (speaker/mic) | pass | owner 2026-09-14 |
|
||||
| NFC | pass | owner 2026-09-14 |
|
||||
| Sensors (basic) | pass | accel/gyro/mag/light/prox listed + active |
|
||||
| Fingerprint | pass | owner 2026-09-14 |
|
||||
| USB data / ADB | pass | adb device authorized |
|
||||
| Charging | pass | USB powered, level 99 |
|
||||
|
||||
## Extended
|
||||
|
||||
| Item | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| Airplane mode | skip | not run |
|
||||
| Flashlight | _user_ | |
|
||||
| Vibration | _user_ | |
|
||||
| Screen rotation | _user_ | |
|
||||
| USB OTG | skip | |
|
||||
| Headphone jack | n/a | sunfish has none |
|
||||
| WebView basic page | pass | `com.android.webview` present (`/product/app/webview`) |
|
||||
| Sideload non-Google APK | skip | |
|
||||
| Widevine / DRM level | skip | check later if needed |
|
||||
| eSIM state | skip | |
|
||||
| WireGuard kernel baseline | skip | |
|
||||
| Bootloader version | pass | `s5-0.5-10252351` |
|
||||
| Baseband / modem | pass | `g7150-00112-230505-B-10075601` |
|
||||
| AVB / lock state | note | `verifiedbootstate=orange`, `flash.locked=0` (unlocked — expected) |
|
||||
| Public test-keys banner | note | expected for UNOFFICIAL userdebug until `011` |
|
||||
|
||||
## Gate to `004`
|
||||
|
||||
P1 blockers unresolved? **no** — owner confirmed main functions 2026-09-14.
|
||||
Handoff: `docs/003-gate-handoff.md`. Proceed to `004`.
|
||||
@@ -0,0 +1,105 @@
|
||||
# 004 / 005 — LAB microG Self-Check
|
||||
|
||||
Device: LAB `11231JEC207477` (never GOLDEN)
|
||||
Build: `23.2-20260915-UNOFFICIAL-sunfish`
|
||||
Date: 2026-09-15
|
||||
Evidence: `/srv/rom/artifacts/005-spoofing/20260915-us6-validation/LAB-US6.txt`
|
||||
|
||||
## Packages
|
||||
|
||||
| Package | `pm path` | Notes |
|
||||
|---------|-----------|-------|
|
||||
| `com.google.android.gms` | `/system_ext/app/GmsCore/GmsCore.apk` | PRESIGNED; from zip |
|
||||
| `com.google.android.gsf` | `/system_ext/app/GsfProxy/GsfProxy.apk` | PRESIGNED; from zip |
|
||||
| `com.android.vending` | system priv-app from zip; LAB currently `/data/app/…` after exact-alarm `adb install -r` | Next bacon restores `/system/priv-app/Phonesky/` |
|
||||
| FakeStore | absent | `pm list packages` — no FakeStore |
|
||||
|
||||
## Spoofing (`005`)
|
||||
|
||||
| Check | Result |
|
||||
|-------|--------|
|
||||
| `settings get secure allow_signature_fake` | `1` |
|
||||
| `FAKE_PACKAGE_SIGNATURE` user 0 gms + vending | `granted=true` |
|
||||
| `FAKE_PACKAGE_SIGNATURE` user 10 (Island) gms + vending | `granted=true` |
|
||||
| Self-Check correct signature (gms + Play) | pass (operator) |
|
||||
| Magisk / KSU / `su` | absent |
|
||||
|
||||
## Self-Check
|
||||
|
||||
| Item | pass/fail | Notes |
|
||||
|------|-----------|-------|
|
||||
| Package / ROM signature rows | pass | after spoof grant |
|
||||
| Permission rows incl. spoof | pass | Developer Options toggle + grant |
|
||||
| Play companion / Phonesky sig | pass | project JKS allow-listed in `005` |
|
||||
|
||||
## Play Store
|
||||
|
||||
| Check | Result | Notes |
|
||||
|-------|--------|-------|
|
||||
| Play opens | pass | |
|
||||
| Login | pass | no `UNREGISTERED_ON_API_CONSOLE` in logcat |
|
||||
| Install app (owner + work) | pass | after exact-alarm Phonesky (`USE_EXACT_ALARM`) |
|
||||
| Version | `52.9.22-24` | |
|
||||
| In-app Play self-update | may fail | AXP-like; acceptable |
|
||||
|
||||
## Modern location (BeaconDB / Positon)
|
||||
|
||||
Mozilla Location Service backends are dead. Prefer an Ichnaea-compatible URL:
|
||||
**BeaconDB** (`https://api.beacondb.net`) or **Positon** (`https://api.positon.xyz/?key=…`).
|
||||
Do **not** reintroduce UnifiedNlp Déjà Vu / Nominatim backend APKs on 0.3.x.
|
||||
|
||||
1. Open **microG Settings → Location**.
|
||||
2. Enable network / Wi‑Fi / cell location as shown in Self-Check.
|
||||
3. Enable the in-GmsCore toggles that still exist in 0.3.x (e.g. remember from
|
||||
GPS, request from online service / hotspot) — these are **not** the old
|
||||
UnifiedNlp plugin list.
|
||||
4. Set (or confirm) the service URL (BeaconDB or Positon).
|
||||
5. Do **not** install UnifiedNlp backend APKs from F-Droid.
|
||||
|
||||
| Check | Result |
|
||||
|-------|--------|
|
||||
| BeaconDB / Positon URL documented | yes |
|
||||
| UnifiedNlp backends required | no |
|
||||
|
||||
### LAB observation (follow-up — 2026-09-16) — **fixed (prebuilt)**
|
||||
|
||||
Root cause: staged GmsCore was official **`*-hw`** (`versionName=…-hw`). That
|
||||
flavor omits `NetworkLocationService` /
|
||||
`NetworkLocationProviderService` from the manifest, so Location UI hides
|
||||
Wi‑Fi/cell NLP (only Timeline-style bits remain). **GOLDEN** / abu ship the
|
||||
**default** flavor (`versionName` without `-hw`) and show the full Location
|
||||
options.
|
||||
|
||||
**Fix (host staged 2026-09-16):** replace with
|
||||
`com.google.android.gms-252432032.apk` → `versionName=0.3.16.252432` (non-hw),
|
||||
synced to `vendor/sunfish-a16/prebuilt/GmsCore.apk`. Quick LAB check without
|
||||
bacon: `adb install -r` the default APK (same microG signer), then:
|
||||
|
||||
```bash
|
||||
adb shell dumpsys package com.google.android.gms | grep -iE 'NetworkLocationProvider|NetworkLocationService'
|
||||
adb shell dumpsys package com.google.android.gms | grep versionName=
|
||||
# expect versionName=0.3.16.252432 (no -hw) + both NetworkLocation* components
|
||||
```
|
||||
|
||||
Permanent: next `bacon` picks up the new prebuilt (~12.5 MiB larger than hw).
|
||||
Positon remains a valid URL if preferred over BeaconDB.
|
||||
|
||||
After `adb install -r` of the default APK, `dumpsys` may still list both
|
||||
`versionName=0.3.16.252432` and `…-hw` until the next full image flash replaces
|
||||
`/system_ext/app/GmsCore` (data overlay + old system base). NLP services already
|
||||
come from the default update.
|
||||
|
||||
## microG F-Droid updates
|
||||
|
||||
| Check | Result | Notes |
|
||||
|-------|--------|-------|
|
||||
| Add [microG F-Droid repo](https://microg.org/fdroid/repo) | optional | one-time |
|
||||
| F-Droid sees GmsCore update (when newer) | expected | official `PRESIGNED` on system_ext |
|
||||
| Do **not** install Companion/FakeStore from F-Droid | — | conflicts with Phonesky |
|
||||
|
||||
## AXP layout sanity
|
||||
|
||||
| Check | Result | Notes |
|
||||
|-------|--------|-------|
|
||||
| Phonesky | priv-app in image | LAB data path only after hotfix upgrade |
|
||||
| GmsCore / GsfProxy | `/system_ext/…` | matches AXP GOLDEN layout intent |
|
||||
@@ -0,0 +1,65 @@
|
||||
# 004 — Phonesky / microG runbook (rom-dev01)
|
||||
|
||||
Proprietary Google/Play APKs **never** go in Git. Binaries live on `rom-dev01`
|
||||
under `/srv/rom/prebuilts/`.
|
||||
|
||||
## Owner policy (2026-09-15)
|
||||
|
||||
- **Copy AXP’s packaging scheme** (GOLDEN layout), modernize versions (LOS 23.2 /
|
||||
A16, latest microG + patched latest Play).
|
||||
- Root later = **KSU-Next + SusFS** (`007`), not Magisk — do not design `004`
|
||||
around Magisk modules.
|
||||
- Prefer AXP behaviour over ad-hoc shortcuts (no “everything on product”, no
|
||||
ABI-strip that forces re-signing official microG).
|
||||
|
||||
## AXP GOLDEN layout (mirror this)
|
||||
|
||||
| Package | Partition | Privileged? |
|
||||
|---------|-----------|-------------|
|
||||
| Phonesky | `system` priv-app | yes |
|
||||
| GmsCore | `system_ext` app | no (AXP: `MicrogGmsCore_GH_presigned`) |
|
||||
| GsfProxy | `system_ext` app | no |
|
||||
|
||||
Host packaging: `vendor/sunfish-a16/{Android.mk,gms.mk,BoardConfig.mk}`.
|
||||
|
||||
## Layout on host
|
||||
|
||||
| Path | Contents |
|
||||
|------|----------|
|
||||
| `/srv/rom/prebuilts/microg/` | official `GmsCore.apk`, `GsfProxy.apk`, `VERSIONS.txt` |
|
||||
| `/srv/rom/prebuilts/phonesky/` | patched `Phonesky.apk`, XMLs, `VERSIONS.txt`, `upstream/` |
|
||||
| `/srv/rom/secrets/phonesky-signing/` | project JKS for Phonesky |
|
||||
| `/srv/rom/tools/phonesky/` | AXP `packages_apps_phonesky` worktree + tools |
|
||||
|
||||
## Stage microG (latest official — F-Droid-updatable)
|
||||
|
||||
1. Download latest **default** `com.google.android.gms-NNNNNNN.apk` (no `-hw`) +
|
||||
`GsfProxy.apk` from microG GitHub releases. Match GOLDEN: `versionName`
|
||||
must **not** end in `-hw` (Huawei flavor drops NLP Location services /
|
||||
UI). Example: `v0.3.16.252432` → `com.google.android.gms-252432032.apk`.
|
||||
2. Keep **official signature** (`LOCAL_CERTIFICATE := PRESIGNED`). **Never**
|
||||
re-sign / ABI-strip GmsCore for size — that breaks F-Droid updates.
|
||||
3. Do **not** install microG’s `com.android.vending-*.apk` (FakeStore).
|
||||
|
||||
## Stage Phonesky (patch latest Play — AXP procedure)
|
||||
|
||||
1. Tools: apktool, aapt, zipalign, `apksigner` via `java -jar …/apksigner.jar`.
|
||||
2. Project keystore once under `/srv/rom/secrets/phonesky-signing/`.
|
||||
3. `apkmd` + AXP `apkmirror.json` → `/srv/rom/prebuilts/phonesky/upstream/`.
|
||||
4. Checkout AXP `packages_apps_phonesky`; run `DEBUG=yes ANDROIDSDK=35 ./patch-playstore …`
|
||||
(host adaptations: apktool 2.12 build without `-t`; **zipalign then sign**).
|
||||
5. Stage fat patched APK as system priv-app + AXP `etc/` XMLs to **system**.
|
||||
|
||||
## Partition headroom
|
||||
|
||||
If `check_partition_sizes` fails after adding the AXP-sized set, raise
|
||||
`BOARD_SUPER_PARTITION_ERROR_LIMIT` in `vendor/sunfish-a16/BoardConfig.mk`
|
||||
(keep under `BOARD_GOOGLE_DYNAMIC_PARTITIONS_SIZE`). Do **not** “fix” by
|
||||
destroying the microG signer.
|
||||
|
||||
## Signing (FR-010)
|
||||
|
||||
| Package | Signer | Updates |
|
||||
|---------|--------|---------|
|
||||
| GmsCore / GsfProxy | Official microG | F-Droid microG repo |
|
||||
| Phonesky | Project JKS | Same-signer patched APKs |
|
||||
@@ -0,0 +1,92 @@
|
||||
# 005 — Restricted signature spoofing runbook
|
||||
|
||||
**Feature**: `005-restricted-signature-spoofing`
|
||||
**LAB only**: serial `11231JEC207477` — never GOLDEN
|
||||
**Host**: `rom-dev01` under `/srv/rom/`
|
||||
|
||||
## What we discovered (2026-09-15)
|
||||
|
||||
LineageOS 23.2 **already** ships restricted microG spoofing
|
||||
(`frameworks/base` commit `23c0a5c19844`, LuK1337):
|
||||
|
||||
| Gate | Stock LOS behaviour |
|
||||
|------|---------------------|
|
||||
| Build | `userdebug`/`eng` only (`isDebuggable()` JNI) |
|
||||
| Packages | `com.google.android.gms`, `com.android.vending` only |
|
||||
| Signer | Must match **microG release** cert (`MICROG_REAL_SIGNATURE`) |
|
||||
| Fake value | Must equal platform Google cert (`MICROG_FAKE_SIGNATURE`) |
|
||||
| Surfaces | Spoofs both `PackageInfo.signatures` and `signingInfo` |
|
||||
|
||||
Gaps vs our stack / AXP UX:
|
||||
|
||||
1. **Our Phonesky** is signed with the **project JKS**, not microG — stock
|
||||
gate rejected it → Play `UNREGISTERED_ON_API_CONSOLE`.
|
||||
2. No `FAKE_PACKAGE_SIGNATURE` permission → microG Self-Check permission rows
|
||||
empty.
|
||||
3. No Developer Options master switch (`allow_signature_fake`).
|
||||
|
||||
## What we applied
|
||||
|
||||
Script (idempotent, marker `SUNFISH_A16_005_SIGSPOOF`):
|
||||
|
||||
- Meta: `vendor/sunfish-a16/patches/005-sigspoof/apply_005_sigspoof.py`
|
||||
- Host copy: `/srv/rom/src/lineage/vendor/sunfish-a16/patches/005-sigspoof/`
|
||||
- References: `/srv/rom/references/extendrom` @ `f129253c…`
|
||||
- Cert hex: `/srv/rom/artifacts/005-spoofing/phonesky-cert.hex`
|
||||
(SHA-256 `31:31:86:CB:…:BD:56`)
|
||||
|
||||
Changes on the LOS tree:
|
||||
|
||||
1. Extend `isMicrogSigned()` to accept **project Phonesky** signer for
|
||||
`com.android.vending`.
|
||||
2. Gate spoofing on `Settings.Secure.allow_signature_fake` (default **0**).
|
||||
3. Require grant of `android.permission.FAKE_PACKAGE_SIGNATURE`.
|
||||
4. Port EXTENDROM permission + Settings Developer Options toggle + strings.
|
||||
5. Keep packaging leftovers: `LOCAL_REPLACE_PREBUILT_APK_INSTALLED` + Play FGS
|
||||
privapp XML (already in `vendor/sunfish-a16/`).
|
||||
|
||||
**LAB 2026-09-15 post-flash:** Self-Check / spoofing / no
|
||||
`UNREGISTERED_ON_API_CONSOLE` OK. Play install failures / ANR: `DownloadService`
|
||||
/`VpaService` FGS `systemExempted` needs **any of** `SCHEDULE_EXACT_ALARM` /
|
||||
`USE_EXACT_ALARM` / VPN — privapp alone is not enough if the APK does not
|
||||
**request** those permissions.
|
||||
|
||||
**Fix (2026-09-15):** Phonesky rebuild adds `USE_EXACT_ALARM` +
|
||||
`SCHEDULE_EXACT_ALARM` to the manifest; artifact
|
||||
`/srv/rom/artifacts/005-spoofing/Phonesky_exact-alarm.apk`; pushed to LAB via
|
||||
`adb install -r` (same project JKS); vendor prebuilt updated under
|
||||
`/srv/rom/src/lineage/vendor/sunfish-a16/prebuilt/Phonesky.apk` for next bacon.
|
||||
`USE_EXACT_ALARM: granted=true` on LAB after upgrade.
|
||||
|
||||
Re-apply after `repo sync` that resets frameworks/Settings:
|
||||
|
||||
```bash
|
||||
python3 /srv/rom/src/lineage/vendor/sunfish-a16/patches/005-sigspoof/apply_005_sigspoof.py
|
||||
```
|
||||
|
||||
Backups: `/srv/rom/artifacts/005-spoofing/bak-snapshots/` (never leave
|
||||
`*.005.bak` under `res/` — aapt2 will fail).
|
||||
|
||||
## LAB validation (US6 — 2026-09-15)
|
||||
|
||||
Accepted on LAB `11231JEC207477` / build `23.2-20260915-UNOFFICIAL-sunfish`.
|
||||
Evidence: `/srv/rom/artifacts/005-spoofing/20260915-us6-validation/LAB-US6.txt`.
|
||||
|
||||
1. ~~Flash LAB; `pm path` gms / gsf / vending~~ — pass
|
||||
2. ~~Allow signature spoofing~~ — `allow_signature_fake=1`
|
||||
3. ~~Self-Check correct signature~~ — pass (grant on user 0 + Island 10)
|
||||
4. ~~Play sign-in / installs~~ — pass after exact-alarm Phonesky; no `UNREGISTERED_ON_API_CONSOLE`
|
||||
5. Location: configure BeaconDB `https://api.beacondb.net` (no UnifiedNlp) — steps in
|
||||
`docs/004-lab-selfcheck.md` + `quickstart.md`
|
||||
|
||||
```bash
|
||||
adb -s 11231JEC207477 shell settings get secure allow_signature_fake
|
||||
# expect 1 when enabled
|
||||
```
|
||||
|
||||
**Handoff:** first stack done → next feature **`006` banking rootless**. Do **not**
|
||||
add KernelSU/`007` until after `006`.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Banking apps (`006`), KSU/root (`007`), Magisk/LSPosed.
|
||||
@@ -0,0 +1,80 @@
|
||||
# abu (KernelSU-Next) vs ours (ReSukiSU) — SusFS integration checklist
|
||||
|
||||
> **Historical hypothesis checklist:** The [2026-09-16 source audit](007-susfs-source-audit.md)
|
||||
> supersedes causal claims here. ReSukiSU intentionally supports SUSFS as an
|
||||
> alternative inline hook provider; forcing MANUAL+SUSFS is a local porting
|
||||
> choice, not an established universal fix. Check module ABI and command wire
|
||||
> formats as well as Kconfig. The reference checkout is not proven identical
|
||||
> to the owner's working Abu L22 binary.
|
||||
|
||||
Oracle: `/srv/rom/references/abu-msm-4.14-ksu` (`drivers/kernelsu` → `KernelSU-Next/kernel`).
|
||||
Ours: ReSukiSU under `msm-4.14/drivers/kernelsu` + LOS 23.2 A16.
|
||||
**Do not copy abu ROM/boot**; copy *model* only. Forks differ (Next ≠ ReSukiSU).
|
||||
|
||||
## Architectural model (abu — correct)
|
||||
|
||||
| Topic | abu KernelSU-Next | ReSukiSU upstream (broken for us) | Ours after patches |
|
||||
|-------|-------------------|-------------------------------------|--------------------|
|
||||
| SusFS | **Addon** `bool` under `menu "KernelSU - SUSFS"`, `depends on KSU` | Was a **choice** entry XOR with MANUAL/TRACEPOINT | Kconfig: SusFS outside choice (abu-like) |
|
||||
| Hooks | `KSU_KPROBES_HOOK` default y; or manual (disable kprobes) | `choice` MANUAL / TRACEPOINT / (was SUSFS) | MANUAL_HOOK + AUTO_* for 4.14 |
|
||||
| `susfs_init()` | `#ifdef CONFIG_KSU_SUSFS` always in `ksu.c`, **independent** of hook method | Often behind `#elif CONFIG_KSU_SUSFS` only | Fixed `init.c`: MANUAL branch also calls `susfs_init()` |
|
||||
| Hook enable keys | N/A (different code) | `#elif SUSFS` before `#elif MANUAL` → no `ksu_init_rc_hook` when both | Fixed `ksud_integration.c`: SusFS-only branch if `!MANUAL_HOOK` |
|
||||
|
||||
## Failures we already hit (XOR leftovers)
|
||||
|
||||
1. Defconfig SusFS on → choice flipped → **no MANUAL_HOOK** → vibrator hang / broken hooks (`T004038Z`).
|
||||
2. MANUAL+SusFS without **AUTO_*** → early logo reboot (`T091211Z`).
|
||||
3. AUTO_* + SusFS → link error `ksu_init_rc_hook` (SUSFS `#elif` won).
|
||||
4. Even after link fix: without `susfs_init()` in MANUAL path, SusFS would be dead code.
|
||||
|
||||
## Remaining `#elif CONFIG_KSU_SUSFS` in our tree (review)
|
||||
|
||||
| File | Pattern | Risk when MANUAL+SUSFS | Action |
|
||||
|------|---------|------------------------|--------|
|
||||
| `runtime/ksud_integration.c` | SusFS iff `!MANUAL` | OK | done |
|
||||
| `core/init.c` | MANUAL then `ifdef SUSFS` init; elif SUSFS legacy | OK | done |
|
||||
| `feature/sucompat.h` | `#elif SUSFS` before else MANUAL macros | Uses SusFS TIF/helpers — **intended** for addon | leave; verify LAB |
|
||||
| `supercall/dispatch.c:527` | mark get: SUSFS then else | SusFS path when addon — OK | leave |
|
||||
| `supercall/dispatch.c:902` | MANUAL before SUSFS for hook_type string | Reports "Manual" when both — OK | leave |
|
||||
| `feature/sucompat.c` | `SUSFS \|\| MANUAL` | OK compose | leave |
|
||||
|
||||
**Rule:** any `#elif CONFIG_KSU_SUSFS` that **defines symbols or inits** needed by MANUAL/AUTO must become either `&& !MANUAL` or `#ifdef SUSFS` *nested inside* MANUAL (abu: always `#ifdef SUSFS`).
|
||||
|
||||
## Feature flag delta (Kconfig)
|
||||
|
||||
abu Next has extras we lack (Next-specific / different SusFS port):
|
||||
- `KSU_SUSFS_HAS_MAGIC_MOUNT`
|
||||
- `KSU_SUSFS_AUTO_ADD_SUS_*` / `TRY_UMOUNT*`
|
||||
- `KSU_SUSFS_SUS_SU` (needs KPROBES)
|
||||
|
||||
Our ReSukiSU SusFS set: PATH/MOUNT/KSTAT/LOG/HIDE_SYMBOLS/SPOOF_CMDLINE/OPEN_REDIRECT/SUS_MAP (+ SPOOF_UNAME optional).
|
||||
Bring-up: keep **SPOOF_UNAME off** (already commented in defconfig); consider SPOOF_CMDLINE off until boot stable.
|
||||
|
||||
abu `sunfish_defconfig` in this reference has **0** `CONFIG_KSU*` lines — enablement is elsewhere / not this file; do not treat that defconfig as SusFS pin list.
|
||||
|
||||
## Hook stack (do not mix blindly)
|
||||
|
||||
| | abu | ours |
|
||||
|--|-----|------|
|
||||
| Primary | KPROBES (`CONFIG_KSU_KPROBES_HOOK`) | MANUAL + AUTO_SETUID/INITRC/INPUT |
|
||||
| Non-GKI docs | kernelsu.org manual integrate | resukisu.org manual integrate |
|
||||
|
||||
Porting abu **kprobe** assumptions into ReSukiSU MANUAL builds = future footgun.
|
||||
|
||||
## Pre-build gate (mandatory)
|
||||
|
||||
Before each SusFS `bootimage`:
|
||||
|
||||
```bash
|
||||
CFG=out/target/product/sunfish/obj/KERNEL_OBJ/.config
|
||||
grep -E "CONFIG_KSU_MANUAL_HOOK=y|CONFIG_KSU_MANUAL_HOOK_AUTO_.*=y|CONFIG_KSU_SUSFS=y" "$CFG"
|
||||
# must have MANUAL=y, all three AUTO=y, SUSFS=y
|
||||
# must NOT have "# CONFIG_KSU_MANUAL_HOOK is not set"
|
||||
nm …/ksud_integration.o | grep ksu_init_rc_hook # after CC
|
||||
```
|
||||
|
||||
After Image: extract-ikconfig and confirm same.
|
||||
|
||||
## Flash discipline
|
||||
|
||||
Flash SusFS to one slot only; keep penúltimo on the other; `--set-active`; both-slot rollback after failure.
|
||||
@@ -0,0 +1,60 @@
|
||||
# Debug boot — freeze on panic (photo / dump)
|
||||
|
||||
Normal sunfish kernel: `CONFIG_PANIC_TIMEOUT=5` + often
|
||||
`CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC` → reboot in seconds. Console is
|
||||
**UART only** (`console=ttyMSM0`); `# CONFIG_VT is not set` → **no Oops text
|
||||
on the phone display** (you only see the Google logo loop).
|
||||
|
||||
## What a “debug boot” must include (owner)
|
||||
|
||||
For a useful photo, **both** are required — freeze alone is not enough:
|
||||
|
||||
1. **Freeze:** `CONFIG_PANIC_TIMEOUT=0` + cmdline `panic=0`; disable
|
||||
`CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC` so it does not reboot in 5s.
|
||||
2. **On-screen console:** `CONFIG_VT` + `CONFIG_FRAMEBUFFER_CONSOLE` (+
|
||||
`console=tty0` in cmdline). Without this, you only see the Google logo.
|
||||
|
||||
| Goal | Mechanism | Photo-able? |
|
||||
|------|-----------|-------------|
|
||||
| Stop reboot loop | `panic=0` / `PANIC_TIMEOUT=0`, no wdog-bite-on-panic | Logo freezes only |
|
||||
| Oops on screen | VT + FRAMEBUFFER_CONSOLE + `console=tty0` | Yes if panic after FB; early may still be logo |
|
||||
| Dump after hang | Freeze + penúltimo + immediate `klog`/`logfs` dd | Not a photo |
|
||||
|
||||
Use **only on LAB**, SusFS/debug trials. Never ship as daily boot.
|
||||
Next SusFS debug build after the sigfix trial must enable **both**.
|
||||
|
||||
## Host recipe (LAB SusFS debug boot)
|
||||
|
||||
1. Defconfig fragment (or temporary edits) on `rom-dev01`:
|
||||
|
||||
```text
|
||||
CONFIG_PANIC_TIMEOUT=0
|
||||
# CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC is not set
|
||||
# optional on-screen console (experimental on Pixel 4.14):
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
```
|
||||
|
||||
2. Cmdline (device tree or unpack/repack boot): add `panic=0` and optionally
|
||||
`console=tty0`. Prefer a **vendor_sunfish / BoardConfig** override gated by
|
||||
a make var (e.g. `SUNFISH_KERNEL_PANIC_DEBUG=1`) so normal bacon stays clean.
|
||||
|
||||
3. Build `bootimage`, name artifact
|
||||
`boot-resukisu-susfs-DEBUG-YYYYMMDDTHHMMSSZ.img`.
|
||||
|
||||
4. Flash only to `boot_b`; keep penúltimo on `boot_a`. On hang: photo if text
|
||||
appears; Vol−+Power → `--set-active=a`.
|
||||
|
||||
## Capture order (always)
|
||||
|
||||
1. Panic / hang on SusFS (debug) slot
|
||||
2. Fastboot **before** Android success on good slot
|
||||
3. Then penúltimo + immediate `dd` of `klog`/`logfs` (4a has no `fastboot fetch`)
|
||||
|
||||
## Status
|
||||
|
||||
Documented 2026-09-16 after SusFS early `kernel_panic` with empty Oops in klog.
|
||||
Sigfix rebuild may already address root cause; keep this recipe for the next
|
||||
opaque bootloop.
|
||||
@@ -0,0 +1,198 @@
|
||||
# 007 — KernelSU-Next on sunfish (LAB runbook)
|
||||
|
||||
**LAB only**: serial `11231JEC207477` — never GOLDEN `11071JEC203839`
|
||||
**Host**: `rom-dev01` — artifacts `/srv/rom/artifacts/007-kernelsu/`, logs
|
||||
`/srv/rom/logs/007-build/`
|
||||
**Managed profile**: **Island** (current LAB/GOLDEN vehicle; historical
|
||||
“Insular” docs are workflow reference only)
|
||||
|
||||
## Latest LAB results
|
||||
|
||||
**2026-09-16:** SusFS DEBUG bring-up **PASS** (matched vendor); banks still
|
||||
**FAIL** (Talsec `-69` / root lock). Full write-up:
|
||||
[`docs/007-lab-results-20260916.md`](007-lab-results-20260916.md).
|
||||
|
||||
## Hard-gates
|
||||
|
||||
| Gate | Rule |
|
||||
|------|------|
|
||||
| Yuh (`com.yuh`) | **PASS** usable session in Island on the tested stack |
|
||||
| Swissquote (`com.swissquote.android`) | **PASS** usable session in Island on the **same** stack |
|
||||
| Root | Banks **never** receive root; hide/umount **verified** (not toggle-only) |
|
||||
| Magisk | Not production |
|
||||
|
||||
If either bank fails after SusFS/attestation experiments → **cancel root**
|
||||
(Phase 9): keep incomplete / withdraw KSU; pivot to native `008`/`009` + optional
|
||||
stock phone. Do **not** ship “root without both banks”.
|
||||
|
||||
## Sequencing (constitution 0.2.1)
|
||||
|
||||
- `006` rootless PASS gate is **deferred**.
|
||||
- Before first rooted flash: **T039** rootless snapshot of *this* LAB ROM
|
||||
(`pre-root/`). FAIL allowed; record facts.
|
||||
- Then KSU → verified hide → SusFS → attestation → both-bank PASS.
|
||||
- **Pins:** always refresh to newest compatible ReSukiSU/manager (non-shallow);
|
||||
record tag + `KSU_VERSION` before `mka`. Never rebuild from a stale host copy.
|
||||
|
||||
## `002` KeyMint / Yuh evidence (index)
|
||||
|
||||
| Source | What | Path / doc |
|
||||
|--------|------|------------|
|
||||
| GOLDEN AXP+Magisk | Yuh FAIL — HA / “certificate invalid”; KeyMint `HARDWARE_TYPE_UNAVAILABLE` | `docs/002-golden-inventory.md` §Compatibility; host refs under `/srv/rom/references/axp/golden/…` when present |
|
||||
| LAB iodé A16 (no Magisk, BL locked) | Same KeyMint/RKP class on Yuh open | `docs/002-lab-iodes-baseline.md`; host `…/lab/2026-09-13-iodes-baseline/yuh-…` |
|
||||
| Contracts | Hide + both-bank gate | `specs/007-kernelsu-sunfish/contracts/` |
|
||||
|
||||
## Manager UI is **not** in the ROM zip
|
||||
|
||||
Kernel root (KSU-Next / ReSukiSU) does **not** ship a visible Settings tile.
|
||||
After flash: install the matching **spoofed manager APK** (version ≤ kernel
|
||||
`KSU_VERSION`), then modules (TEESimulator-RS / Zygisk / PIF, etc.). Same on
|
||||
torukk’s MicroG zip — ResukiSU/KSU is kernel-only until the manager is installed
|
||||
(see XDA #41; our pin: `.local-artifacts/007-kernelsu/ReSukiSU_*spoofed_*.apk`).
|
||||
|
||||
## Host policy
|
||||
|
||||
**All heavy work on `rom-dev01` only** (kernel clone, integrate, `mka`, image
|
||||
staging). Laptop = thin client (adb/fastboot, Spec Kit, docs). Do not run kernel
|
||||
builds or multi‑GB clones on the laptop.
|
||||
|
||||
**Long jobs must be detached on the host** — never leave `mka`/`ninja` on a
|
||||
laptop SSH pipe (Wi‑Fi drops kill the build). Prefer **tmux** via
|
||||
`/srv/rom/artifacts/bin/rom-detach` (falls back to screen / nohup):
|
||||
|
||||
```bash
|
||||
/srv/rom/artifacts/bin/rom-detach 007-boot -- bash -lc \
|
||||
'cd /srv/rom/src/lineage && source build/envsetup.sh && lunch lineage_sunfish-bp4a-userdebug && mka bootimage -j$(nproc)'
|
||||
cat /srv/rom/artifacts/detach-007-boot.status
|
||||
tmux ls # attach: tmux attach -t 007-boot
|
||||
```
|
||||
|
||||
Agents: start detached, then only poll `detach-*.status` / logs with short SSH.
|
||||
|
||||
| Path on host | Role |
|
||||
|--------------|------|
|
||||
| `/srv/rom/src/lineage/kernel/google/msm-4.14` | Our LOS kernel (integrate here) |
|
||||
| `/srv/rom/src/lineage/kernel/google/msm-4.14/KernelSU-Next` | setup.sh checkout @ `a54e4fa…` |
|
||||
| `/srv/rom/references/kernelsu-next/` | KernelSU-Next `legacy` mirror (setup source) |
|
||||
| `/srv/rom/references/abu-msm-4.14-ksu/` | abu-adm `ksu-susfs-23.0` **reference only** |
|
||||
| `/srv/rom/artifacts/007-kernelsu/abu-reference/` | Owner-supplied abu `boot-abu.img` + `dtbo-abu.img` + SHA256 |
|
||||
| `/srv/rom/artifacts/007-kernelsu/` | Our outs / evidence |
|
||||
| `/srv/rom/logs/007-build/` | Build logs |
|
||||
|
||||
### Integration status (2026-09-16)
|
||||
|
||||
- **Production root fork for LAB:** **ReSukiSU** (symlink `drivers/kernelsu` →
|
||||
`/srv/rom/references/resukisu/kernel`, full non-shallow clone). KernelSU-Next
|
||||
remains historical learning only.
|
||||
- Manual hooks (`CONFIG_KSU_MANUAL_HOOK`): `fs/open.c`, `fs/exec.c`, `fs/stat.c`,
|
||||
`fs/read_write.c`, `drivers/input/input.c`, `kernel/sys.c` (`setresuid`),
|
||||
`kernel/reboot.c`
|
||||
- `sunfish_defconfig`: `CONFIG_KSU=y`, `CONFIG_KSU_MANUAL_HOOK=y`, all three
|
||||
`AUTO_*` hooks **on** for 4.14, SusFS options as addon (not XOR). See
|
||||
`docs/007-abu-vs-ours-susfs.md`.
|
||||
- **Our boots (use these — not Downloads):**
|
||||
|
||||
| Role | Artifact |
|
||||
|------|----------|
|
||||
| Penúltimo (ReSukiSU, no SusFS) | `boot-resukisu-our-20260915T183729Z.img` / `boot-resukisu-our-latest.img` |
|
||||
| Último (ReSukiSU + SusFS) | `boot-resukisu-susfs-20260916T004038Z.img` / `…-susfs-latest.img` (sha `455a77a6…`) |
|
||||
|
||||
- SusFS: **built** (API bridge 4.14 ↔ ReSukiSU ioctl). **Not claimed** on LAB —
|
||||
trial only; US2 hide not finished before build. See
|
||||
`docs/session-20260916-handoff.md`.
|
||||
|
||||
## Community / abu — **reference archive only**
|
||||
|
||||
Same problem space (sunfish + microG + hide + banks). **Not** our flash path.
|
||||
Do not install abu/torukk ROMs or `~/Downloads/boot-sunfish-resukisu*.img` as
|
||||
“our” kernel.
|
||||
|
||||
| Topic | Useful reference | Our action |
|
||||
|-------|------------------|------------|
|
||||
| Root fork | ReSukiSU for hard banks (XDA) | We already build **our** ReSukiSU boot |
|
||||
| Attestation | TEESimulator-RS | Prefer over TrickyStore when modules resume |
|
||||
| Modules | Zygisk Next + PIF inject | Documented exception if bank gate needs it |
|
||||
| SusFS / kernel | abu `ksu-susfs` trees, `abu-reference/` imgs | Diff / port ideas only |
|
||||
| Their full ROM | torukk 22.2 MicroG / abu A15 | **Ignore for day-to-day** — restore always = our 23.2 bacon |
|
||||
|
||||
Host refs: `/srv/rom/references/abu-msm-4.14-ksu/`,
|
||||
`/srv/rom/artifacts/007-kernelsu/abu-reference/` (`boot-abu` / `dtbo-abu`).
|
||||
|
||||
```bash
|
||||
# LAB — our penúltimo (preferred after ROM sideload)
|
||||
# Always flash BOTH slots after a failed SusFS/bootloop trial — bootloader may
|
||||
# mark the other slot unbootable and leave current-slot on the bad one.
|
||||
fastboot flash boot_a .local-artifacts/007-kernelsu/boot-resukisu-our-20260915T183729Z.img
|
||||
fastboot flash boot_b .local-artifacts/007-kernelsu/boot-resukisu-our-20260915T183729Z.img
|
||||
fastboot --set-active=a # or the slot that last ran our 23.2 bacon successfully
|
||||
fastboot reboot
|
||||
# host: /srv/rom/artifacts/007-kernelsu/boot-resukisu-our-20260915T183729Z.img
|
||||
|
||||
# Emergency (no KSU): bacon stock boot
|
||||
# fastboot flash boot_a|boot_b .local-artifacts/007-kernelsu/boot-005-known-good.img
|
||||
```
|
||||
|
||||
**Slot lesson (2026-09-16):** SusFS bootloop left `current-slot:b` and
|
||||
`slot-unbootable:a:yes`. Flashing only `boot` (→ active slot) could not revive
|
||||
LAB; `boot-005` on **both** slots + `--set-active=a` recovered. Before any
|
||||
kernel trial: `fastboot getvar current-slot` / `slot-unbootable:*`. After
|
||||
failure: flash rollback to **boot_a and boot_b**, then set the known-good slot.
|
||||
|
||||
## Pin table (2026-09-16)
|
||||
|
||||
| Component | Revision | Status | Notes |
|
||||
|-----------|----------|--------|-------|
|
||||
| ReSukiSU | host `/srv/rom/references/resukisu` (non-shallow; match manager) | **active** | record tag + `KSU_VERSION` before each `mka` |
|
||||
| KernelSU-Next | `a54e4fa…` (`legacy`) | archived | learning only |
|
||||
| LOS sunfish kernel | `28f9290ae067…` + dirty SusFS/hooks | tree | `msm-4.14` |
|
||||
| SusFS | bridged in-tree (trial) | **rebuild** | `T004038Z` hung (no MANUAL_HOOK); `T091211Z` logo-reboot (MANUAL+SUSFS but **AUTO_* hooks off**); next: AUTO_*=y + SusFS |
|
||||
| Attestation stack | — | pending | TEESimulator-RS first candidate |
|
||||
|
||||
## Kernel inventory (T005)
|
||||
|
||||
| Item | Value |
|
||||
|------|--------|
|
||||
| Source | `/srv/rom/src/lineage/kernel/google/msm-4.14` |
|
||||
| Device makefile | `device/google/sunfish/BoardConfigLineage.mk` → `TARGET_KERNEL_SOURCE := kernel/google/msm-4.14` |
|
||||
| Defconfig | `arch/arm64/configs/sunfish_defconfig` |
|
||||
| Boot image name | `Image.lz4` |
|
||||
|
||||
## KernelSU-Next choice (T006–T007) — amended by community 2026-08
|
||||
|
||||
**Earlier decision**: KernelSU-Next `legacy` + manual hooks for first in-tree POC.
|
||||
|
||||
**Amended (owner + torukk XDA 2026-08-22)**: For **hard-bank** detection
|
||||
(Revolut-class; our gate is Yuh/Swissquote), community evidence favors
|
||||
**ReSukiSU** + **TEESimulator-RS** (+ Zygisk Next + PIF inject) over Next+TrickyStore.
|
||||
Keep Next work as learning / optional A/B; **do not** treat Next-only as the
|
||||
banking solution if ResukiSU PoC is available.
|
||||
|
||||
**LAB PoC order (current, 2026-09-16):**
|
||||
1. ~~Foreign ResukiSU / abu boots~~ — reference only; wrong for our A16 tree
|
||||
2. **Done**: our ReSukiSU → `boot-resukisu-our-20260915T183729Z.img` (penúltimo)
|
||||
3. **Done (build)**: SusFS trial → `boot-resukisu-susfs-20260916T004038Z.img` —
|
||||
flash/claim **after** US2; prefer penúltimo on LAB until then
|
||||
4. Manager + TEESimulator-RS ± Zygisk/PIF → bank gate
|
||||
|
||||
## Integration notes (T008)
|
||||
|
||||
Work on host tree; flash only our `boot-resukisu-our-*` / `boot-resukisu-susfs-*`
|
||||
artifacts (never `~/Downloads/boot-sunfish-resukisu*`):
|
||||
|
||||
1. Wire ReSukiSU as **`drivers/kernelsu` → `/srv/rom/references/resukisu/kernel`** (full git clone lives *outside* the msm tree). Do **not** keep a `KernelSU/` directory inside `msm-4.14`: this tree’s `scripts/setlocalversion` walks nested `.git` dirs and appends `KernelSU-gHASH` into `uname -r` (easy bank detection).
|
||||
2. Always use a **non-shallow** ReSukiSU clone so `KSU_VERSION = 30000 + rev-list + 700` matches the manager (≥35080). Shallow depth=1 produced bogus **30701**.
|
||||
3. Enable `CONFIG_KSU=y` + `CONFIG_KSU_MANUAL_HOOK` (+ AUTO_* on 4.14).
|
||||
4. Patch syscall hook sites per https://resukisu.org/guide/manual-integrate.html.
|
||||
5. Build `mka bootimage`; verify `uname -r` has **no** `KernelSU` string before bank testing.
|
||||
6. SusFS: built as trial; **do not claim** until US1–US2 green and T019 boots clean.
|
||||
|
||||
References: ReSukiSU manual integrate; abu/XDA only as SusFS/module oracle
|
||||
(`docs/reference-sources.md` §8; `docs/session-20260916-handoff.md`).
|
||||
|
||||
## Rootless snapshot (T039)
|
||||
|
||||
See `/srv/rom/artifacts/007-kernelsu/pre-root/OUTCOMES.txt` and `preflight.txt`.
|
||||
|
||||
Recorded on `23.2-20260915-UNOFFICIAL-sunfish`: microG + Phonesky + spoof ON;
|
||||
Island user 10 present; **no su**. Yuh/Swissquote **not installed** at snapshot
|
||||
time (N/A outcomes). Reinstall via Aurora→Island before US5 banking gate.
|
||||
@@ -0,0 +1,220 @@
|
||||
# 007 LAB results — 2026-09-16
|
||||
|
||||
LAB only: serial `11231JEC207477`. GOLDEN not used.
|
||||
Build base: `23.2-20260915-UNOFFICIAL-sunfish`.
|
||||
Kernel under test: ReSukiSU **35153** + SusFS **v1.5.5**, DEBUG boot
|
||||
`#8 … Wed Sep 16 12:09:18 UTC 2026`
|
||||
(`boot-resukisu-susfs-DEBUG-20260916T115115Z.img`).
|
||||
|
||||
Related: [source audit](007-susfs-source-audit.md),
|
||||
[attempts brief](007-susfs-attempts-chatgpt-brief.md),
|
||||
[runbook](007-kernelsu-runbook.md).
|
||||
|
||||
## Executive summary
|
||||
|
||||
| Area | Result |
|
||||
|------|--------|
|
||||
| SusFS + ReSukiSU **boot** (matched vendor) | **PASS** |
|
||||
| Manager 35153 + `susfs_init` | **PASS** |
|
||||
| Play downloads (system Phonesky alone) | **FAIL** → fixed with exact-alarm APK hotfix |
|
||||
| TEESimulator-RS + ReZygisk + PIF inject | Installed and running |
|
||||
| Yuh / Swissquote usable session | **FAIL** (Talsec root detect / exit **-69**) |
|
||||
| SusFS as banking hide by itself | **Not sufficient** (expected; US2/attestation still open) |
|
||||
|
||||
**Bottom line:** The SusFS bring-up *pipeline* works end-to-end (build →
|
||||
matched `boot`+`vendor` → modules load → Manager sees SusFS). Banking PASS is
|
||||
still blocked by root/environment detection; SusFS did not clear that gate.
|
||||
|
||||
---
|
||||
|
||||
## 1. Boot / SusFS bring-up
|
||||
|
||||
### What failed earlier (corrected causality)
|
||||
|
||||
1. **Boot-only SusFS flashes** left LAB on an old `/vendor/lib/modules` set.
|
||||
With `CONFIG_MODVERSIONS=y`, `drv2624` (and peers) disagreed on CRCs
|
||||
(**31/56** incl. `module_layout`). That matches the T004038Z-class hang in
|
||||
`VibratorManagerService` when the module never loads — **not** proof of the
|
||||
later early-panic series.
|
||||
2. First matched-module attempt used a **hand-repacked** `vendor.img` with
|
||||
wrong SELinux labels (`vendor_file` instead of
|
||||
`vendor_kernel_modules`). `init-insmod-sh` got `avc: denied { module_load }`
|
||||
→ empty `lsmod` → same vibrator / bootanim stall. **ADB was alive.**
|
||||
|
||||
Reproduce ABI check:
|
||||
|
||||
```bash
|
||||
python3 scripts/check-module-abi.py <Module.symvers> <module.ko>
|
||||
```
|
||||
|
||||
### What worked
|
||||
|
||||
| Step | Detail |
|
||||
|------|--------|
|
||||
| DEBUG boot | `panic=0`, VT/fbcon; artifact `.local-artifacts/007-kernelsu/boot-resukisu-susfs-DEBUG-20260916T115115Z.img` |
|
||||
| Vendor | Repacked modules from same build; flash via **fastbootd** (`vendor_a` sparse); vbmeta `--disable-verity --disable-verification` |
|
||||
| SELinux fix | Relabel `.ko` → `u:object_r:vendor_kernel_modules:s0` (`incrementalfs` → `vendor_incremental_module`) |
|
||||
| Post-boot | `sys.boot_completed=1`, `drv2624` + ~40 modules loaded |
|
||||
| SusFS | `dmesg`: `susfs_init … version: v1.5.5` |
|
||||
| Manager | Spoofed `weogax.atbfxb.skiggr` **35153**; UI: driver 35153, SusFS v1.5.5, hook **Manual**, SELinux Enforcing |
|
||||
|
||||
`su` from adb: `uid=0` `u:r:ksu:s0`. No `/sys/fs/susfs` (normal for 1.5.5;
|
||||
ioctl/supercall path).
|
||||
|
||||
### Architecture note (open)
|
||||
|
||||
MANUAL_HOOK + `CONFIG_KSU_SUSFS` remains a **local hybrid** vs upstream ReSukiSU
|
||||
hook `choice`. This DEBUG build **boots** with that hybrid + matched vendor.
|
||||
ChatGPT’s “hook ABI collision” theory is **not** required to explain the
|
||||
vibrator hang; it remains a hypothesis for earlier logo→reboot trials that
|
||||
were not re-run with matched vendor. Prefer a controlled **SusFS-inline,
|
||||
no MANUAL**, min-features experiment later — do not treat hybrid as final
|
||||
architecture.
|
||||
|
||||
Prepared but not on this boot: execve post-hook UAF patch
|
||||
`vendor/sunfish/patches/007-kernelsu/0001-exec-avoid-post-hook-filename-uaf.patch`
|
||||
(real bug; also present on root-only path → not SusFS-only panic proof).
|
||||
|
||||
---
|
||||
|
||||
## 2. Play Store “pending”
|
||||
|
||||
**Cause:** `DownloadService` crash loop:
|
||||
|
||||
```text
|
||||
SecurityException: FGS type systemExempted requires
|
||||
FOREGROUND_SERVICE_SYSTEM_EXEMPTED + (SCHEDULE_EXACT_ALARM | USE_EXACT_ALARM | VPN)
|
||||
```
|
||||
|
||||
System `/system/priv-app/Phonesky` lacked `USE_EXACT_ALARM` in the **APK
|
||||
manifest** (privapp XML alone is insufficient). Documented hotfix:
|
||||
|
||||
| Item | Path |
|
||||
|------|------|
|
||||
| Host | `/srv/rom/artifacts/005-spoofing/Phonesky_exact-alarm.apk` |
|
||||
| Laptop | `.local-artifacts/004-microg/Phonesky_exact-alarm.apk` |
|
||||
|
||||
```bash
|
||||
adb install -r .local-artifacts/004-microg/Phonesky_exact-alarm.apk
|
||||
```
|
||||
|
||||
Not in the bacon image yet (deferred with other API warnings). Next bacon must
|
||||
ship the exact-alarm Phonesky prebuilt.
|
||||
|
||||
---
|
||||
|
||||
## 3. Modules reinstall
|
||||
|
||||
Installed with `su -M` (global mount ns; plain `su` often cannot see
|
||||
`/data/adb` under SusFS) via `/data/adb/ksud module install …`:
|
||||
|
||||
| Module | id | Version |
|
||||
|--------|-----|---------|
|
||||
| ReZygisk | `rezygisk` | v1.0.0 (515) |
|
||||
| TEESimulator-RS | `tricky_store` | v6.0.1-307 |
|
||||
| Play Integrity Fix [INJECT] | `playintegrityfix` | v4.7-1-inject-s |
|
||||
|
||||
Zips staged under `.local-artifacts/007-kernelsu/modules/`. Versions matched
|
||||
upstream `update.json` at install time. Reboot required after install; user
|
||||
confirmed activated.
|
||||
|
||||
**TEESimulator targets:** default `target.txt` had Play/GMS + test apps only.
|
||||
`com.yuh` and `com.swissquote.android` must be listed (GUI may not expose this;
|
||||
edit `/data/adb/tricky_store/target.txt` or module action). Adding them was
|
||||
necessary for TEEsim to bind those UIDs; it did **not** by itself clear Talsec.
|
||||
|
||||
Observed TEEsim noise: `StrongBox op limit reached (hw=4 sw=0 max=4)`,
|
||||
`Skip patching short certificate chain of length null`.
|
||||
|
||||
**PIF note:** `pif.prop` spoofed **Pixel 6** (`oriole`) on sunfish — device
|
||||
mismatch risk for banks; revisit fingerprint before next bank trial.
|
||||
|
||||
---
|
||||
|
||||
## 4. Banking (Yuh / Swissquote)
|
||||
|
||||
### Observed behaviour
|
||||
|
||||
- Both load **Talsec** `libts.so`.
|
||||
- Swissquote (and Yuh after retries): `VM exiting with result code **-69**`
|
||||
then process death — intentional anti-root exit, **not** an uncaught Java
|
||||
crash. Same signature as 2026-09-15 captures (with/without TEEsim).
|
||||
- Probes in logcat: `getenforce`, `/proc`, serial props, `qemu.*`, `ps` /
|
||||
`pid_max`, cache symlink, etc.
|
||||
- Operator report: after many attempts Yuh **locked the app** citing **root**.
|
||||
|
||||
### Profile / policy gaps (spec US2 still open)
|
||||
|
||||
- Contract: banks **never** receive root; umount/hide must be **verified**.
|
||||
- `.allowlist` contained both bank packages (binary profile); confirm in
|
||||
Manager UI: **Deny / Forbidden** + **Umount modules** for
|
||||
`com.yuh` and `com.swissquote.android` (all userIds tested).
|
||||
- SusFS initialised ≠ verified path hide for banking UIDs.
|
||||
- Island / work profile not re-validated in this session.
|
||||
|
||||
### Verdict on SusFS vs banks
|
||||
|
||||
SusFS **does not** replace: deny-root profiles, verified umount, coherent
|
||||
attestation (TEEsim keybox/StrongBox), and PIF props matching the device.
|
||||
Pipeline works; **both-bank PASS remains FAIL**.
|
||||
|
||||
---
|
||||
|
||||
## 5. Operational recipes (LAB)
|
||||
|
||||
### Flash matched DEBUG (fastbootd)
|
||||
|
||||
```bash
|
||||
adb reboot fastboot # userspace fastbootd
|
||||
fastboot flash vendor_a .local-artifacts/007-kernelsu/vendor-DEBUG-modules.sparse.img
|
||||
fastboot --disable-verity --disable-verification flash vbmeta_a .local-artifacts/007-kernelsu/vbmeta.img
|
||||
fastboot flash boot_a .local-artifacts/007-kernelsu/boot-resukisu-susfs-DEBUG-20260916T115115Z.img
|
||||
fastboot flash boot_b .local-artifacts/007-kernelsu/boot-resukisu-susfs-DEBUG-20260916T115115Z.img
|
||||
fastboot reboot
|
||||
```
|
||||
|
||||
Rollback vendor (host): `/srv/rom/artifacts/007-kernelsu/vendor-pre-debug-20260915.img`.
|
||||
|
||||
### Module install (after SusFS boot)
|
||||
|
||||
```bash
|
||||
adb push <zip> /data/local/tmp/ksu-mods/
|
||||
adb shell 'su -M -c "/data/adb/ksud module install /data/local/tmp/ksu-mods/<zip>"'
|
||||
adb reboot
|
||||
```
|
||||
|
||||
### TEESimulator bank targets
|
||||
|
||||
```bash
|
||||
adb shell 'su -M -c "grep -E \"yuh|swissquote\" /data/adb/tricky_store/target.txt ||
|
||||
printf \"%s\\n\" com.yuh com.swissquote.android >> /data/adb/tricky_store/target.txt"'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Artifacts index
|
||||
|
||||
| Artifact | Location |
|
||||
|----------|----------|
|
||||
| DEBUG boot | `.local-artifacts/007-kernelsu/boot-resukisu-susfs-DEBUG-20260916T115115Z.img` |
|
||||
| Vendor sparse (correct SELinux) | `.local-artifacts/007-kernelsu/vendor-DEBUG-modules.sparse.img` (+ host `…/vendor-repack/`) |
|
||||
| Experiment dir | `a16-build:/srv/rom/artifacts/007-kernelsu/debug-20260916T115115Z/` |
|
||||
| Module zips | `.local-artifacts/007-kernelsu/modules/` |
|
||||
| Phonesky exact-alarm | `.local-artifacts/004-microg/Phonesky_exact-alarm.apk` |
|
||||
| ABI checker | `scripts/check-module-abi.py` |
|
||||
| RCA CRCs | `.local-artifacts/007-kernelsu/rca-20260916/` |
|
||||
| Manager pin | `.local-artifacts/007-kernelsu/SPOOFED_MANAGER_PIN.txt` (35153) |
|
||||
|
||||
---
|
||||
|
||||
## 7. Open follow-ups (non-ordering commitment)
|
||||
|
||||
1. Bacon: ship exact-alarm Phonesky + always package `boot` with matching
|
||||
vendor modules (and correct `vendor_kernel_modules` labels).
|
||||
2. Confirm Manager Deny + Umount for both banks; prove with `su` from bank UID
|
||||
and mount evidence (US2).
|
||||
3. TEEsim StrongBox limit / keybox quality; PIF fingerprint → sunfish-coherent.
|
||||
4. Optional control: SusFS-inline without MANUAL, min features, matched vendor.
|
||||
5. Apply execve UAF patch on next kernel rebuild.
|
||||
6. Do **not** claim banking PASS until Yuh + Swissquote usable sessions on the
|
||||
same stack (runbook hard-gate).
|
||||
@@ -0,0 +1,312 @@
|
||||
# SusFS + ReSukiSU on sunfish LOS 23.2 — full attempt log (for external review)
|
||||
|
||||
> **Audit correction (2026-09-16):** See [source and artifact audit](007-susfs-source-audit.md).
|
||||
> The claims below that missing MANUAL_HOOK caused the vibrator hang, or that
|
||||
> the upstream hook choice is intrinsically broken, are hypotheses, not proven
|
||||
> causes. The audit confirms incompatible installed/vendor module CRCs, an
|
||||
> exec post-hook use-after-free, and incomplete/mismatched SUSFS API wrappers.
|
||||
> The exact early-panic cause still requires a trace or controlled experiment.
|
||||
|
||||
**Date compiled:** 2026-09-16
|
||||
**Project:** `sunfish-a16-rom` (independent; not SSYSTEMS)
|
||||
**Device (LAB only):** Pixel 4a `sunfish`, serial `11231JEC207477`
|
||||
**ROM base:** LineageOS **23.2** / Android **16** (`lineage-23.2-20260915-UNOFFICIAL-sunfish`)
|
||||
**Goal:** ReSukiSU root **plus** SusFS hide addon on **our** `msm-4.14` tree (A16), using abu/GOLDEN as **behavioural oracles**, not as flash images.
|
||||
|
||||
**Ask for help:** Why do MANUAL_HOOK + AUTO_* + CONFIG_KSU_SUSFS builds still `kernel_panic` before userspace on this tree, while (1) penúltimo ReSukiSU-without-SusFS boots, and (2) an earlier SusFS-without-MANUAL build reached Android (then hung on vibrator)? What remaining XOR / composition bugs exist in ReSukiSU when treating SusFS as an addon like KernelSU-Next?
|
||||
|
||||
---
|
||||
|
||||
## 1. Concepts (do not confuse)
|
||||
|
||||
| Name | What it is |
|
||||
|------|------------|
|
||||
| **KernelSU (KSU)** | Generic root-in-kernel project family |
|
||||
| **ReSukiSU** | Fork we ship (kernel driver + Manager). Version code **35153**, `v4.2.0-rc2-…@ReSukiSU` |
|
||||
| **KernelSU-Next** | Different fork; what **abu** wires in their reference tree |
|
||||
| **SusFS** | Kernel **addon** (simonpunk) for path/mount/uname/cmdline hide. **Not** a replacement for ReSukiSU. Should sit **on top** of a KSU-family driver |
|
||||
|
||||
**Intended product stack:**
|
||||
|
||||
```
|
||||
apps / banks
|
||||
↑
|
||||
SusFS ← optional hide (compile into boot)
|
||||
↑
|
||||
ReSukiSU ← root
|
||||
↑
|
||||
msm-4.14 + LOS 23.2 system
|
||||
```
|
||||
|
||||
**abu product habit:** two boots (root-only vs root+SusFS). Same idea: SusFS on/off at **compile time** in the boot image, not a runtime “activate SusFS” without the code in the kernel.
|
||||
|
||||
---
|
||||
|
||||
## 2. Important paths (host `rom-dev01` + laptop)
|
||||
|
||||
### Host
|
||||
|
||||
| Path | Role |
|
||||
|------|------|
|
||||
| `/srv/rom/src/lineage/` | LOS 23.2 tree |
|
||||
| `/srv/rom/src/lineage/kernel/google/msm-4.14/` | Our kernel (dirty: ReSukiSU + SusFS + patches) |
|
||||
| `/srv/rom/src/lineage/kernel/google/msm-4.14/drivers/kernelsu/` | ReSukiSU kernel module sources (in-tree) |
|
||||
| `/srv/rom/src/lineage/kernel/google/msm-4.14/fs/susfs.c` | SusFS implementation |
|
||||
| `/srv/rom/src/lineage/kernel/google/msm-4.14/arch/arm64/configs/sunfish_defconfig` | Defconfig (KSU/SusFS/debug knobs) |
|
||||
| `/srv/rom/src/lineage/device/google/sunfish/BoardConfig-common.mk` | `BOARD_KERNEL_CMDLINE`; optional `SUNFISH_DEBUG_PANIC_SCREEN=1` → `panic=0 console=tty0` |
|
||||
| `/srv/rom/artifacts/007-kernelsu/` | Boot images + managers + RCA |
|
||||
| `/srv/rom/artifacts/007-kernelsu/susfs-fail-rca/` | ikconfig diffs, notes, abu checklist |
|
||||
| `/srv/rom/artifacts/007-kernelsu/run-susfs-bootimage.sh` | Normal SusFS bootimage builder |
|
||||
| `/srv/rom/artifacts/007-kernelsu/run-susfs-bootimage-debug.sh` | DEBUG builder (`SUNFISH_DEBUG_PANIC_SCREEN=1`) |
|
||||
| `/srv/rom/logs/007-build/susfs-bootimage.log` | Cumulative build log (script tee) |
|
||||
| `/srv/rom/logs/007-build/susfs-bootimage-debug.log` | Debug build log |
|
||||
| `/srv/rom/artifacts/detach-*.log` | Per-session `rom-detach` logs |
|
||||
| `/srv/rom/references/abu-msm-4.14-ksu/` | **abu reference kernel** (A15-era). `drivers/kernelsu` → symlink `KernelSU-Next/kernel` |
|
||||
| `/srv/rom/references/resukisu/` | ReSukiSU git reference (non-shallow; version from `rev-list`) |
|
||||
| `/srv/rom/references/susfs4ksu/` | Upstream SusFS project reference |
|
||||
| `/srv/rom/artifacts/007-kernelsu/abu-reference/` | Owner-supplied abu `boot-abu` / `dtbo-abu` (reference only; **do not flash as ours**) |
|
||||
|
||||
### Laptop workspace
|
||||
|
||||
| Path | Role |
|
||||
|------|------|
|
||||
| `/home/aventura/Workspaces/sunfish-a16-rom/` | Git project |
|
||||
| `.local-artifacts/007-kernelsu/` | Copied boots, klog dumps, Manager APKs |
|
||||
| `docs/007-kernelsu-runbook.md` | Runbook |
|
||||
| `docs/007-abu-vs-ours-susfs.md` | abu vs ours checklist |
|
||||
| `docs/007-debug-boot-panic-screen.md` | Debug boot / photo Oops notes |
|
||||
| `specs/007-kernelsu-sunfish/` | Feature spec/tasks |
|
||||
|
||||
**SSH:** `ssh a16-build` → `android-build@rom-dev01` (see `docs/ssh/config`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Boot image changelog (chronological)
|
||||
|
||||
All under `/srv/rom/artifacts/007-kernelsu/` (and laptop `.local-artifacts/007-kernelsu/` when copied).
|
||||
|
||||
| Stamp / file | uname / notes | Config essence | LAB result |
|
||||
|--------------|---------------|----------------|------------|
|
||||
| **Penúltimo** `boot-resukisu-our-20260915T183729Z.img` | `#1 … Tue Sep 15 18:06:17 UTC 2026` | `MANUAL_HOOK=y` + all **AUTO_***=y; **SusFS off** | **GOOD** — daily LAB root |
|
||||
| `boot-005-known-good.img` | Stock bacon kernel (no KSU in practice for root) | LOS boot from zip | Emergency recovery when slots broken |
|
||||
| **SusFS #1** `…-susfs-20260916T004038Z.img` | `#3 … Wed Sep 16 00:43:54` | `CONFIG_KSU_SUSFS=y`, **`MANUAL_HOOK` unset** (choice XOR) | Kernel up, **adb alive**, bootanim forever: `system_server` stuck in **VibratorManagerService.nativeGetVibratorIds** (~66s watchdog) |
|
||||
| **SusFS #2** `…-susfs-20260916T091211Z.img` | `#4 … Wed Sep 16 09:21:41` | After Kconfig patch: `MANUAL_HOOK=y` + SusFS; **AUTO_* all unset** | **Google logo → reboot loop** (earlier than #1) |
|
||||
| **SusFS #3** `…-susfs-20260916T104649Z.img` | `#6 … Wed Sep 16 10:51:09` | `MANUAL` + **AUTO_***=y + SusFS; `susfs_init` in MANUAL path; link fix for `ksu_init_rc_hook` | Still logo→reboot. Proven on **slot a** (same system as penúltimo) → **not A/B system_b** |
|
||||
| **SusFS #4 sigfix** `…-susfs-20260916T112839Z.img` | `#7 … Wed Sep 16 11:32:09` sha `472a32d8…` | + sucompat **faccessat/stat** signatures: SusFS `struct filename**` only if `SUSFS && !MANUAL` | **Worse** — returns to fastboot **faster** |
|
||||
| **SusFS #5 DEBUG** (building at doc time) | `susfs-boot-debug` session | #4 macros fix (`susfs_*` privilege macros only if `!MANUAL`) + `PANIC_TIMEOUT=0`, no `QCOM_FORCE_WDOG_BITE_ON_PANIC`, `VT`+`FRAMEBUFFER_CONSOLE`, cmdline `panic=0 console=tty0`, `SPOOF_CMDLINE` off | Pending |
|
||||
|
||||
**Known-good rollback always:**
|
||||
`boot-resukisu-our-20260915T183729Z.img` on `boot_a` + `--set-active=a`.
|
||||
|
||||
**Manager matching 35153:**
|
||||
`ReSukiSU_v4.2.0-rc2-spoofed_35153-arm64-v8a-release.apk`
|
||||
(without Manager, `su` missing even if kernel has KSU).
|
||||
|
||||
---
|
||||
|
||||
## 4. Root-cause chain (what we learned)
|
||||
|
||||
### 4.1 ReSukiSU upstream treats SusFS as a **hooking method** (XOR)
|
||||
|
||||
Kconfig `choice "KernelSU Hooking Method"` originally included `KSU_SUSFS` alongside `KSU_MANUAL_HOOK` / `KSU_TRACEPOINT_HOOK`.
|
||||
|
||||
Enabling SusFS in defconfig → warning `override: KSU_SUSFS changes choice state` → **MANUAL_HOOK off**.
|
||||
|
||||
**ikconfig proof (T004038Z vs penúltimo):** see
|
||||
`/srv/rom/artifacts/007-kernelsu/susfs-fail-rca/ikconfig.diff`.
|
||||
|
||||
**abu / KernelSU-Next model (correct for addon):** SusFS is a separate `bool` menu under KSU, **not** in the hook choice. Hooks = KPROBES (or manual). `susfs_init()` under `#ifdef CONFIG_KSU_SUSFS` always.
|
||||
|
||||
### 4.2 First LAB symptom (T004038Z) — vibrator watchdog
|
||||
|
||||
- Not an early panic: Android mostly up, adb works.
|
||||
- `WATCHDOG KILLING SYSTEM PROCESS` blocked in `VibratorManagerService.nativeGetVibratorIds`.
|
||||
- Interpreted as fallout of **missing MANUAL_HOOK** (broken input/LSM hook path / module vermagic issues discussed; drv2624 is vendor module).
|
||||
|
||||
### 4.3 After forcing MANUAL+SusFS — early `kernel_panic`
|
||||
|
||||
Builds with MANUAL (+ later AUTO) + SusFS die at **Google logo**, reboot, often land in **fastboot** after retries.
|
||||
|
||||
**Logging reality on Pixel 4a:**
|
||||
|
||||
- Bootloader **does not support** `fastboot fetch`.
|
||||
- `/dev/block/by-name/klog` and `logfs` dumps show many `PM: Reason: kernel_panic` / `HARD RESET by PS_HOLD` but **no Oops / Call trace**.
|
||||
- `/sys/fs/pstore` empty after successful penúltimo boot; Pixel ramoops often encrypted (`/vendor/bin/ramoops`, keys under CE — missing/unusable in our tries).
|
||||
- Console default: `console=ttyMSM0` only; `# CONFIG_VT is not set` historically → **no Oops text on panel** (only logo).
|
||||
|
||||
### 4.4 Composition bugs fixed in-tree (still not enough for a clean boot)
|
||||
|
||||
Patches applied under `drivers/kernelsu/` (and defconfig / BoardConfig):
|
||||
|
||||
| # | File(s) | Change |
|
||||
|---|---------|--------|
|
||||
| 1 | `Kconfig` + `Kbuild` | SusFS **out of** hook `choice`; SusFS addon + MANUAL together (abu-like). Snapshot: `susfs-fail-rca/kconfig-fix-20260916T090322Z/` |
|
||||
| 2 | `arch/.../sunfish_defconfig` | Re-enable `AUTO_SETUID/INITRC/INPUT=y` (T091211Z had them explicitly **unset**) |
|
||||
| 3 | `runtime/ksud_integration.c` | `#elif CONFIG_KSU_SUSFS` → only if `&& !CONFIG_KSU_MANUAL_HOOK` so `ksu_init_rc_hook` is defined under MANUAL+AUTO (else **link error** `undefined symbol: ksu_init_rc_hook`) |
|
||||
| 4 | `core/init.c` | In `MANUAL_HOOK` branch, also `#ifdef CONFIG_KSU_SUSFS susfs_init()` (abu always inits SusFS) |
|
||||
| 5 | `feature/sucompat.h` + `.c` | `faccessat`/`stat`: SusFS `struct filename **` API **only** if `SUSFS && !MANUAL`. MANUAL call sites in `fs/open.c` / `fs/stat.c` pass `const char __user **` — with SusFS signatures → **ABI mismatch / panic** |
|
||||
| 6 | `feature/sucompat.h` | Privilege macros: SusFS `susfs_is_current_proc_no_su` etc. **only** if `SUSFS && !MANUAL` (was still SusFS when both set — likely early panic) |
|
||||
| 7 | defconfig + BoardConfig (DEBUG) | `PANIC_TIMEOUT=0`, disable `QCOM_FORCE_WDOG_BITE_ON_PANIC`, enable `VT`/`FRAMEBUFFER_CONSOLE`, cmdline `panic=0 console=tty0` when `SUNFISH_DEBUG_PANIC_SCREEN=1`; `SPOOF_CMDLINE` off |
|
||||
|
||||
** empirically:** fix #5 (sigfix T112839Z) made LAB failure **faster** to fastboot → either wrong direction for some other call path, or #6 was the dominant bug and #5 alone left broken macros. #6 is in the DEBUG build, **not yet LAB-proven**.
|
||||
|
||||
### 4.5 Slot / A/B lesson (not the SusFS root cause)
|
||||
|
||||
- After failed trials, `current-slot:b`, `slot-unbootable:a:yes` left LAB unbootable until **both** slots got `boot-005` + `--set-active=a`.
|
||||
- SusFS on **slot a** (same `system_a` as working penúltimo) **still** bootlooped → failure is **SusFS/MANUAL kernel composition**, not stale `system_b`.
|
||||
|
||||
**Flash discipline now:** penúltimo on `boot_a`, experiment on `boot_b`, `--set-active`; rollback = `--set-active=a` (and reflash `a` if needed).
|
||||
|
||||
---
|
||||
|
||||
## 5. Critical comparison: why T004038Z got further than MANUAL+SusFS
|
||||
|
||||
| | T004038Z (SusFS as hook choice) | T091211Z+ (MANUAL+SusFS addon attempts) |
|
||||
|--|----------------------------------|----------------------------------------|
|
||||
| MANUAL_HOOK | **off** | **on** (+ AUTO on later builds) |
|
||||
| Early boot | Survives to userspace / adb | `kernel_panic`, logo loop |
|
||||
| Later failure | Vibrator HAL / system_server watchdog | Never gets there |
|
||||
|
||||
**Hypothesis for reviewers:** ReSukiSU still has multiple `#ifdef CONFIG_KSU_SUSFS` paths written for **XOR** (SusFS *instead of* MANUAL). Turning both on without auditing every `elif` leaves:
|
||||
|
||||
- Wrong sucompat prototypes vs `fs/*.c` hooks
|
||||
- Wrong privilege helpers (`susfs_*` vs TIF flags)
|
||||
- Possibly more (execveat_sucompat, dispatch mark, input hooks, etc.)
|
||||
|
||||
abu avoids this by using **Next + KPROBES** and SusFS as a pure addon with `#ifdef CONFIG_KSU_SUSFS` init, not ReSukiSU’s choice XOR.
|
||||
|
||||
---
|
||||
|
||||
## 6. abu reference details (oracle, not flash path)
|
||||
|
||||
**Tree:** `/srv/rom/references/abu-msm-4.14-ksu/`
|
||||
**KSU:** `drivers/kernelsu` → `../KernelSU-Next/kernel`
|
||||
|
||||
**Kconfig pattern (excerpt behaviour):**
|
||||
|
||||
- `CONFIG_KSU` tristate
|
||||
- `CONFIG_KSU_KPROBES_HOOK` (default y) — not ReSukiSU MANUAL choice
|
||||
- `menu "KernelSU - SUSFS"` → `CONFIG_KSU_SUSFS` bool addon + many `KSU_SUSFS_*` features
|
||||
- `ksu.c`: `#ifdef CONFIG_KSU_SUSFS` → `susfs_init();` **unconditional on SusFS**, independent of kprobes
|
||||
|
||||
**Feature flags abu has that our ReSukiSU SusFS Kconfig may lack:**
|
||||
`HAS_MAGIC_MOUNT`, `AUTO_ADD_SUS_*`, `TRY_UMOUNT*`, `SUS_SU` (kprobes), etc.
|
||||
|
||||
**abu `sunfish_defconfig` in this mirror:** **0** `CONFIG_KSU*` lines — do not treat as the SusFS pin list.
|
||||
|
||||
**Owner note:** abu also ships separate ReSukiSU-oriented boots / managers under artifacts; still **reference**. Our flash path is only `/srv/rom/artifacts/007-kernelsu/boot-resukisu-*` built from **our** tree.
|
||||
|
||||
---
|
||||
|
||||
## 7. Parallel work same day (context, not SusFS)
|
||||
|
||||
- microG Location UI missing on LAB: we had staged official **`*-hw.apk`** (`versionName=…-hw`) which **omits** `NetworkLocationService` / `NetworkLocationProviderService`.
|
||||
- GOLDEN/abu show full Location options with **default** (non-hw) GmsCore.
|
||||
- Fixed: stage `com.google.android.gms-252432032.apk` (non-hw); LAB `adb install -r` restored NLP UI.
|
||||
- GOLDEN/abu = **A15 scheme oracle**; we keep **newer** packages on A16.
|
||||
|
||||
---
|
||||
|
||||
## 8. How we build / logs
|
||||
|
||||
```bash
|
||||
# normal SusFS bootimage (host)
|
||||
/srv/rom/artifacts/bin/rom-detach susfs-boot-NAME -- \
|
||||
bash -lc /srv/rom/artifacts/007-kernelsu/run-susfs-bootimage.sh
|
||||
|
||||
# DEBUG (panic freeze + tty0)
|
||||
/srv/rom/artifacts/bin/rom-detach susfs-boot-debug -- \
|
||||
bash -lc /srv/rom/artifacts/007-kernelsu/run-susfs-bootimage-debug.sh
|
||||
```
|
||||
|
||||
Always record:
|
||||
|
||||
- `/srv/rom/artifacts/detach-<session>-<TS>.log`
|
||||
- `/srv/rom/logs/007-build/susfs-bootimage.log` (or `-debug.log`)
|
||||
- `detach-<session>.status` (`exit=0` / `exit=1`)
|
||||
|
||||
Verify image before flash:
|
||||
|
||||
```bash
|
||||
unpack_bootimg + lz4 -dc kernel + scripts/extract-ikconfig
|
||||
# expect MANUAL_HOOK=y, three AUTO_*=y, KSU_SUSFS=y
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. LAB recovery / log capture protocol (4a)
|
||||
|
||||
```text
|
||||
1. SusFS on boot_b, penúltimo on boot_a, --set-active=b, reboot
|
||||
2. On logo loop: Vol- + Power → fastboot
|
||||
3. fastboot fetch klog → FAILS on this device (unsupported)
|
||||
4. fastboot flash boot_a <penúltimo>; --set-active=a; reboot
|
||||
5. IMMEDIATELY on adb:
|
||||
su -c 'dd if=/dev/block/by-name/klog …; dd if=/dev/block/by-name/logfs …'
|
||||
adb pull → lab-klog-*.bin / lab-logfs-*.bin
|
||||
6. strings | grep kernel_panic|Oops|Call trace|susfs
|
||||
```
|
||||
|
||||
Observed: step 6 usually only `PM: Reason: kernel_panic` — **insufficient for stack**. Hence DEBUG on-screen build.
|
||||
|
||||
---
|
||||
|
||||
## 10. Current tree intent (defconfig snapshot at doc time)
|
||||
|
||||
```
|
||||
CONFIG_KSU=y
|
||||
CONFIG_KSU_MANUAL_HOOK=y
|
||||
CONFIG_KSU_MANUAL_HOOK_AUTO_SETUID_HOOK=y
|
||||
CONFIG_KSU_MANUAL_HOOK_AUTO_INITRC_HOOK=y
|
||||
CONFIG_KSU_MANUAL_HOOK_AUTO_INPUT_HOOK=y
|
||||
CONFIG_KSU_SUSFS=y
|
||||
CONFIG_KSU_SUSFS_SUS_PATH=y
|
||||
CONFIG_KSU_SUSFS_SUS_MOUNT=y
|
||||
CONFIG_KSU_SUSFS_SUS_KSTAT=y
|
||||
# CONFIG_KSU_SUSFS_SPOOF_UNAME is not set
|
||||
CONFIG_KSU_SUSFS_ENABLE_LOG=y
|
||||
CONFIG_KSU_SUSFS_HIDE_KSU_SUSFS_SYMBOLS=y
|
||||
# CONFIG_KSU_SUSFS_SPOOF_CMDLINE_OR_BOOTCONFIG is not set
|
||||
CONFIG_KSU_SUSFS_OPEN_REDIRECT=y
|
||||
CONFIG_KSU_SUSFS_SUS_MAP=y
|
||||
# DEBUG bring-up:
|
||||
CONFIG_PANIC_TIMEOUT=0
|
||||
# CONFIG_QCOM_FORCE_WDOG_BITE_ON_PANIC is not set
|
||||
CONFIG_VT=y
|
||||
CONFIG_VT_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
…
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Open questions for a second opinion
|
||||
|
||||
1. Is ReSukiSU **fundamentally** unsafe to run with `CONFIG_KSU_MANUAL_HOOK=y` **and** `CONFIG_KSU_SUSFS=y` without a larger port from KernelSU-Next’s addon model (more than Kconfig)?
|
||||
2. Given T004038Z reached userspace with SusFS-as-choice (no MANUAL), should bring-up prefer that path and fix vibrator separately, vs insisting on MANUAL+AUTO+SusFS?
|
||||
3. Remaining `#ifdef CONFIG_KSU_SUSFS` sites to audit in ReSukiSU when MANUAL is also on (`sucompat.c` execveat_sucompat, `dispatch.c`, input, etc.)?
|
||||
4. Best way to get a **panic backtrace** on Pixel 4a 4.14 without UART cable (fbcon reliability? pstore decrypt? `CONFIG_PSTORE_CONSOLE`?)?
|
||||
5. Any known ReSukiSU + susfs4ksu commit/tag combo that officially supports “SusFS addon + manual hooks” on non-GKI 4.14?
|
||||
|
||||
---
|
||||
|
||||
## 12. Related docs in-repo
|
||||
|
||||
- `docs/007-abu-vs-ours-susfs.md`
|
||||
- `docs/007-debug-boot-panic-screen.md`
|
||||
- `docs/007-kernelsu-runbook.md`
|
||||
- `docs/session-20260916-handoff.md`
|
||||
- Host: `/srv/rom/artifacts/007-kernelsu/susfs-fail-rca/SUMMARY.txt` and `NOTE-*.txt`
|
||||
|
||||
---
|
||||
|
||||
## 13. Non-goals / constraints
|
||||
|
||||
- No Magisk as production root.
|
||||
- Do not flash abu/torukk/Downloads boots as product.
|
||||
- LAB only; never GOLDEN.
|
||||
- Prefer small attributable patches; large Android builds on `rom-dev01` only, detached (`rom-detach`).
|
||||
|
||||
---
|
||||
|
||||
*End of brief — 2026-09-16 afternoon LAB session after T112839Z failure; DEBUG build in flight.*
|
||||
@@ -0,0 +1,139 @@
|
||||
# SUSFS bring-up: source and artifact audit, 2026-09-16
|
||||
|
||||
Status: **superseded for boot outcome** by
|
||||
[007-lab-results-20260916.md](007-lab-results-20260916.md) — matched
|
||||
DEBUG boot + vendor (correct SELinux) **booted**; SusFS v1.5.5 + Manager
|
||||
35153 verified. This audit retains the ABI / stub / UAF analysis. Banking
|
||||
PASS still FAIL. LAB only; GOLDEN was not accessed.
|
||||
|
||||
## Verified baseline and build
|
||||
|
||||
LAB reports `23.2-20260915-UNOFFICIAL-sunfish`, slot `_a`, kernel
|
||||
`4.14.357-openela-g28f9290ae067-dirty #1 ... Sep 15 18:06:17 UTC 2026`.
|
||||
Approved shell root works. The installed vibrator module probes successfully
|
||||
on this kernel. The DEBUG build started at `2026-09-16T11:51:15Z` and was
|
||||
still linking with `ld.lld` using a full CPU at 12:18Z. Ninja's idle-output
|
||||
warning alone is not a stalled-build diagnosis. Its inputs were not edited
|
||||
during this audit.
|
||||
|
||||
## Confirmed incompatible vendor module
|
||||
|
||||
The installed `/vendor/lib/modules/drv2624.ko` imports `module_layout` with
|
||||
CRC `0xbce8f094`. The SUSFS sigfix build's `Module.symvers` exports it as
|
||||
`0xf9adc508`. There are **31 mismatches among 56 imports**. The matching
|
||||
module in the host output passes all 56 checks against that same symvers.
|
||||
|
||||
Evidence was captured before DEBUG replaced these outputs:
|
||||
|
||||
- Host symvers mtime: `2026-09-16 11:44:39 UTC`.
|
||||
- Host vendor module mtime: `2026-09-16 11:45:48 UTC`.
|
||||
- Kernel config: `CONFIG_MODVERSIONS=y`, module force loading disabled.
|
||||
- Device module loading list: `device/google/sunfish/init.insmod.sunfish.cfg`
|
||||
includes `drv2624.ko` alongside audio, touch and WLAN modules.
|
||||
- Local evidence: `.local-artifacts/007-kernelsu/rca-20260916/`, including
|
||||
`Module.symvers-sigfix`, `drv2624-installed.ko`, `drv2624-built.ko` and CRCs.
|
||||
|
||||
Reproduce with `python3 scripts/check-module-abi.py <Module.symvers> <module.ko>`.
|
||||
Exit 1 means incompatible or unverified; exit 0 verifies CRCs only, not full
|
||||
ABI/CFI/firmware compatibility or device behaviour.
|
||||
|
||||
**Implication:** flashing a SUSFS boot while retaining these installed vendor
|
||||
modules is an invalid release combination. Rebuilding modules on the host
|
||||
does not update the phone's vendor partition. The older vibrator watchdog
|
||||
is consistent with this defect, but historical dmesg or a controlled test is
|
||||
still needed to prove that particular attempt's cause. This result does not
|
||||
prove the cause of the subsequent early panics.
|
||||
|
||||
SUSFS currently changes `task_struct` and `vfsmount`; those changes can affect
|
||||
layouts and transitive exported symbol CRCs. Do not bypass version checks.
|
||||
Package a consistent kernel/modules set and verify all imports before testing.
|
||||
After vendor changes, the old boot alone is not necessarily a valid rollback;
|
||||
preserve the corresponding old vendor/ROM and slot state too.
|
||||
|
||||
## Confirmed filename lifetime defect
|
||||
|
||||
Our `fs/exec.c:do_execveat_common()` calls `__do_execve_file()`, which calls
|
||||
`putname(filename)` on both successful and failed exec paths. The wrapper
|
||||
then calls `ksu_handle_post_execveat()`; ReSukiSU dereferences
|
||||
`filename->name`. This is a use-after-free in the integration. It also exists
|
||||
in the root-only path, so its existence does not establish why only SUSFS
|
||||
panics in the recorded trials.
|
||||
|
||||
Prepared patch:
|
||||
`vendor/sunfish/patches/007-kernelsu/0001-exec-avoid-post-hook-filename-uaf.patch`.
|
||||
It calls `ksu_handle_post_execve()` with NULL filename, which that handler
|
||||
explicitly supports for its LSM adapter. The patch is staged locally, not
|
||||
applied to the running build, and still needs compilation and LAB validation.
|
||||
|
||||
## Confirmed incomplete and mismatched SUSFS API
|
||||
|
||||
The active kernel advertises SUSFS **v1.5.5**, based on upstream
|
||||
`kernel-4.14` at `77905b5a071e6f3669e3b1814cea30147c0801da` (February 2025),
|
||||
plus local compatibility wrappers. It is not a complete modern backport.
|
||||
|
||||
The active `fs/susfs.c` contains:
|
||||
|
||||
- `susfs_add_sus_map()`: reports success without implementing map hiding.
|
||||
- `susfs_set_avc_log_spoofing()`: reports success without the SELinux hook.
|
||||
- `susfs_add_sus_path_loop()`: aliases a one-time addition, with no loop list.
|
||||
- `susfs_run_extra_works()` and `susfs_start_sdcard_monitor_fn()`: no-op.
|
||||
- `susfs_get_enabled_features()`: returns only the generic KSU_SUSFS string.
|
||||
|
||||
The local `st_susfs_sus_path` starts with `err`, then `target_ino`, then a
|
||||
pathname. Modern upstream v2.3.0 starts with the pathname, then `err`.
|
||||
Sharing command numbers or converting a pointer type does not make those
|
||||
wire formats compatible. Do not interpret compile/link success or a manager
|
||||
feature badge as proof that the commands work.
|
||||
|
||||
[ReSukiSU integration documentation](https://resukisu.org/guide/build.html)
|
||||
explicitly directs non-GKI SUSFS integrators to backport the 5.10 patches.
|
||||
Its separate SUSFS hook mode is deliberate; the Kconfig choice is not in
|
||||
itself an upstream bug. Missing manual hooks when selecting SUSFS means
|
||||
the SUSFS integration must provide its own complete hook path.
|
||||
|
||||
## Upstream freshness checked without changing live inputs
|
||||
|
||||
Remote refs were queried directly on 2026-09-16:
|
||||
|
||||
- Latest ReSukiSU tag seen: `v4.2.0-rc2`,
|
||||
`3576e6a5255fc880c00f6a3175d89268a6d942be`.
|
||||
- Active ReSukiSU: `6d674e50a022a85076dcfe4498af9a8bfead2cf9`, nine commits
|
||||
after that tag, non-shallow, rev-list count 4453, computed version 35153,
|
||||
with local patches. Manager binary matching still requires independent
|
||||
verification; the filename is not sufficient.
|
||||
- Latest observed SUSFS 5.10 branch:
|
||||
`e466df60670eab2847ea76940be2f8a125c8adc9`, advertising **v2.3.0**.
|
||||
- Remote 4.14 branch still points to the old v1.5.5 commit above.
|
||||
- Abu reference checkout `ksu-susfs-23.0` is
|
||||
`8c604af9d3d97a8b1b2da1b663a4e39b32697e5a`, with SUSFS **v1.5.12**.
|
||||
This checkout is not proof of the exact source/configuration of the
|
||||
owner's working L22 binary. Do not conflate the two.
|
||||
|
||||
Before a new build, fetch tags, record full revisions and version codes, and
|
||||
use a matching manager and userspace tool. A v2.3.0 port must include actual
|
||||
implementations, correct struct layouts and all call-site adaptations.
|
||||
|
||||
## Panic evidence remains missing
|
||||
|
||||
The known-good dmesg shows the ramoops script exits 0, but inspection shows
|
||||
that the script returns the final key-generation command's status, not the
|
||||
earlier decrypt status. LAB has `vendor.ramoops.decryption.error=1`,
|
||||
`use_alt=0`, and empty pstore. No private key contents were read or copied.
|
||||
Therefore neither successful script exit nor an empty directory proves that
|
||||
the failed kernel produced no backtrace.
|
||||
|
||||
Framebuffer console config does not guarantee a visible panic: display
|
||||
registration and panic timing must also permit output. `panic=0` does not
|
||||
by itself disable every independent hardware watchdog.
|
||||
|
||||
## Next diagnostic work
|
||||
|
||||
1. Preserve DEBUG as a named experiment with hashes/config/source snapshot.
|
||||
2. Fix the lifetime defect in a subsequent isolated change.
|
||||
3. Obtain panic trace or instrument milestones; distinguish kernel init,
|
||||
module load, init and zygote failures rather than infer timing from logo.
|
||||
4. Use a matched kernel/vendor-module deployment and rollback. Never compare
|
||||
different system slots as though only boot changed.
|
||||
5. Complete a modern SUSFS backport with the intended hook model, then verify
|
||||
real command responses, root denial, per-UID hiding and hardware behaviour.
|
||||
Boot success alone does not meet the requested result or feature gates.
|
||||
@@ -0,0 +1,115 @@
|
||||
# Design: native call-recording unlock + FLAG_SECURE override (`008`/`009`)
|
||||
|
||||
**Date**: 2026-09-16
|
||||
**Status**: Approved by owner (requirements); Spec Kit feature
|
||||
`specs/008-call-rec-flag-secure/`
|
||||
**LAB only**: `11231JEC207477`. No Magisk/LSPosed/Zygisk for these features.
|
||||
|
||||
## Problem
|
||||
|
||||
1. Lineage Dialer can refuse call recording based on **country / carrier**
|
||||
rules even when the user wants to record.
|
||||
2. Apps set `FLAG_SECURE` so screenshots / screen capture fail; we want an
|
||||
optional **global** override (project-specific; not AXP Pro catalog).
|
||||
|
||||
## Goals (MVP)
|
||||
|
||||
Two **Developer Options** switches (same UX pattern as `005`
|
||||
`allow_signature_fake`):
|
||||
|
||||
| Toggle (plain language) | Secure setting | Default | Effect when ON |
|
||||
|-------------------------|----------------|---------|----------------|
|
||||
| Disable call recording restrictions | `extendrom_call_recording` (GOLDEN / EXTENDROM) | `0` | Country/region limits ignored; Dialer may record |
|
||||
| Allow screenshots of secure windows | `disable_secure_windows` (AOSP; DO pref `allow_flag_secure_override`) | `0` | Global: ignore `FLAG_SECURE` for screenshots / screen capture (debuggable builds) |
|
||||
|
||||
- **Global only** — product requirement; no per-app lists (not planned).
|
||||
- OFF = stock Android / LOS behaviour.
|
||||
- No root modules required at runtime.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Full AXP call-recording policy UI (auto-record rules, etc.).
|
||||
- Per-app FLAG_SECURE lists (out of scope permanently for this project).
|
||||
- Banking / KernelSU (`007` incomplete).
|
||||
- Shipping Magisk zips.
|
||||
|
||||
## Approaches considered
|
||||
|
||||
### Call recording
|
||||
|
||||
| Approach | Pros | Cons |
|
||||
|----------|------|------|
|
||||
| **A. EXTENDROM / AXP GOLDEN native F_CALLREC** (chosen) | Same Secure key as GOLDEN (`extendrom_call_recording=1` observed); DO + Dialer gate; attributable | Re-validate paths on LOS 23.2 / A16 |
|
||||
| B. Magisk Dialer RRO (`call_record_states.xml`) | Tiny | Not native; no GOLDEN parity; rejected |
|
||||
| C. Blind-copy A11 overlays only | Fast | May no-op without Dialer Java gate |
|
||||
|
||||
**Choice: A.** Primary sources:
|
||||
`/srv/rom/references/extendrom/er.sh` (F_CALLREC),
|
||||
`overlays/call-rec`, `config/call-rec/…/CallRecPreferenceController.java`.
|
||||
Secure string: `Settings.Secure.ER_ALLOW_ANY_CALL_REC = "extendrom_call_recording"`.
|
||||
|
||||
Also enable Dialer `call_recording_enabled` / audio source as needed for
|
||||
sunfish (EXTENDROM sets `call_recording_enabled=true`,
|
||||
`call_recording_audio_source=4`), after verifying LOS 23.2 Dialer still uses
|
||||
those resources.
|
||||
|
||||
### FLAG_SECURE
|
||||
|
||||
| Approach | Pros | Cons |
|
||||
|----------|------|------|
|
||||
| **A. DO → AOSP `DISABLE_SECURE_WINDOWS`** (chosen) | Already in WMS on A16; tiny surface | Debuggable-only gate in stock WMS |
|
||||
| B. Magisk `services.jar` patcher | Works on `user` | Not native ROM |
|
||||
| C. Duplicate frameworks hooks under another Secure key | — | Redundant with AOSP |
|
||||
|
||||
**Choice: A.** Wire Settings DO to `disable_secure_windows`.
|
||||
|
||||
## Design
|
||||
|
||||
### Settings / UI
|
||||
|
||||
- Category under Developer Options (new or shared “Privacy overrides” /
|
||||
EXTENDROM-style categories).
|
||||
- Two `SwitchPreference`s + short legal/risk summaries (call recording:
|
||||
user responsible for local law — EXTENDROM wording as reference).
|
||||
- Controllers mirror `005` / EXTENDROM `DeveloperOptionsPreferenceController`:
|
||||
write `Settings.Secure` 0/1; reset to 0 when Developer Options master is
|
||||
disabled.
|
||||
|
||||
### Call recording path
|
||||
|
||||
1. Inventory LOS 23.2 Dialer: where country/carrier recording is blocked
|
||||
(`isCountryAllowed` or successor).
|
||||
2. When `extendrom_call_recording=1`, treat as allowed (GOLDEN).
|
||||
3. Ensure recording feature is compiled/enabled for Dialer on sunfish
|
||||
(`config.xml` / product overlay as required).
|
||||
4. LAB: enable toggle → place/receive call → record → file exists; disable →
|
||||
region block behaviour restored (or stock deny if in restricted region).
|
||||
|
||||
### FLAG_SECURE path
|
||||
|
||||
1. Confirmed A16: `WindowManagerService` + `WindowState.isSecureLocked()` already
|
||||
honour `Settings.Secure.DISABLE_SECURE_WINDOWS`.
|
||||
2. DO switch writes that key (UI title: Allow screenshots of secure windows).
|
||||
3. LAB userdebug: OFF blocked / ON capturable; document DRM exceptions.
|
||||
|
||||
### Packaging
|
||||
|
||||
- Patches under `vendor/sunfish-a16/patches/008-…` (idempotent apply script
|
||||
like `005-sigspoof`), attributed to EXTENDROM/`er.sh` F_CALLREC (call-rec)
|
||||
and native frameworks work (FLAG_SECURE).
|
||||
- No Magisk in the bacon zip; no Magisk zips in the meta-repo.
|
||||
|
||||
### Validation
|
||||
|
||||
- LAB serial only; document settings get/put and screenshots/logs under
|
||||
`/srv/rom/artifacts/008-…`.
|
||||
- Does not reopen `007` banking gates.
|
||||
|
||||
## Relationship to roadmap numbers
|
||||
|
||||
| Roadmap # | Theme | This feature |
|
||||
|-----------|--------|--------------|
|
||||
| 008 | Call recording | Included |
|
||||
| 009 | FLAG_SECURE | Included (global only) |
|
||||
|
||||
Single Spec Kit directory: `specs/008-call-rec-flag-secure/`.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Runbook: `008` call-rec + FLAG_SECURE (LAB)
|
||||
|
||||
**LAB serial**: `11231JEC207477` only — never GOLDEN.
|
||||
**Apply** (on `rom-dev01`):
|
||||
|
||||
```bash
|
||||
python3 /srv/rom/src/lineage/vendor/sunfish-a16/patches/008-call-rec-flag-secure/apply_008_call_rec_flag_secure.py
|
||||
```
|
||||
|
||||
Idempotent (second run = all “already”). Marker:
|
||||
`SUNFISH_A16_008_CALL_REC_FLAG_SECURE`.
|
||||
|
||||
**Evidence**: `/srv/rom/artifacts/008-call-rec-flag-secure/`
|
||||
**Logs**: `/srv/rom/logs/008-build/`
|
||||
**Backups**: `/srv/rom/artifacts/008-call-rec-flag-secure/bak-snapshots/`
|
||||
|
||||
## Secure keys
|
||||
|
||||
| Key | Default | Source |
|
||||
|-----|---------|--------|
|
||||
| `extendrom_call_recording` | `0` | AXP GOLDEN / EXTENDROM (`ER_ALLOW_ANY_CALL_REC`) |
|
||||
| `disable_secure_windows` | `0` | AOSP A16 `Settings.Secure.DISABLE_SECURE_WINDOWS` (DO UI key `allow_flag_secure_override`) |
|
||||
|
||||
GOLDEN dump: `extendrom_call_recording=1` in
|
||||
`.local-artifacts/002-golden/…/settings/secure-*.txt`.
|
||||
|
||||
## Call-rec — EXTENDROM `F_CALLREC` (applied)
|
||||
|
||||
| Step | LOS 23.2 path | Status |
|
||||
|------|---------------|--------|
|
||||
| Dialer config | `packages/apps/Dialer/.../callrecord/res/values/config.xml` | already `enabled=true`, audio `4` |
|
||||
| Controllers | `Settings/.../ER_CallRecPreferenceController.java` + `ER_CallRecInfo.java` | applied |
|
||||
| Dashboard | `DevelopmentSettingsDashboardFragment.java` | applied |
|
||||
| DO XML | `Settings/res/xml/development_settings.xml` | applied |
|
||||
| Strings | `Settings/res/values/strings.xml` | applied |
|
||||
| Secure const | `frameworks/base/.../Settings.java` `ER_ALLOW_ANY_CALL_REC` | applied |
|
||||
| Dialer gate | `Dialer/.../CallRecorder.java` `canRecordInCurrentCountry` | applied |
|
||||
|
||||
## FLAG_SECURE — A16 inventory (applied via DO only)
|
||||
|
||||
AOSP already implements the capture path:
|
||||
|
||||
- `WindowState.isSecureLocked()` → early false if
|
||||
`mWmService.getDisableSecureWindows()`
|
||||
- `WindowManagerService.updateDisableSecureWindows()` reads
|
||||
`Settings.Secure.DISABLE_SECURE_WINDOWS`
|
||||
- **Only when** `ro.debuggable` / `SYSTEM_DEBUGGABLE` is true (LAB
|
||||
`userdebug` OK; `user` needs retest / possible gate lift later)
|
||||
|
||||
Project work: Settings DO writes that Secure key (no Magisk / no jar patcher).
|
||||
|
||||
## Validation
|
||||
|
||||
See `specs/008-call-rec-flag-secure/quickstart.md`.
|
||||
|
||||
After bacon + flash Magisk-free:
|
||||
|
||||
```bash
|
||||
adb -s 11231JEC207477 shell settings get secure extendrom_call_recording
|
||||
adb -s 11231JEC207477 shell settings get secure disable_secure_windows
|
||||
```
|
||||
|
||||
## `user` vs `userdebug`
|
||||
|
||||
LAB = `userdebug` (DO + WMS secure-windows disable active). Before release
|
||||
(`011`), re-check on `user`: DO visibility (like `005`) and whether
|
||||
`updateDisableSecureWindows` still no-ops when not debuggable — document
|
||||
outcome; do not silently claim `user` PASS.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Documentation
|
||||
|
||||
Project rules: `.specify/memory/constitution.md`
|
||||
Agent rules: `../AGENTS.md`
|
||||
Feature specs: `../specs/`
|
||||
|
||||
Conversation continuity: [`chatgpt-context.md`](chatgpt-context.md) — context
|
||||
from the shared ChatGPT discussion, reconciled with later repository records;
|
||||
non-normative.
|
||||
|
||||
## 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-a16-rom` — Spec Kit / constitution / docs (meta)
|
||||
- `sunfish-rom-manifest`
|
||||
- `sunfish-rom-build`
|
||||
- `sunfish-rom-patches`
|
||||
|
||||
Plus forks only when modification requires them (kernel, frameworks/base,
|
||||
Settings, Dialer, vendor/config).
|
||||
|
||||
## Reference sources (Lineage / AXP / GrapheneOS)
|
||||
|
||||
[`reference-sources.md`](reference-sources.md) — roles, URLs, local vs later
|
||||
`rom-dev01` archive work. **Sunfish only.**
|
||||
|
||||
## Device roles (two sunfish)
|
||||
|
||||
[`device-roles.md`](device-roles.md) — GOLDEN (AXP, do not flash) vs LAB (experiments).
|
||||
|
||||
## AXP sunfish preservation (detail)
|
||||
|
||||
[`axp-sunfish-preservation.md`](axp-sunfish-preservation.md) — Disroot/Codeberg/
|
||||
downloads/Tor cookbook for sunfish-scoped AXP archive. Run after `001` on
|
||||
`rom-dev01`. **Not** a full AXP org clone.
|
||||
|
||||
## AXP Pro parity
|
||||
|
||||
Living matrix (non-normative): [`axp-pro-parity.md`](axp-pro-parity.md).
|
||||
|
||||
## Android 15 → 16 developer delta
|
||||
|
||||
Living notes for porting AXP/GrapheneOS ideas onto LOS 23.2 without blind copy:
|
||||
[`a15-a16-delta.md`](a15-a16-delta.md).
|
||||
|
||||
## Hardening backlog
|
||||
|
||||
Non-normative candidates: [`hardening-backlog.md`](hardening-backlog.md).
|
||||
@@ -0,0 +1,129 @@
|
||||
# Android 15 (AXP GOLDEN) → Android 16 (LOS 23.2) — developer delta
|
||||
|
||||
Living notes for porting **AXP / GrapheneOS ideas** onto our base without
|
||||
blind copy. Non-normative until a row is promoted into a feature `spec.md`.
|
||||
|
||||
| Ours (LAB target) | GOLDEN (oracle) |
|
||||
|-------------------|-----------------|
|
||||
| LineageOS **23.2** / Android **16** | AXP Pro / LOS-derived **22.2** / Android **15** |
|
||||
| `BUILD_ID=BP4A.251205.006`, SDK **36** tree | SDK **35**, `ro.build.version.release=15` |
|
||||
| Device: sunfish (same silicon) | sunfish |
|
||||
|
||||
**Working rule (owner):** prefer AXP A15 scheme when still valid; if A16 is
|
||||
easier, use it; if harder, redesign the *path* to the **same end state**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Already measured on this project
|
||||
|
||||
| Area | A15 / AXP behaviour | A16 / LOS 23.2 reality | Adaptation |
|
||||
|------|---------------------|------------------------|------------|
|
||||
| Phonesky on `/system/priv-app` | Works on GOLDEN | `artifact_path_requirements` / `generic_system.mk` rejects device-specific `system/` installs unless allow-listed | Keep AXP path; `PRODUCT_ARTIFACT_PATH_REQUIREMENT_ALLOWED_LIST` (`004`) — do **not** move to `product` only to silence the check |
|
||||
| GmsCore / Gsf on `system_ext` app | GOLDEN layout | Builds clean (no artifact hit) | Keep |
|
||||
| Priv-app XML for GmsCore | GOLDEN: not priv-app | Inventing `privapp-permissions-microg` diverges | Removed; add only if Self-Check proves need |
|
||||
| Super partition headroom | AXP fuller image fits their budgets | Vanilla LOS ERROR_LIMIT too tight for fat microG+Play | Modest `BOARD_SUPER_PARTITION_ERROR_LIMIT` bump — not ABI-strip of official microG |
|
||||
| Play targetSdk / apktool | Older Play on GOLDEN (50.x) | Latest Play ~52.x needs apktool 2.12 + `ANDROIDSDK=35+`, zipalign-before-sign | Documented in `004` runbook |
|
||||
| PRESIGNED prebuilt APKs | AXP ships Play/microG with intact v2/v3 | `BUILD_PREBUILT` uncompresses JNI / realigns → strips APK Sig v2/v3; PM skips Phonesky (`pm path` empty) | `LOCAL_REPLACE_PREBUILT_APK_INSTALLED` for GmsCore/Gsf/Phonesky (`004`, measured 2026-09-15) |
|
||||
| Phonesky privapp allowlist | AXP XML for older Play | Play 52.x on A16 requests `HIDE_STATUS_BAR_NOTIFICATION` + `READ_SYSTEM_GRAMMATICAL_GENDER`; missing → boot abort on userdebug | Extend `privapp-permissions-com.android.vending.xml` |
|
||||
| Signature spoofing | EXTENDROM: `allow_signature_fake` + `FAKE_PACKAGE_SIGNATURE` + Settings toggle; grants on gms+vending; A15 STABLE | LOS 23.2 **already** has LuK1337 allow-list spoof (`ComputerEngine` `23c0a5c`): userdebug + microG signer + Google fake-sig + `signingInfo`. Missing vs AXP: no `FAKE_PACKAGE` perm/UI; **rejects project-signed Phonesky** | Feature **`005`**: extend signer allow-list for our Phonesky JKS; port EXTENDROM toggle + `FAKE_PACKAGE_SIGNATURE`; see `docs/005-spoofing-runbook.md` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Partition / packaging (porter mindset)
|
||||
|
||||
- AOSP has been tightening **system vs system_ext vs product** for years; A16
|
||||
builds (especially with `generic_system.mk`) make “drop OEM APKs on system”
|
||||
a **build-time** problem, not only a policy preference.
|
||||
- **Privapp-permissions must live on the same partition as the priv-app**
|
||||
(AOSP rule since product partition work). Moving Phonesky later ⇒ move XMLs
|
||||
with it.
|
||||
- `system_ext` remains the natural home for ROM Google-compat substitutes
|
||||
(AXP: microG, F-Droid, Aurora base) — still valid on A16.
|
||||
- Prefer **allow-list exception** or **system_ext/product** over rewriting the
|
||||
whole AXP layout when GSI rules bite.
|
||||
|
||||
---
|
||||
|
||||
## 3. Compatibility stack (microG / Play / spoofing)
|
||||
|
||||
| Topic | Note for A16 |
|
||||
|-------|----------------|
|
||||
| microG | Use **current** upstream; do not pin GOLDEN 0.3.15. Keep official signer for F-Droid. |
|
||||
| Phonesky | Still patch via AXP `patch-playstore`; newer Play = newer apktool/SDK framework. |
|
||||
| Signature spoofing | **Done in `005`:** extend LuK1337 allow-list for project Phonesky JKS; port EXTENDROM toggle + `FAKE_PACKAGE_SIGNATURE`. LAB US6 green 2026-09-15. |
|
||||
| Phonesky FGS / exact-alarm | A16 `systemExempted` needs manifest `USE_EXACT_ALARM` (or SCHEDULE / VPN), not only privapp XML. Fixed in Phonesky rebuild; vendor prebuilt updated. |
|
||||
| FakeStore | Still forbidden next to real Phonesky. |
|
||||
|
||||
---
|
||||
|
||||
## 4. Attestation / KeyMint / banking (`006`/`007`)
|
||||
|
||||
- GOLDEN already shows **KeyMint / RKP / TEE** stress with Yuh on **A15**.
|
||||
- A16 does not remove that class of problem; RKP and attestation surfaces
|
||||
continue to evolve — treat GrapheneOS/AOSP docs as *what* to measure, LOS+LAB
|
||||
as *where* to measure.
|
||||
- Magisk DenyList on GOLDEN ≠ our root plan. Production root = **KSU-Next +
|
||||
SusFS** (`007`). Do not port Magisk-shaped packaging into `004`.
|
||||
|
||||
---
|
||||
|
||||
## 5. GrapheneOS on Android 16 (reference, not base)
|
||||
|
||||
- GOS ported features to A16; publicly noted **harder** device-support work
|
||||
because AOSP dropped much Pixel board/userspace publishing with 16.
|
||||
- For **sunfish** we stay on **LOS 23.2 device trees**, not GOS device bringup.
|
||||
- Use modern GOS as reference for **hardening / privacy behaviour** patches
|
||||
(`013`, hardening backlog) — classify each patch: direct / port / obsolete /
|
||||
A16-incompatible (same discipline as `reference-sources.md`).
|
||||
- Never treat historical GOS **A13 sunfish** kernel as A16 base.
|
||||
|
||||
---
|
||||
|
||||
## 6. Call recording / FLAG_SECURE / UX (`008`+)
|
||||
|
||||
- AXP overlays and older XML toggles often **break or no-op** across major
|
||||
releases. On A16: re-find Dialer/Telecom/framework hooks in LOS 23.2 first;
|
||||
then decide AXP vs EXTENDROM vs iodé vs native LOS.
|
||||
- Screenshot / sensitive-content APIs continue to tighten — verify before
|
||||
porting FLAG_SECURE bypasses.
|
||||
|
||||
---
|
||||
|
||||
## 7. Checklist before applying an AXP or GOS change on A16
|
||||
|
||||
1. What problem does it solve on GOLDEN / in GOS docs?
|
||||
2. Does LOS 23.2 already provide an equivalent?
|
||||
3. Partition + artifact-path impact?
|
||||
4. Same-signer / update path impact (microG, Phonesky)?
|
||||
5. Kernel 4.14 / sunfish EOL constraints?
|
||||
6. If blocked: document blocker; redesign route; **same end state**.
|
||||
|
||||
---
|
||||
|
||||
## 8. Open follow-ups (fill as we hit them)
|
||||
|
||||
- [x] Exact LOS 23.2 spoofing surface for `005` — stock LuK1337 path + our
|
||||
`SUNFISH_A16_005_SIGSPOOF` extension (2026-09-15); runbook
|
||||
`docs/005-spoofing-runbook.md`
|
||||
- [ ] Whether A16 needs any microG permission XML AXP ships outside privapp
|
||||
- [ ] RKP/KeyMint behaviour on LAB after `004` (compare to `002` Yuh logs)
|
||||
- [ ] Call-recording hook locations on LOS 23.2 Dialer
|
||||
- [ ] Which GOS A16 hardening patches are realistic on sunfish 4.14
|
||||
|
||||
## 9. EXTENDROM A15 → A16 mapping (`005`)
|
||||
|
||||
| EXTENDROM A15 patch | LOS 23.2 action |
|
||||
|---------------------|-----------------|
|
||||
| `02`/`06` ComputerEngine FAKE + gate | **Adapt** existing LuK1337 `generateFakeSignature`; add toggle + permission + Phonesky signer |
|
||||
| `01`/`12` api current + lint | Applied |
|
||||
| `07` AndroidManifest permission | Applied |
|
||||
| `03` PermissionMapping | Applied (`.kt` path) |
|
||||
| `04` Activity requestPermissions | Applied (A16 short-circuit path context) |
|
||||
| `05` Settings.Secure.ALLOW_SIGNATURE_FAKE | Applied |
|
||||
| `08`–`11` Settings Developer Options | Applied (controllers + XML + strings) |
|
||||
| Overlay strings | Inlined into frameworks/Settings `strings.xml` |
|
||||
|
||||
Source checkout: `/srv/rom/references/extendrom` @ `f129253c07e735a373441254457cf75efac11d04`.
|
||||
|
||||
Update this file when a delta is **measured** (build error, Self-Check, adb),
|
||||
not from blog speculation alone.
|
||||
@@ -0,0 +1,95 @@
|
||||
# AXP.OS Pro feature parity matrix
|
||||
|
||||
Living tracker for how `sunfish-a16-rom` relates to **AXP.OS Pro** functionality.
|
||||
|
||||
**Non-normative.** This file is a product/backlog tracker. A row becomes a
|
||||
requirement only when promoted into a feature `spec.md`. For an active feature,
|
||||
constitution + that feature's `spec.md` are authoritative if they conflict with
|
||||
this matrix.
|
||||
|
||||
**Goal (constitution):** reproduce AXP.OS Pro functionality except where a
|
||||
feature is obsolete, incompatible with LineageOS 23.2 / Android 16 / sunfish, or
|
||||
deliberately substituted (documented in this table).
|
||||
|
||||
**Do not** treat this as a blind copy list. Every row must state our target and
|
||||
implementation source. Update status as features land.
|
||||
|
||||
Status values: `todo` | `decide` | `substitute` | `wont` | `partial` | `done` |
|
||||
`los-provides` | `later`
|
||||
|
||||
The parity matrix **spans the whole project (`004`–`013`)**. Feature `010` owns
|
||||
only accepted AXP **usability/privacy** items not already assigned to another
|
||||
feature. Signing/AVB, userspace hardening, and kernel hardening remain `011`–
|
||||
`013` even though they also appear here as AXP Pro concerns.
|
||||
|
||||
| Feature | AXP Pro | Our objective | Status | Source / implementation |
|
||||
|---------|---------|---------------|--------|-------------------------|
|
||||
| Base ROM | AXP (LOS-derived) | LineageOS 23.2 / Android 16 sunfish | todo | LOS official `lineage-23.2`; `003` |
|
||||
| On-device release testing | Yes (pre-release device QA) | Yes — stage checklists + known-good builds | todo | `003` smoke; later release gate; `011` |
|
||||
| ASB patch integration / backports | Yes | Prefer LOS merges; backport missing applicable patches; document non-applicable | todo | LOS first; gaps → `012`/`013` |
|
||||
| SELinux enforcing | Yes | Expect **Enforcing**; measure on vanilla then keep | todo | Verify in `003`; then likely `los-provides` |
|
||||
| Data encryption enforced | Yes | Expect encryption enabled; no silent weaken | todo | `003` PIN/encrypt smoke; then likely `los-provides` |
|
||||
| Project signing | Yes | Own keys for release builds | todo | `011` |
|
||||
| Strong signing / AVB key policy | Yes (AVB/APK/dm-verity hardening) | Project AVB + release signing policy | todo | `011` |
|
||||
| Reproducible builds | Yes | Traceable builds; push toward reproducibility | todo | metadata from day one; harden in `011` |
|
||||
| Privacy-focused system defaults | Yes | Decide defaults beyond LOS stock | decide | `010` |
|
||||
| microG + GSF | Yes | Yes — working Self-Check / push | done | `004` packaging + `005` LAB US6 (`23.2-20260915`) |
|
||||
| Patched Phonesky / Play | Yes | Yes — priv-app, updatable | done | Play 52.9.22-24 + exact-alarm; installs OK on LAB (`005`) |
|
||||
| Signature spoofing | Advanced / configured | Restricted LOS + Phonesky JKS + DO toggle | done | `005` runbook; `allow_signature_fake` + `FAKE_PACKAGE` |
|
||||
| Magisk / preroot | Magisk (**Magia** UI on GOLDEN, 29.0) | **Substitute:** KernelSU-Next (+ SusFS) / evaluate ReSukiSU | substitute | Captured in `002`; do **not** fix GOLDEN; project root = `007` on LAB |
|
||||
| DenyList / umount for banks | Magia DenyList (pkg list in `docs/002-golden-inventory.md`) | KernelSU app profiles + verified umount | todo | `007` re-runs `006`; GOLDEN DenyList captured `002` |
|
||||
| Insular work profile | AXP docs say Insular; **GOLDEN measures Island** (`com.oasisfeng.island.fdroid` 6.4.2) | Banking workflow parity (Island or equivalent) | todo | `006`; capture in `002` |
|
||||
| Yuh in Insular/Island | Historically worked; **FAIL since ~weeks** (HA / “certificate invalid”; KeyMint/TEE errors in `002` logs) | Hard-gate Compatibility MVP (rootless in `006`); **Revolut not a hard-gate** | partial | `002` evidence; LAB may need SusFS+TrickyStore-class stack (`reference-sources.md` §8); never GOLDEN |
|
||||
| Swissquote in Insular/Island | **PASS** on GOLDEN (owner report, DenyList) | Hard-gate Compatibility MVP (rootless in `006`) | partial | `002`; re-test in `006`/`007`/`011` |
|
||||
| Unrestricted call recording | Yes | Yes — native ROM on Android 16 | todo | AXP/EXTENDROM/iodé as references only; re-validate on LOS 23.2; `008` |
|
||||
| DNS blocker / privacy DNS | Yes | Wanted; exact UX TBD | decide | `010` |
|
||||
| Hosts / tracker blocking | Yes | Wanted | decide | `010` |
|
||||
| hardened_malloc | Yes | Wanted if cleanly portable | decide | Graphene/AXP; `012`; see hardening backlog |
|
||||
| Hardened / CVE-patched kernel | Yes | LOS 23.2 kernel + Graphene/AXP/Divest backports | todo | `013` (+ selective work with `007`) |
|
||||
| Deblobbing | Yes | Case-by-case; don't break HW | decide | `010` / `013` |
|
||||
| AOSmium WebView | Yes | Ship usable WebView; allow installing alternate WebView providers and selecting the active one in **Developer options → WebView implementation** | decide | `010`; stock/AOSmium/Vanadium/etc. as candidates |
|
||||
| WireGuard in kernel | Yes | Check if LOS 23.2 already sufficient | decide | Baseline in `003`; else `010`/`013` |
|
||||
| eSIM support | Documented on AXP | sunfish support TBD; verify vanilla first | decide | Baseline in `003`; else `010` |
|
||||
| F-Droid + extra repos | Yes | Decide default ship set | decide | `010` |
|
||||
| Aurora Store | Used in golden banking flow | Document/capture; may remain user app | decide | `002` flow; `010` |
|
||||
| NeoLauncher | Default on AXP | Decide LOS launcher vs NeoLauncher | decide | `010` |
|
||||
| Fossify Gallery / bundled app set | Part of AXP usability set | Decide which extras to ship | decide | `010` |
|
||||
| Boot debug | Available | Useful for bring-up | decide | `010` or early debug docs |
|
||||
| Relock / custom AVB | AXP path | Project keys + AVB after stable ROM | todo | `011` |
|
||||
| Widevine (basic) | Yes | Don't regress vs vanilla LOS if possible | decide | Measure in `003`; track in `010`/`011` |
|
||||
| App/data backup | AXP tooling | Not a project gate (two devices: GOLDEN stays; LAB is disposable). Optional personal NeoBackup only; no custom ROM/recovery backup | substitute | See `docs/device-roles.md` |
|
||||
| Extra bundled packages | Various | Only if justified | decide | `010` |
|
||||
| Auto-reboot / radio timers | Privacy extras | Wanted where practical | decide | `010` |
|
||||
|
||||
## Mapping rules
|
||||
|
||||
| AXP mechanism | Our default approach |
|
||||
|---------------|----------------------|
|
||||
| Magisk | KernelSU-Next (`007`); Magisk only as A/B diagnostic if needed |
|
||||
| AXP signature spoofing stack | LOS restricted spoofing + controlled Phonesky extension (`005`) |
|
||||
| AXP hardened kernel tree | LOS sunfish kernel + selective backports |
|
||||
| AXP Phonesky | Keep functionality; reproducible patch/sign pipeline |
|
||||
| AXP call-recording toggles (older Android) | Re-validate on Android 16; do not blind-port XML |
|
||||
| AXP backup/restore tooling | NeoBackup (external); no project-owned backup feature |
|
||||
| AXP AOSmium / extras | Explicit decide rows above — not silent omissions |
|
||||
| WebView provider | Keep Android multi-provider path: install other WebViews + choose in Developer options |
|
||||
|
||||
## Project-specific additions
|
||||
|
||||
Not AXP Pro catalog features. Tracked here so they are not confused with parity.
|
||||
|
||||
| Feature | Origin | Objective | Status | Feature # |
|
||||
|---------|--------|-----------|--------|-----------|
|
||||
| FLAG_SECURE override | Project requirement | Native control: Android default remains default; **global** DO override only (no per-app); screenshots + screen capture; no LSPosed/Zygisk/root module | todo | `009` / `008-call-rec-flag-secure` |
|
||||
| Optional root-unavailable boot mode | Project / msg-GrapheneOS inspiration | Diagnostic/fallback boot without root | later | after daily-driver MVP |
|
||||
| Upstream deprecation / Kotlin warning hygiene | Build log noise on LOS 23.2 | **Last steps before final ROM freeze:** triage remaining compile warnings; migrate call sites API-by-API (or inherit LOS fixes); keep our patches warning-clean. Not a gate for `005`–`010` MVPs. | later | after `010` / with `011` freeze; see `docs/hardening-backlog.md` |
|
||||
|
||||
## Ownership
|
||||
|
||||
- Matrix maintained in this file (`docs/axp-pro-parity.md`).
|
||||
- Rows may map to `004`–`013`; **`010` is not “all of AXP Pro parity”** — only
|
||||
remaining usability/privacy items not owned elsewhere.
|
||||
- `002` captures what the **current device** actually runs; this matrix is the
|
||||
**product intent** relative to AXP Pro docs + that capture.
|
||||
- Compatibility MVP ends at `006` (rootless); Daily-driver MVP ends at `010`
|
||||
(constitution). Hardening candidates: `docs/hardening-backlog.md`.
|
||||
@@ -0,0 +1,510 @@
|
||||
# AXP.OS sunfish preservation / reference archive
|
||||
|
||||
Parent overview (Lineage + AXP + GrapheneOS): [`reference-sources.md`](reference-sources.md).
|
||||
|
||||
## Purpose
|
||||
|
||||
AXP.OS is an important historical and functional reference for
|
||||
`sunfish-a16-rom`.
|
||||
|
||||
Some AXP.OS infrastructure is self-hosted and may disappear. Preserve **useful
|
||||
publicly accessible material related to sunfish / AXP.OS A15** before relying on
|
||||
it during later ROM development.
|
||||
|
||||
This archive is **REFERENCE** material. It is **not** the base ROM.
|
||||
|
||||
```text
|
||||
GOLDEN device: AXP.OS 22.2 / Android 15 on sunfish
|
||||
historical GOS: Android 13 sunfish (hardening reference only)
|
||||
new ROM base: LineageOS 23.2 / Android 16
|
||||
AXP sources: reference inputs only
|
||||
```
|
||||
|
||||
**Do not** block ROM development indefinitely on recovering unavailable AXP
|
||||
material.
|
||||
|
||||
**Do not** archive all ~225 Disroot repositories (Sony, OnePlus, Fairphone,
|
||||
unrelated Pixels, etc.).
|
||||
|
||||
```text
|
||||
AXP archive != complete backup of AXP.OS
|
||||
AXP archive == what is needed to understand, reproduce, and port
|
||||
AXP.OS A15 for SUNFISH
|
||||
```
|
||||
|
||||
Execute this work on **`rom-dev01`** under `/srv/rom/references/axp/`. Do not
|
||||
keep growing large mirrors on the laptop once the server copy is verified.
|
||||
|
||||
---
|
||||
|
||||
## When to run
|
||||
|
||||
- After `001` has `/srv/rom` and `android-build` SSH working.
|
||||
- Before or in parallel with early `002` (does not replace GOLDEN live `adb`).
|
||||
- Prefer rsync of the existing laptop archive first, then fill gaps on the server.
|
||||
|
||||
---
|
||||
|
||||
## Architecture reminder
|
||||
|
||||
| Role | Meaning |
|
||||
|------|---------|
|
||||
| GOLDEN | Live AXP.OS 22.2 / A15 — do not flash for experiments |
|
||||
| LAB | LOS / project ROM experiments only |
|
||||
| This archive | Offline docs + sunfish-related git/releases on `rom-dev01` |
|
||||
|
||||
See also: `docs/device-roles.md`.
|
||||
|
||||
---
|
||||
|
||||
## 1. Known AXP.OS hosting
|
||||
|
||||
### Main website
|
||||
|
||||
Preserve (rendered + git source):
|
||||
|
||||
- https://axpos.org/
|
||||
- https://axpos.org/news/
|
||||
- https://axpos.org/docs/
|
||||
- https://axpos.org/devices/
|
||||
- https://axpos.org/devices/google/sunfish/
|
||||
- https://axpos.org/devices/changelogs/2026/
|
||||
- https://axpos.org/docs/knowledge/faq/
|
||||
- https://axpos.org/docs/knowledge/reproducible/
|
||||
- https://axpos.org/docs/knowledge/microg/
|
||||
- https://axpos.org/docs/knowledge/callrec/
|
||||
- https://axpos.org/docs/knowledge/features/
|
||||
- https://axpos.org/docs/knowledge/technical-details/
|
||||
|
||||
Website hosting: Codeberg.
|
||||
|
||||
Website source:
|
||||
|
||||
- https://codeberg.org/AXP-OS/axpos-org
|
||||
- https://codeberg.org/AXP-OS/axpos-org.git
|
||||
|
||||
Observed branches: `hugo`, `pages`.
|
||||
|
||||
Official docs describe:
|
||||
|
||||
| Host | Role |
|
||||
|------|------|
|
||||
| **Disroot** (`git.disroot.org/AXP.OS`) | Main **public** mirror of repos / APK releases / reproducible-build data |
|
||||
| **code.binbash.rocks/AXP.OS** | Complete self-hosted set (CI, internals) — **not** anonymously public |
|
||||
| **Codeberg** | Partial (website + fewer repos after Jan 2026 removals) |
|
||||
| **GitHub** (`github.com/AXP-OS`) | Mainly APK/release mirror |
|
||||
|
||||
---
|
||||
|
||||
### Public source mirror: Disroot
|
||||
|
||||
- Org: https://git.disroot.org/AXP.OS
|
||||
- API: https://git.disroot.org/api/v1/orgs/AXP.OS/repos
|
||||
|
||||
Snapshot **2026-08-09** (inventory only — not a mandate to clone everything):
|
||||
|
||||
- Repos: **225**
|
||||
- Forgejo reported size: **49,908,145 KiB (~48 GiB)** Git metadata only
|
||||
- **Additional** space needed for LFS, releases, wikis, downloads
|
||||
|
||||
Generate inventory dynamically from the API. Do **not** maintain a hard-coded
|
||||
full org clone list.
|
||||
|
||||
---
|
||||
|
||||
### Codeberg
|
||||
|
||||
- https://codeberg.org/AXP-OS
|
||||
- Snapshot 2026-08-09: **14** public repos, complete attempt ~**38 GiB**
|
||||
- Includes `axpos-org` website source
|
||||
- **Not** a complete AXP source archive (100+ repos removed Jan 2026 per AXP docs)
|
||||
|
||||
Known laptop archive: `~/Archives/AXP.OS/codeberg/`
|
||||
|
||||
Known issue: `legacy_prebuilt_apps.git` has historical LFS pointers whose objects
|
||||
return **HTTP 404** on Codeberg.
|
||||
|
||||
```text
|
||||
"Git mirror valid" != "all historical LFS content preserved"
|
||||
```
|
||||
|
||||
Do **not** delete the Codeberg archive just because Disroot is newer/larger.
|
||||
|
||||
---
|
||||
|
||||
### GitHub
|
||||
|
||||
- https://github.com/AXP-OS
|
||||
- Documented focus: APK/release mirror (PhoneSky, AOSmium, OpenEUICC, …)
|
||||
- Lower priority; useful independent source for artifacts/public keys
|
||||
|
||||
---
|
||||
|
||||
### Self-hosted Gitea (not publicly readable)
|
||||
|
||||
- https://code.binbash.rocks / https://code.binbash.rocks/AXP.OS
|
||||
- Observed DNS 2026-08-09: `148.251.225.181`
|
||||
- Site root HTTP 200; anonymous org API returned `[]`
|
||||
- Historical repo URLs request auth; web 404
|
||||
|
||||
**Do not** attempt to bypass access controls. Only use legitimately public
|
||||
material. Official docs: this host holds the complete private set.
|
||||
|
||||
---
|
||||
|
||||
## 2. Download / OTA infrastructure
|
||||
|
||||
### Clearnet downloads
|
||||
|
||||
- https://download.axpos.org (DNS 2026-08-09 → `148.251.225.182`, PTR yes.binbash.rocks)
|
||||
- Root `/` may time out; **always probe exact paths**
|
||||
|
||||
Sunfish paths:
|
||||
|
||||
```text
|
||||
PRO: https://download.axpos.org/axp/sunfish/
|
||||
…/factory/ …/recovery/ …/tests/
|
||||
|
||||
SLIM: https://download.axpos.org/axp-slim/sunfish/
|
||||
```
|
||||
|
||||
Device page confirms **AXP.OS 22.2 / Android 15** for Pro and Slim, with links
|
||||
to OS zip, recovery, factory, and keys.
|
||||
|
||||
When reachable, preserve for sunfish (Pro + Slim as available):
|
||||
|
||||
- OS ZIPs, `.prop`, `.sha512sum`
|
||||
- recovery / factory packages
|
||||
- relevant test artifacts
|
||||
- signing / AVB **public** keys
|
||||
|
||||
Never treat images as trusted without published checksums/signatures.
|
||||
|
||||
Example filenames seen in indexes (verify live):
|
||||
|
||||
```text
|
||||
AXP.OS-22.2-20260324-PRO-sunfish.zip(+.prop+.sha512sum)
|
||||
AXP.OS-22.2-20260331-PRO-sunfish.zip(+.prop+.sha512sum)
|
||||
```
|
||||
|
||||
### Tor download mirror
|
||||
|
||||
Onion advertised by AXP:
|
||||
|
||||
```text
|
||||
e3tx35xwvqoihx36tjmnzurjcghs6kjwrwnen55jg7ujqilbaicutpid.onion
|
||||
HTTP :8008 (main documented alias)
|
||||
HTTPS :9009 (historical)
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```text
|
||||
http://…onion:8008/axp/sunfish/
|
||||
http://…onion:8008/axp-slim/sunfish/
|
||||
```
|
||||
|
||||
Probe when preservation runs; do not assume availability.
|
||||
|
||||
### Legacy download host
|
||||
|
||||
`leech.binbash.rocks` — observed unavailable 2026-08-09 (timeouts / refused).
|
||||
Treat as legacy; `download.axpos.org` replaced port-8008 URLs per changelog.
|
||||
|
||||
### OTA
|
||||
|
||||
```text
|
||||
https://update.axpos.org
|
||||
https://update-unstable.axpos.org
|
||||
```
|
||||
|
||||
Both resolved to `148.251.225.182` (2026-08-09); `/` → HTTP 403 Apache.
|
||||
403 on `/` ≠ OTA API dead (updater endpoints, not browsing).
|
||||
|
||||
Older (pre build 2026.005):
|
||||
|
||||
```text
|
||||
https://sfxota.binbash.rocks:8010
|
||||
https://sfxota-unstable.binbash.rocks:8010
|
||||
```
|
||||
|
||||
If needed: capture the exact OTA URL from **GOLDEN** via `adb logcat` while
|
||||
checking for updates — **do not modify GOLDEN** merely for discovery.
|
||||
|
||||
---
|
||||
|
||||
## 3. Historical IP snapshot (diagnostic only)
|
||||
|
||||
Observed **2026-08-09** — **never hard-code**; re-resolve DNS before use:
|
||||
|
||||
| Host | IPv4 |
|
||||
|------|------|
|
||||
| axpos.org | 217.197.84.141 |
|
||||
| code.binbash.rocks | 148.251.225.181 |
|
||||
| download.axpos.org | 148.251.225.182 |
|
||||
| update.axpos.org | 148.251.225.182 |
|
||||
| update-unstable.axpos.org | 148.251.225.182 |
|
||||
| leech.binbash.rocks | 162.55.66.39 |
|
||||
|
||||
---
|
||||
|
||||
## 4. Existing laptop archive → server first
|
||||
|
||||
Laptop working location:
|
||||
|
||||
```text
|
||||
~/Archives/AXP.OS/
|
||||
website-rendered/
|
||||
codeberg/
|
||||
disroot-repositories.jsonl
|
||||
mirror-forgejo-org.sh
|
||||
…
|
||||
```
|
||||
|
||||
**Do not** redownload blindly.
|
||||
|
||||
Once `rom-dev01` is available:
|
||||
|
||||
```bash
|
||||
ssh android-build@rom-dev01 \
|
||||
'mkdir -p /srv/rom/references/axp/archive'
|
||||
|
||||
rsync -aH --partial --info=progress2 \
|
||||
"$HOME/Archives/AXP.OS/" \
|
||||
android-build@rom-dev01:/srv/rom/references/axp/archive/
|
||||
|
||||
du -sh ~/Archives/AXP.OS
|
||||
ssh android-build@rom-dev01 'du -sh /srv/rom/references/axp/archive'
|
||||
```
|
||||
|
||||
Keep the laptop copy until the server copy is verified.
|
||||
|
||||
---
|
||||
|
||||
## 5. Suggested server layout
|
||||
|
||||
```text
|
||||
/srv/rom/references/axp/archive/
|
||||
├── website-rendered/
|
||||
├── codeberg/
|
||||
│ ├── git/
|
||||
│ ├── releases/
|
||||
│ └── metadata/
|
||||
├── disroot/
|
||||
│ ├── git/ # sunfish-selected repos only (see §8)
|
||||
│ ├── releases/
|
||||
│ └── metadata/
|
||||
├── github/ # optional APK/release mirrors
|
||||
├── downloads/
|
||||
│ ├── sunfish-pro/
|
||||
│ └── sunfish-slim/
|
||||
├── status/
|
||||
├── tools/ # e.g. mirror-forgejo-org.sh
|
||||
└── README.md
|
||||
```
|
||||
|
||||
Separate from any **working checkouts** used during active porting.
|
||||
|
||||
---
|
||||
|
||||
## 6. Storage preflight (mandatory)
|
||||
|
||||
```bash
|
||||
df -h /srv/rom
|
||||
du -sh /srv/rom/references/axp/archive 2>/dev/null || true
|
||||
```
|
||||
|
||||
Preservation **must not** consume space needed for LOS tree, `out/`, ccache,
|
||||
artifacts.
|
||||
|
||||
Full Disroot org (~48 GiB Git + LFS/releases) is **out of scope**. Prefer
|
||||
sunfish-selected set (typically far smaller) + website + sunfish images.
|
||||
|
||||
---
|
||||
|
||||
## 7. What to preserve (sunfish-scoped)
|
||||
|
||||
### Always (small / high value)
|
||||
|
||||
1. Rendered website (`axpos.org`) + `sitemap.xml` / `robots.txt`
|
||||
2. `axpos-org.git` (Codeberg)
|
||||
3. Existing Codeberg org archive (rsync; refresh optionally)
|
||||
4. Disroot org **inventory JSONL** (metadata only)
|
||||
5. Status probe snapshots under `status/`
|
||||
|
||||
### Highest priority if downloads work
|
||||
|
||||
Sunfish Pro/Slim OS zip, recovery, factory, `.prop`, `.sha512sum`, public keys
|
||||
(clearnet path first; Tor fallback).
|
||||
|
||||
### Git (Disroot / public) — selection rule
|
||||
|
||||
**Do not** clone all 225 repos.
|
||||
|
||||
**Do** discover the exact set from **sunfish A15 / 22.2** reproducible-build /
|
||||
manifest / `axp_versioning` data, then clone **that** set (+ histories).
|
||||
|
||||
Minimum explicit interest (seed list — expand from manifests):
|
||||
|
||||
| Priority | Examples |
|
||||
|----------|----------|
|
||||
| Device/kernel | `android_device_google_sunfish`, `android_kernel_google_msm-4.14` |
|
||||
| Versioning | `axp_versioning`, sunfish-related manifests / `axp.xml` tags |
|
||||
| Likely port targets | `android_frameworks_base`, `android_packages_apps_Settings`, shared `build`/config **if** present in sunfish build |
|
||||
| Compat features | microG / signature spoofing / Phonesky-related public repos |
|
||||
| Features we want | call recording, FLAG_SECURE-related, hardening **used by sunfish A15** |
|
||||
|
||||
Exclude by default: other OEMs/devices, unrelated Pixel generations, bulk
|
||||
device trees not referenced by the sunfish A15 build.
|
||||
|
||||
### Lower priority
|
||||
|
||||
GitHub APK/release mirrors for apps we care about (Phonesky, etc.).
|
||||
|
||||
### Out of scope
|
||||
|
||||
Private `code.binbash.rocks` content without credentials.
|
||||
|
||||
---
|
||||
|
||||
## 8. Manifest-driven repo selection (preferred workflow)
|
||||
|
||||
1. From archived docs / Disroot, locate sunfish **22.2 / A15** reproducible
|
||||
tags and `axp_versioning` / manifest (`axp.xml` or equivalent).
|
||||
2. Extract the list of repositories + revisions for that build.
|
||||
3. Clone `--mirror` **only those** repos (plus any tiny shared deps they need).
|
||||
4. Record the selection in
|
||||
`/srv/rom/references/axp/archive/status/sunfish-repo-selection.txt`
|
||||
with tag/build id and date.
|
||||
5. `git fsck --full` per mirror; `git lfs fetch --all` where applicable; log LFS
|
||||
failures separately (404s are expected for some historical objects).
|
||||
|
||||
Fallback if manifests are incomplete: inventory API + name filters
|
||||
(`sunfish`, `msm-4.14`, `phonesky`, `microg`, `signature`, `spoof`, `callrec`,
|
||||
`versioning`, `manifest`, …) **plus** manual review — still not “clone org”.
|
||||
|
||||
---
|
||||
|
||||
## 9. Website commands (server refresh)
|
||||
|
||||
```bash
|
||||
mkdir -p /srv/rom/references/axp/archive/website-rendered
|
||||
|
||||
wget \
|
||||
--mirror --page-requisites --convert-links --adjust-extension \
|
||||
--restrict-file-names=unix --domains=axpos.org \
|
||||
--directory-prefix=/srv/rom/references/axp/archive/website-rendered \
|
||||
https://axpos.org/
|
||||
|
||||
curl -fL https://axpos.org/sitemap.xml \
|
||||
-o /srv/rom/references/axp/archive/website-sitemap.xml || true
|
||||
curl -fL https://axpos.org/robots.txt \
|
||||
-o /srv/rom/references/axp/archive/website-robots.txt || true
|
||||
```
|
||||
|
||||
Prefer transferring the existing laptop `website-rendered/` and `axpos-org.git`
|
||||
via rsync; refresh only if needed:
|
||||
|
||||
```bash
|
||||
git --git-dir=axpos-org.git remote update --prune
|
||||
git --git-dir=axpos-org.git show-ref
|
||||
git --git-dir=axpos-org.git fsck --full
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Forgejo inventory (Disroot / Codeberg)
|
||||
|
||||
```bash
|
||||
tmp="$(mktemp)"; page=1
|
||||
while :; do
|
||||
data="$(curl -fsSL \
|
||||
"https://git.disroot.org/api/v1/orgs/AXP.OS/repos?limit=50&page=$page")"
|
||||
count="$(jq 'length' <<<"$data")"
|
||||
[ "$count" -eq 0 ] && break
|
||||
jq -c '.[]' <<<"$data" >> "$tmp"
|
||||
page=$((page + 1))
|
||||
done
|
||||
cp "$tmp" /srv/rom/references/axp/archive/disroot/metadata/disroot-repositories.jsonl
|
||||
rm "$tmp"
|
||||
```
|
||||
|
||||
Useful queries: largest repos; name filter for sunfish-interest (see research
|
||||
notes). Same pattern for Codeberg org `AXP-OS`.
|
||||
|
||||
If using `mirror-forgejo-org.sh` from the laptop archive:
|
||||
|
||||
- **Codeberg**: OK to refresh the small org into `archive/codeberg/`
|
||||
- **Disroot**: do **not** invoke a full-org mirror by default; use
|
||||
manifest-selected clones into `archive/disroot/git/`
|
||||
|
||||
Scripts must be resumable; one repo failure must not abort the batch; prefer
|
||||
`git remote update --prune` over delete/reclone.
|
||||
|
||||
---
|
||||
|
||||
## 11. Service / path probes
|
||||
|
||||
Probe roots **and** exact sunfish paths (`/axp/sunfish/`, `/axp-slim/sunfish/`).
|
||||
Save under `archive/status/` with `date -Is`.
|
||||
|
||||
Tor fallback (optional):
|
||||
|
||||
```bash
|
||||
# apt: tor torsocks — only if needed
|
||||
curl --socks5-hostname 127.0.0.1:9050 --connect-timeout 30 --max-time 120 -I \
|
||||
'http://e3tx35xwvqoihx36tjmnzurjcghs6kjwrwnen55jg7ujqilbaicutpid.onion:8008/axp/sunfish/'
|
||||
```
|
||||
|
||||
Mine archived website for URLs:
|
||||
|
||||
```bash
|
||||
grep -RhoE 'https?://[^"<> ]+' \
|
||||
/srv/rom/references/axp/archive/website-rendered/axpos.org 2>/dev/null |
|
||||
grep -Ei 'axpos|binbash|codeberg|disroot|github|sunfish' | sort -u \
|
||||
> /srv/rom/references/axp/archive/discovered-urls.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. Verification
|
||||
|
||||
```bash
|
||||
find /srv/rom/references/axp/archive -type d -name '*.git' -prune | wc -l
|
||||
du -sh /srv/rom/references/axp/archive/*
|
||||
date -Is > /srv/rom/references/axp/archive/SNAPSHOT_DATE.txt
|
||||
```
|
||||
|
||||
Document LFS/release errors. Do not claim 100% completeness if objects 404.
|
||||
|
||||
---
|
||||
|
||||
## 13. Priority order (execution)
|
||||
|
||||
1. rsync laptop `~/Archives/AXP.OS/` → server; verify `du`
|
||||
2. Storage preflight (`df`)
|
||||
3. Website rendered + `axpos-org.git` (if not already complete)
|
||||
4. Probe/download **sunfish** Pro/Slim images + checksums/keys (clearnet → Tor)
|
||||
5. Disroot inventory JSONL + **manifest-driven** sunfish repo mirrors
|
||||
6. Optional Codeberg refresh; optional GitHub APK repos of interest
|
||||
7. Status snapshot + selection file
|
||||
|
||||
Skip: full Disroot org; private binbash Gitea; endless LFS 404 retries.
|
||||
|
||||
---
|
||||
|
||||
## 14. Later development use
|
||||
|
||||
Do **not** blindly cherry-pick AXP into LOS 23.2.
|
||||
|
||||
For each candidate:
|
||||
|
||||
1. Identify repo + AXP branch/tag/build (prefer sunfish 22.2 / A15)
|
||||
2. Identify corresponding LOS/AOSP base
|
||||
3. Inspect full diff
|
||||
4. Classify: direct / port / obsolete / superseded / A16-incompatible
|
||||
5. Record provenance; dedupe vs LOS / GrapheneOS / DivestOS
|
||||
6. Apply one logical change; build; test on **LAB** only
|
||||
|
||||
AXP A15 GOLDEN remains the live oracle.
|
||||
LOS 23.2 / Android 16 remains the base.
|
||||
@@ -0,0 +1,100 @@
|
||||
# ChatGPT conversation continuity
|
||||
|
||||
Imported context: 2026-09-13 from [mi ROM](https://chatgpt.com/share/6aa718c6-c834-83ed-9e2d-2b18fc1ad141).
|
||||
|
||||
This is a non-normative continuity note, not a replacement for the constitution
|
||||
or feature specs. The shared page was retrieved and its user/assistant text
|
||||
extracted. The payload contains repeated messages; extraction order is not a
|
||||
reliable chronology. Linked attachments, redacted tool outputs and the original
|
||||
external citations have not been independently recovered or verified. Historical
|
||||
assistant suggestions are not new user instructions or verified technical facts.
|
||||
The raw conversation is not copied into Git because it includes unrelated
|
||||
personal topics and diagnostic data.
|
||||
|
||||
## Intent and settled direction
|
||||
|
||||
- Build a personal, maintainable ROM for **Pixel 4a / sunfish only**, with
|
||||
LineageOS 23.2 / Android 16 as the base and AXP.OS Pro as the functional
|
||||
reference. The motivation is continuity beyond AXP maintenance.
|
||||
- Functionality comes first, especially microG, patched Google Play and banking
|
||||
inside Insular. Yuh and Swissquote are the required targets; N26 and Revolut
|
||||
were optional challenges, not reasons to block the project.
|
||||
- Preserve two-device separation: GOLDEN is the daily AXP reference; LAB is for
|
||||
experiments. The conversation corrected an earlier A13 mix-up: GOLDEN is AXP
|
||||
A15; historical GrapheneOS sunfish is A13. Never revive the earlier assumption
|
||||
that there is only one phone or that GOLDEN must be wiped/restored.
|
||||
- Keep the compatible LineageOS kernel/device stack. Study historical sunfish
|
||||
GrapheneOS, modern applicable GrapheneOS techniques, and AXP/DivestOS changes;
|
||||
do not transplant an old GrapheneOS or stock A13 kernel into the A16 ROM.
|
||||
- Rootless compatibility comes first (`006`), then KernelSU-Next (`007`) with
|
||||
a complete banking regression. Magisk describes the existing AXP workflow,
|
||||
not an intermediate production architecture for the new ROM.
|
||||
- Native call recording and configurable FLAG_SECURE override matter for daily
|
||||
use. Prefer integrating these into the ROM over depending on root modules.
|
||||
- Insular starts as a user app; Managed Mainland is optional. Preserve the
|
||||
historical Aurora → do not launch → deny root → Insular first launch → Play
|
||||
update workflow as reference, with exact current behaviour measured in `002`.
|
||||
- NeoBackup was accepted as an external personal tool. A custom TWRP-like full
|
||||
backup implementation is not part of the ROM project.
|
||||
- Signing, AVB/relocking and OTA remain later release work. The conversation
|
||||
raised hardware attestation explicitly: do not promise Play Integrity or
|
||||
hardware-attestation success merely because the ROM has KernelSU or custom
|
||||
signing. Validate actual banking behaviour and research current requirements
|
||||
when that feature is implemented.
|
||||
|
||||
## Additional research context
|
||||
|
||||
The last Phonesky discussion considered module-based installers, but retained
|
||||
the AXP-style patch/build/sign pipeline as the intended direction. It identified
|
||||
`https://github.com/AXP-OS/packages_apps_phonesky` as a research lead for the
|
||||
patcher, versioned diffs and release automation. Revalidate upstream before use;
|
||||
do not treat the historical version or maintenance claims as current facts.
|
||||
Stable signing identity and subsequent APK updates belong in feature `004`.
|
||||
|
||||
Privacy candidates included SUPL identifiers, Build.SERIAL restrictions,
|
||||
package visibility, MAC privacy, analytics removal, hosts/DNS filtering,
|
||||
certificate review, auto-reboot, radio timeouts and log reduction. Preserve them
|
||||
through [the existing backlog](hardening-backlog.md), promoting requirements
|
||||
into specs before implementation.
|
||||
|
||||
## Working preferences and infrastructure
|
||||
|
||||
The user prefers Spanish conversation, concrete next steps and manageable stages;
|
||||
large speculative plans and repeated reopening of settled decisions are tiring.
|
||||
Technical project documentation remains English.
|
||||
|
||||
The laptop has limited storage. Android trees, builds and growing reference
|
||||
archives belong on `rom-dev01`; local work centres on editing, SSH, adb/fastboot
|
||||
and artifact transfer. The agreed planning capacity was **6 vCPU, 52 GB RAM,
|
||||
32 GB swap and approximately 2 TB expandable disk**. The chat explicitly
|
||||
corrected assistant claims of 16 vCPU/64 GB/750 GB and confusion between laptop
|
||||
free space and server capacity. Actual host measurements still take precedence.
|
||||
|
||||
Keep independent Gitea repositories, Ansible and Semaphore; do not fold this
|
||||
personal project into company GitLab, Redmine or Salt workflows. VM provisioning
|
||||
remains outside this repository. Public IP, public web access, SSH tunnels and
|
||||
possible future WireGuard were discussed separately. That discussion is not
|
||||
authorization to expose services: current constitution/spec access rules govern.
|
||||
|
||||
AXP preservation is scoped to sunfish and relevant shared dependencies, not all
|
||||
225 Disroot repositories or every GrapheneOS archive. Transfer and verify the
|
||||
existing laptop archive before redundant downloads. Historical LFS failures and
|
||||
service outages are observations, not proof of current availability. Existing
|
||||
[reference sources](reference-sources.md) and
|
||||
[preservation instructions](axp-sunfish-preservation.md) already capture this.
|
||||
|
||||
## Current repository supersedes historical waiting state
|
||||
|
||||
The chat ended its planning phase waiting for `rom-dev01` before implementing
|
||||
`001`. That is historical context, not today's task status. Repository records
|
||||
dated 2026-09-13 already describe host work, the `002` handoff, and `003` source
|
||||
initialization. See [002 handoff](002-gate-handoff.md) and
|
||||
[003 build notes](003-build-notes.md); live execution status was not checked
|
||||
during this context import.
|
||||
|
||||
In particular, `002` now documents a Yuh failure on GOLDEN. The earlier statement
|
||||
that both banks worked is a historical observation, not a substitute for the
|
||||
current inventory or a reason to mark compatibility passed.
|
||||
|
||||
Resume from current feature evidence and tasks, preserving this conversation's
|
||||
intent without replaying old commands or overwriting newer decisions.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Device roles — two Pixel 4a (sunfish)
|
||||
|
||||
Project assumption: **two physical sunfish devices**.
|
||||
|
||||
| Role | Use | Flash / experiment? |
|
||||
|------|-----|---------------------|
|
||||
| **GOLDEN** | Daily-driver **AXP.OS Pro 22.2 / Android 15** (main phone) | **NO** — never flash/wipe/modify; **`adb` sample only** |
|
||||
| **LAB** | Experiments / our ROM (as found: **iodé** / Lineage 7.8 A16) | **YES** — flash freely; factory rescue ready |
|
||||
|
||||
## Measured GOLDEN (2026-09-13)
|
||||
|
||||
| Field | Value |
|
||||
|-------|--------|
|
||||
| Serial | `11071JEC203839` |
|
||||
| Build | `22.2-2026.003-sunfish-pro` (`ro.lineage.releasetype=PRO`), Android **15**, patch `2026-03-03` |
|
||||
| Bootloader | **unlocked** (`flash.locked=0`, `verifiedbootstate=orange`) |
|
||||
| Magisk | **29.0** (`/system_ext/bin/magisk`) |
|
||||
| Work profile | Island user 10; Yuh + Swissquote in Island only |
|
||||
| Inventory | [`002-golden-inventory.md`](002-golden-inventory.md) |
|
||||
|
||||
## Measured LAB (2026-09-13)
|
||||
|
||||
| Field | Value |
|
||||
|-------|--------|
|
||||
| Serial | `11231JEC207477` |
|
||||
| As found | iodé / `7.8-20260902-sunfish`, Android **16**, patch `2026-08-01` |
|
||||
| Bootloader | **locked** |
|
||||
| Baseline note | [`002-lab-iodes-baseline.md`](002-lab-iodes-baseline.md) |
|
||||
| Factory rescue | [`002-lab-stock-rescue.md`](002-lab-stock-rescue.md) — SHA-256 **VERIFY_OK** |
|
||||
|
||||
## Implications
|
||||
|
||||
- NeoBackup / wipe of GOLDEN is **not** a project requirement.
|
||||
- `003+` flashing **only on LAB**.
|
||||
- **Do not flash GOLDEN** under any circumstance.
|
||||
@@ -0,0 +1,119 @@
|
||||
# Hardening backlog (non-normative)
|
||||
|
||||
Candidate hardening ideas for later evaluation. **Not requirements** until a row
|
||||
is promoted into an active feature `spec.md` (`012` / `013` or related).
|
||||
|
||||
Authority order for an active feature:
|
||||
|
||||
1. Constitution
|
||||
2. That feature's `spec.md`
|
||||
3. This backlog / `docs/axp-pro-parity.md` (hints only)
|
||||
|
||||
Status: `candidate` | `investigate` | `accepted→spec` | `rejected` | `los-provides`
|
||||
|
||||
## Privacy / identifiers
|
||||
|
||||
| Idea | Notes | Status |
|
||||
|------|-------|--------|
|
||||
| SUPL IMSI/MSISDN exposure | Reduce carrier ID leakage via SUPL | candidate |
|
||||
| Build.SERIAL restrictions | Identifier privacy | candidate |
|
||||
| Analytics / statistics removal | Drop unused telemetry | candidate |
|
||||
| Package query visibility | Tighten package visibility | candidate |
|
||||
| MAC / address privacy | Wi-Fi/BT randomization policy | candidate |
|
||||
| Private DNS defaults | Sensible defaults without breaking banks | candidate |
|
||||
| CA-store review | Trust anchors audit | candidate |
|
||||
|
||||
## Userspace
|
||||
|
||||
| Idea | Notes | Status |
|
||||
|------|-------|--------|
|
||||
| hardened_malloc | Graphene/AXP portability on sunfish | candidate |
|
||||
| Bionic hardening | Selective, attributable | candidate |
|
||||
| JNI protections | Safer JNI boundaries | candidate |
|
||||
| Stack canaries | Confirm / strengthen where applicable | candidate |
|
||||
| ptrace / Yama | Restrict debugging attach | candidate |
|
||||
| seccomp | Incremental filter improvements | candidate |
|
||||
| noexec / nosuid / nodev mounts | Where applicable without breaking HW | candidate |
|
||||
| Dynamic code / JIT restrictions | Evaluate app compatibility cost | candidate |
|
||||
| Exec spawning / ASLR-related | Attack-surface reduction | candidate |
|
||||
|
||||
## Kernel
|
||||
|
||||
| Idea | Notes | Status |
|
||||
|------|-------|--------|
|
||||
| Historical GrapheneOS sunfish kernel patches/config | Device-specific commits **and** config known to have run on sunfish — not CONFIG-only review | candidate |
|
||||
| Modern GrapheneOS kernel techniques | Evaluate equivalent/backport on sunfish 4.14; no blind cherry-picks | candidate |
|
||||
| AXP/DivestOS sunfish kernel patch audit | Identify AXP-owned vs inherited vs upstream; de-duplicate against LOS | candidate |
|
||||
| Applicable CVE backports | Document EOL firmware vs patchable kernel | candidate |
|
||||
| CFI | Feasibility on 4.14 | candidate |
|
||||
| ASLR config | Kernel/userspace related knobs | candidate |
|
||||
| IPv6 privacy | Address generation / exposure | candidate |
|
||||
| Debug / UART restrictions | Reduce attack surface | candidate |
|
||||
| Attack-surface reduction | Drop unused drivers/configs carefully | candidate |
|
||||
|
||||
## Kernel hardening source policy
|
||||
|
||||
The kernel base remains the LineageOS 23.2-compatible sunfish kernel.
|
||||
|
||||
```text
|
||||
┌─ historical GOS sunfish
|
||||
│
|
||||
LOS23/A16 sunfish 4.14 ←─┼─ AXP own + DivestOS
|
||||
OUR BASE │
|
||||
├─ modern GOS techniques
|
||||
│
|
||||
└─ original upstream fixes
|
||||
```
|
||||
|
||||
**Not:** GrapheneOS Android 13 (or any old GrapheneOS) kernel tree as our base.
|
||||
|
||||
Candidate hardening comes from four classes:
|
||||
|
||||
1. **Historical GrapheneOS sunfish** — device-specific patches/configuration known
|
||||
to have run on sunfish (real commits, not only `.config`).
|
||||
2. **AXP.OS / DivestOS sunfish** — audit the actual patch stack; distinguish
|
||||
AXP-owned changes from inherited changes.
|
||||
3. **Modern GrapheneOS** — use current kernel hardening as a source of
|
||||
techniques/security properties; adapt/backport only where feasible on
|
||||
non-GKI Linux 4.14; do not assume current Pixel kernel patches cherry-pick
|
||||
cleanly.
|
||||
4. **Original upstream** — where a GrapheneOS/AXP/Divest patch derives from AOSP,
|
||||
Android common, Linux stable, or another upstream source, prefer the
|
||||
appropriate original upstream fix when practical.
|
||||
|
||||
For each candidate record:
|
||||
|
||||
- security problem / property;
|
||||
- original source and commit;
|
||||
- source lineage / provenance;
|
||||
- sunfish-specific or generic;
|
||||
- already present in LOS 23.2?;
|
||||
- already present through another patch?;
|
||||
- kernel/hardware prerequisites;
|
||||
- applicability to Linux 4.14;
|
||||
- port/backport required;
|
||||
- compatibility/regression risk;
|
||||
- test result;
|
||||
- final decision.
|
||||
|
||||
## Much later / evaluate
|
||||
|
||||
| Idea | Notes | Status |
|
||||
|------|-------|--------|
|
||||
| Per-app network control | High UX/complexity | candidate |
|
||||
| Sensors permission model | Graphene-like | candidate |
|
||||
| Storage Scopes-like behaviour | Compatibility cost | candidate |
|
||||
| Contact Scopes-like behaviour | Compatibility cost | candidate |
|
||||
| Duress PIN/password | Later | candidate |
|
||||
| USB restrictions | Policy toggles | candidate |
|
||||
| Exploit-protection toggles | User-facing switches | candidate |
|
||||
| Modernize LOS API deprecations / Kotlin annotation targets | **Final-ROM hygiene (last steps)**, not a mid-feature gate. Measured on `005` bacon 2026-09-15 SUCCESS (~45k log lines): ~3k deprecated, ~4.5k KT-73255 annotation-target, ~8.7k “warning” hits total; **0** hard `error:`/`FAILED:` in successful run. Themes: Settings Slices `[removal]`; SystemUI KeyguardState/SceneContainer/CommunalScenes; DesktopMode desk APIs; `FingerprintManager`/`Executors`; SettingsLib `@StringRes` KT-73255. Fix **API-by-API** with attributable ports; never megapatch or `-Xlint:-deprecation` as “done”. Prefer waiting for LOS merges; only port what still warns at freeze. Own patches (`005` spoofing, vendor) must stay clean first. Evidence: `/srv/rom/artifacts/005-spoofing/20260915-bacon/bacon-log-triage.md`. | candidate |
|
||||
|
||||
## EOL firmware caveat (for `013`)
|
||||
|
||||
sunfish is EOL. The project can modify kernel/framework we build, but cannot
|
||||
fabricate new proprietary vendor/modem firmware. Document clearly:
|
||||
|
||||
- security patches we can backport in-tree;
|
||||
- old proprietary firmware/baseband/vendor images we **cannot** fix;
|
||||
- do not claim hardware protections unsupported by Pixel 4a.
|
||||
@@ -0,0 +1,365 @@
|
||||
# Reference sources — LineageOS, AXP.OS, GrapheneOS (sunfish only)
|
||||
|
||||
Project documentation consolidating where sources live, what role they play, what
|
||||
is already archived locally, and what to execute later on `rom-dev01`.
|
||||
|
||||
**Scope: Google Pixel 4a (`sunfish`) only.** Do not plan or archive unrelated
|
||||
devices (other Pixels, OnePlus, Fairphone, Sony, …).
|
||||
|
||||
```text
|
||||
LineageOS 23.2 / Android 16 → AUTHORITATIVE CURRENT BASE (build from this)
|
||||
AXP.OS 22.2 / Android 15 → GOLDEN / functional reference (live device + selective archive)
|
||||
GrapheneOS Android 13 sunfish → HISTORICAL hardening reference (selective archive)
|
||||
```
|
||||
|
||||
Do **not** execute server archive/download/build commands from this file until
|
||||
`rom-dev01` exists. Do **not** treat this as work on frozen feature `001`.
|
||||
|
||||
Detailed AXP hosting probes, Tor/download URLs, and Forgejo inventory commands:
|
||||
[`axp-sunfish-preservation.md`](axp-sunfish-preservation.md).
|
||||
|
||||
Device roles (GOLDEN vs LAB): [`device-roles.md`](device-roles.md).
|
||||
|
||||
---
|
||||
|
||||
## Classification legend
|
||||
|
||||
| Label | Meaning |
|
||||
|-------|---------|
|
||||
| **AUTHORITATIVE CURRENT SOURCE** | Use for builds / official current truth |
|
||||
| **HISTORICAL REFERENCE** | Study/port only; not the build base |
|
||||
| **LOCAL ARCHIVE** | Copy under `/srv/rom/references/…` or laptop path |
|
||||
| **UNAVAILABLE / PRIVATE** | Do not scrape or bypass access controls |
|
||||
| **TO BE EXECUTED LATER ON rom-dev01** | Commands/actions deferred until host is ready |
|
||||
|
||||
---
|
||||
|
||||
## Target layout on rom-dev01
|
||||
|
||||
```text
|
||||
/srv/rom/references/
|
||||
├── axp/
|
||||
│ ├── archive/ # see axp-sunfish-preservation.md
|
||||
│ ├── manifests/ # sunfish A15 selection / versioning notes
|
||||
│ └── README.md
|
||||
├── lineage/
|
||||
│ ├── manifests/ # repo manifest -r snapshots (reproducibility)
|
||||
│ └── README.md
|
||||
└── grapheneos/
|
||||
├── mirrors/ # selective bare clones only
|
||||
├── manifests/
|
||||
├── metadata/
|
||||
└── README.md
|
||||
```
|
||||
|
||||
Plus the normal **build checkout** (not an “archive”):
|
||||
|
||||
```text
|
||||
/srv/rom/src/lineage-23.2/ # full Lineage tree used to compile (feature 003+)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 1. LineageOS 23.2 / Android 16 — BASE
|
||||
|
||||
## Role
|
||||
|
||||
**AUTHORITATIVE CURRENT SOURCE** for the ROM. Compiling = syncing and building
|
||||
this tree for sunfish. No need for a redundant mass mirror of the entire
|
||||
LineageOS GitHub organization.
|
||||
|
||||
## Authoritative URLs
|
||||
|
||||
| Item | URL | Class |
|
||||
|------|-----|--------|
|
||||
| Android / repo umbrella | https://github.com/LineageOS/android | AUTHORITATIVE CURRENT |
|
||||
| Device sunfish | https://github.com/LineageOS/android_device_google_sunfish | AUTHORITATIVE CURRENT |
|
||||
| Kernel msm-4.14 | https://github.com/LineageOS/android_kernel_google_msm-4.14 | AUTHORITATIVE CURRENT |
|
||||
| Wiki device page | https://wiki.lineageos.org/devices/sunfish/ | AUTHORITATIVE CURRENT (verify against repos) |
|
||||
|
||||
**Note:** Indexed/cached wiki install pages may still mention older branches
|
||||
(e.g. 22.2). For branch and source tree truth, trust **current GitHub branches /
|
||||
official `repo init`**, not a stale wiki cache. As of project research,
|
||||
`android_device_google_sunfish` and `android_kernel_google_msm-4.14` expose
|
||||
**`lineage-23.2`**.
|
||||
|
||||
## Official source init
|
||||
|
||||
```bash
|
||||
repo init \
|
||||
-u https://github.com/LineageOS/android.git \
|
||||
-b lineage-23.2 \
|
||||
--git-lfs
|
||||
|
||||
repo sync
|
||||
```
|
||||
|
||||
(Exact path on host: e.g. `/srv/rom/src/lineage-23.2` — set during `003`.)
|
||||
|
||||
## What to preserve locally (not a full org archive)
|
||||
|
||||
**TO BE EXECUTED LATER ON rom-dev01** after syncs/builds:
|
||||
|
||||
```bash
|
||||
mkdir -p /srv/rom/references/lineage/manifests
|
||||
|
||||
cd /srv/rom/src/lineage-23.2 # or actual checkout path
|
||||
|
||||
# After first successful sync:
|
||||
repo manifest -r \
|
||||
-o /srv/rom/references/lineage/manifests/lineage-23.2-initial.xml
|
||||
|
||||
# After first known-good vanilla sunfish boot/build:
|
||||
repo manifest -r \
|
||||
-o /srv/rom/references/lineage/manifests/lineage-23.2-sunfish-vanilla-known-good.xml
|
||||
```
|
||||
|
||||
Also keep short README under `/srv/rom/references/lineage/README.md` with:
|
||||
|
||||
- `repo init` command used
|
||||
- date / host
|
||||
- pointer to known-good images under `/srv/rom/artifacts/` (hashes)
|
||||
|
||||
## Explicitly out of scope for Lineage “archive”
|
||||
|
||||
- `git clone --mirror` of hundreds of LineageOS repos “just in case”
|
||||
- Mirroring unrelated device trees
|
||||
|
||||
The build checkout **is** the working copy; revision-locked manifests are the
|
||||
reproducibility archive.
|
||||
|
||||
---
|
||||
|
||||
# 2. AXP.OS 22.2 / Android 15 — GOLDEN / functional reference
|
||||
|
||||
## Role
|
||||
|
||||
**HISTORICAL + FUNCTIONAL REFERENCE** (and live GOLDEN device). Not the build
|
||||
base. Infrastructure risk is higher (self-hosted pieces may vanish) → selective
|
||||
archive matters more than for Lineage.
|
||||
|
||||
Full operational cookbook: [`axp-sunfish-preservation.md`](axp-sunfish-preservation.md).
|
||||
|
||||
## Source classes
|
||||
|
||||
| Source | Class | Notes |
|
||||
|--------|-------|--------|
|
||||
| GOLDEN phone (AXP 22.2 / A15) | AUTHORITATIVE CURRENT *for behaviour* | Live `adb`; do not flash |
|
||||
| https://axpos.org (docs/news/devices) | AUTHORITATIVE CURRENT *docs* (while up) | Hosted via Codeberg |
|
||||
| https://git.disroot.org/AXP.OS | AUTHORITATIVE CURRENT *public git* | Main public mirror (~225 repos; **do not clone all**) |
|
||||
| https://codeberg.org/AXP-OS | HISTORICAL / PARTIAL | Website git + fewer repos after Jan 2026 removals |
|
||||
| https://github.com/AXP-OS | AUTHORITATIVE for some **APK/releases** | Lower priority mirror |
|
||||
| https://code.binbash.rocks/AXP.OS | UNAVAILABLE / PRIVATE anonymously | Alive; no anonymous repo list; do not bypass |
|
||||
| https://download.axpos.org/…/sunfish/ | AUTHORITATIVE downloads (when reachable) | Probe exact paths |
|
||||
| Tor onion `:8008` | FALLBACK downloads | See preservation doc |
|
||||
| `leech.binbash.rocks` | UNAVAILABLE (2026-08-09 probes) | Legacy |
|
||||
|
||||
## Sunfish-only archive criteria
|
||||
|
||||
Preserve/reference **only**:
|
||||
|
||||
- documentation/web useful to the project
|
||||
- `android_device_google_sunfish`, `android_kernel_google_msm-4.14`
|
||||
- manifests / `axp_versioning` needed to identify exact AXP sunfish revisions
|
||||
- common repos **only when** they contain AXP changes applicable to sunfish
|
||||
(e.g. frameworks/base, Settings, build/config, microG/spoofing, Phonesky,
|
||||
callrec, FLAG_SECURE, hardening) — **selected via sunfish A15 manifests**,
|
||||
not by cloning the whole org
|
||||
- sunfish Pro/Slim builds, recovery, factory, `.prop`, checksums, public keys
|
||||
where recoverable
|
||||
|
||||
**Discarded:** full Disroot “225 repos / ~48 GiB Git” org mirror as a project
|
||||
goal.
|
||||
|
||||
## LOCAL ARCHIVE (laptop today)
|
||||
|
||||
```text
|
||||
~/Archives/AXP.OS/
|
||||
website-rendered/
|
||||
codeberg/ # ~14 repos / ~38 GiB; LFS gaps in legacy_prebuilt_apps
|
||||
disroot-repositories.jsonl
|
||||
mirror-forgejo-org.sh
|
||||
…
|
||||
```
|
||||
|
||||
## TO BE EXECUTED LATER ON rom-dev01
|
||||
|
||||
1. rsync laptop archive → `/srv/rom/references/axp/archive/`
|
||||
2. `df` preflight (must not steal LOS/`out`/ccache space)
|
||||
3. Refresh website / selected Disroot mirrors via **manifest-driven** selection
|
||||
4. Probe/download sunfish Pro/Slim artifacts if hosts allow
|
||||
5. Never attempt private binbash access
|
||||
|
||||
See [`axp-sunfish-preservation.md`](axp-sunfish-preservation.md) for commands.
|
||||
|
||||
---
|
||||
|
||||
# 3. GrapheneOS — Android 13 sunfish (historical hardening)
|
||||
|
||||
## Role
|
||||
|
||||
**HISTORICAL REFERENCE** for hardening techniques/patches that once ran on
|
||||
sunfish. **Not** the ROM base. Official project: sunfish **unsupported**; old
|
||||
trees moved toward **GrapheneOS-Archive**.
|
||||
|
||||
Confirms project rule: GrapheneOS sunfish = **A13 history**, never A16 base.
|
||||
|
||||
## Authoritative / archive URLs
|
||||
|
||||
| Item | URL | Class |
|
||||
|------|-----|--------|
|
||||
| Current GrapheneOS orgs | https://github.com/GrapheneOS | AUTHORITATIVE CURRENT (active devices) |
|
||||
| Platform manifest (current) | https://github.com/GrapheneOS/platform_manifest | AUTHORITATIVE CURRENT |
|
||||
| Official historical archive org | https://github.com/GrapheneOS-Archive | HISTORICAL REFERENCE |
|
||||
| sunfish device (archived) | https://github.com/GrapheneOS-Archive/device_google_sunfish | HISTORICAL — archive/read-only (e.g. since 2025-12-04); branch **13** |
|
||||
| Releases / changelog | https://grapheneos.org/releases | AUTHORITATIVE for release history (A13 era mentions Pixel 4a) |
|
||||
| FAQ | https://grapheneos.org/faq | AUTHORITATIVE docs |
|
||||
| Example reorganized tree | `GrapheneOS-Archive/platform_frameworks_base-old` (read-only) | HISTORICAL — illustrates repo moves |
|
||||
|
||||
**Do not** mirror all ~244 repos in GrapheneOS-Archive.
|
||||
|
||||
## Selection rule (same spirit as AXP)
|
||||
|
||||
1. From last sunfish **Android 13** GrapheneOS manifests/tags, list repos/commits
|
||||
that carried GrapheneOS deltas relevant to sunfish.
|
||||
2. Mirror **only** those (plus `device_google_sunfish` + useful manifests).
|
||||
3. Likely candidates after proof: frameworks, system/core, SELinux, malloc,
|
||||
kernel/configs, etc. — **only if** tied to sunfish A13 lineage.
|
||||
4. Record provenance; port carefully to LOS 23.2 / 4.14 (see constitution /
|
||||
`docs/hardening-backlog.md`).
|
||||
|
||||
## TO BE EXECUTED LATER ON rom-dev01 (minimum seed)
|
||||
|
||||
```bash
|
||||
mkdir -p /srv/rom/references/grapheneos/{mirrors,manifests,metadata}
|
||||
|
||||
git clone --mirror \
|
||||
https://github.com/GrapheneOS-Archive/device_google_sunfish.git \
|
||||
/srv/rom/references/grapheneos/mirrors/device_google_sunfish.git
|
||||
|
||||
git clone --mirror \
|
||||
https://github.com/GrapheneOS/platform_manifest.git \
|
||||
/srv/rom/references/grapheneos/mirrors/platform_manifest.git
|
||||
|
||||
git --git-dir=/srv/rom/references/grapheneos/mirrors/device_google_sunfish.git fsck --full
|
||||
git --git-dir=/srv/rom/references/grapheneos/mirrors/device_google_sunfish.git show-ref
|
||||
```
|
||||
|
||||
Then expand selectively from A13 sunfish manifests/tags — not the whole Archive
|
||||
org.
|
||||
|
||||
## LOCAL ARCHIVE
|
||||
|
||||
No complete GrapheneOS sunfish archive is assumed on the laptop yet (unlike
|
||||
AXP). Seed mirrors are **TO BE EXECUTED LATER ON rom-dev01**.
|
||||
|
||||
---
|
||||
|
||||
# 4. Conceptual comparison
|
||||
|
||||
| | LineageOS | AXP.OS | GrapheneOS (sunfish) |
|
||||
|--|-----------|--------|----------------------|
|
||||
| Android | 16 (23.2) | 15 (22.2) | 13 (last) |
|
||||
| Role | **BASE** | **GOLDEN / functional** | **Hardening history** |
|
||||
| Full tree checkout | Yes (to build) | No (selective) | No (selective) |
|
||||
| Mass org mirror | No | No | No |
|
||||
| Key local artifact | `repo manifest -r` XML | web + sunfish repos + images | device_sunfish + selected A13 repos |
|
||||
| Urgency | Low (GitHub active) | Higher (self-host risk) | Medium (already moving to Archive) |
|
||||
|
||||
---
|
||||
|
||||
# 5. Shared porting discipline
|
||||
|
||||
For **any** AXP or GrapheneOS candidate change:
|
||||
|
||||
1. Identify source repo + tag/branch/build (sunfish-relevant)
|
||||
2. Identify corresponding LOS 23.2 / AOSP base
|
||||
3. Inspect full diff
|
||||
4. Classify: direct / port / obsolete / superseded / A16- or 4.14-incompatible
|
||||
5. Deduplicate vs LOS / the other reference
|
||||
6. One logical change; build; test on **LAB** only
|
||||
|
||||
---
|
||||
|
||||
# 6. Execution status checklist
|
||||
|
||||
| Item | Status |
|
||||
|------|--------|
|
||||
| Document Lineage URLs + manifest `-r` strategy | Done (this file) |
|
||||
| Document AXP sunfish-scoped preservation | Done (`axp-sunfish-preservation.md` + this file) |
|
||||
| Document GrapheneOS Archive sunfish strategy | Done (this file) |
|
||||
| Laptop AXP archive under `~/Archives/AXP.OS/` | Exists (operator); rsync later |
|
||||
| rom-dev01 AXP/Lineage/GOS archives | **TO BE EXECUTED LATER** |
|
||||
| Lineage full sync / first `manifest -r` | **TO BE EXECUTED LATER** (`003`) |
|
||||
| Feature `001` implement | Not started (frozen docs) |
|
||||
| Features `002`/`003` | Not started |
|
||||
|
||||
---
|
||||
|
||||
# 7. Contradictions / pitfalls noted
|
||||
|
||||
1. **Wiki vs GitHub for Lineage:** install wiki caches may show 22.2; repos show
|
||||
`lineage-23.2` — trust repos/`repo init`.
|
||||
2. **AXP “~48 GiB Disroot” ≠ required archive size** — that is whole-org Git
|
||||
metadata; project policy is sunfish-selected only.
|
||||
3. **Codeberg AXP archive ≠ complete** — LFS 404s (e.g. `legacy_prebuilt_apps`);
|
||||
keep anyway; do not claim 100% LFS.
|
||||
4. **download.axpos.org `/` timeout ≠ paths dead** — probe `/axp/sunfish/` etc.
|
||||
5. **OTA `/` → 403** does not mean updater API is down.
|
||||
6. **GrapheneOS-Archive growth** — sunfish material is being archived; prefer
|
||||
Archive URLs + manifests over assuming old live GrapheneOS device support.
|
||||
7. **AXP Android version:** GOLDEN is **22.2 / A15**; last GrapheneOS sunfish is
|
||||
**A13** — do not conflate.
|
||||
|
||||
---
|
||||
|
||||
# 8. Community inspiration (non-base) — LOS + microG + KSU-Next + SusFS
|
||||
|
||||
**Not** our ROM base. Useful field report for sunfish banking / root / SusFS.
|
||||
|
||||
| Item | Detail |
|
||||
|------|--------|
|
||||
| Thread | [XDA: UNOFFICIAL sunfish LOS 22.2 + MicroG + KSU-Next + SusFS](https://xdaforums.com/t/rom-unofficial-sunfish-pixel-4a-lineageos-22-2-microg-ksu-next-susfs.4772261/) (torukk) |
|
||||
| Ship | LOS **22.2** / A15 + upstream microG + kernel KSU-Next + SusFS |
|
||||
| Kernel tree (author) | https://github.com/abu-adm/android_kernel_google_msm-4.14 (branch noted compatible with LOS23 kernel work) |
|
||||
| Claims | Revolut / hard banks workable with **spoofed** KSU-Next manager + SusFS + **TrickyStore** + microG “unblock hardware attestation”; integrity landscape changes fast |
|
||||
| LOS 23.2 note (forum) | Boot image with SusFS/ReSukiSU flashed onto official LOS 23.2: SusFS works, but ReSukiSU config unstable, heat, sudden reboots vs Magisk |
|
||||
| Our use | Inspiration for `006`/`007` (profiles, SusFS, attestation modules on **LAB**). Still build **our** LOS 23.2 vanilla first (`003`), then microG/Phonesky, then KSU-Next. Do **not** adopt as drop-in base; layer AXP/Graphene call-rec / FLAG_SECURE / hardening later as planned |
|
||||
|
||||
If iodé/vanilla keep failing Yuh KeyMint/RKP, this thread’s stack (SusFS + TrickyStore + microG HA toggles) is the first **LAB** experiment family to evaluate — after stock factory diagnosis when convenient.
|
||||
|
||||
---
|
||||
|
||||
# 9. Community inspiration (non-base) — rooted GrapheneOS OTAs
|
||||
|
||||
**Not** our ROM base. **Not** for sunfish (EOL; project targets modern supported Pixels).
|
||||
|
||||
| Item | Detail |
|
||||
|------|--------|
|
||||
| Repo | https://github.com/schnatterer/rooted-graphene |
|
||||
| Idea | Patch **Magisk** into official GrapheneOS OTAs; keep **AVB + locked bootloader** + root; own OTA channel via [Custota](https://github.com/chenxiaolong/Custota) / GitHub Pages; switch Magisk ↔ rootless by OTA |
|
||||
| Tooling of interest | [avbroot](https://github.com/chenxiaolong/avbroot), Custota, signed OTA pipeline |
|
||||
| Limits (upstream notes) | Stock Magisk Zygisk broken in this setup → banking detection; optional third-party Magisk fork; **KernelSU hard to integrate** with this Magisk-in-OTA approach |
|
||||
| Our use | Inspiration for later **`011`** (project signing / AVB / OTA) and for “locked + root” trade-offs — **not** a Magisk production path (constitution: KernelSU-Next). Do not treat as GrapheneOS-on-sunfish revival |
|
||||
|
||||
Contrast with §8 (torukk): that one is **sunfish + KSU-Next + SusFS + LOS**; this one is **modern Graphene + Magisk + locked AVB OTA**. Different lessons for different stages.
|
||||
|
||||
---
|
||||
|
||||
# 10. Attestation / banking compatibility references
|
||||
|
||||
Primary reading when designing `006`/`007` attestation strategy (not sunfish-specific
|
||||
fixes by themselves):
|
||||
|
||||
| Source | URL | Why keep |
|
||||
|--------|-----|----------|
|
||||
| GrapheneOS attestation compatibility guide | https://grapheneos.org/articles/attestation-compatibility-guide | Explains **hardware attestation API** vs Play Integrity; `SelfSigned` + whitelist of official GOS verified-boot keys (`attestation.json`); why modern supported Pixels can work with banks that whitelist GOS; sunfish **not** on that key list (EOL) |
|
||||
| PrivSec banking apps compat report (issue) | https://github.com/PrivSec-dev/banking-apps-compat-report/issues/509 | Crowdsourced banking/attestation outcomes across ROMs (incl. Graphene); use for comparative evidence, not as a recipe dump |
|
||||
|
||||
**Project takeaway:** Yuh/Swissquote working on **supported** GrapheneOS tracks
|
||||
whitelist + healthy TEE/AVB on current Pixels. Our sunfish path still needs
|
||||
LOS+microG/Phonesky + measured KeyMint/RKP behaviour; GOS docs inform *what*
|
||||
apps check, not a drop-in port.
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Session handoff — 2026-09-16 (LAB / 007)
|
||||
|
||||
**For the next chat:** read this file first, then `docs/007-kernelsu-runbook.md`.
|
||||
**Prior chat (full context):** Cursor transcript id
|
||||
`a601104c-c593-45d3-b737-545a7838957d`
|
||||
(path: `~/.cursor/projects/home-aventura-Workspaces-sunfish-a16-rom/agent-transcripts/a601104c-c593-45d3-b737-545a7838957d/`).
|
||||
|
||||
**Rules:** working tree only (no commit / push / MR). LAB only
|
||||
`11231JEC207477` — never GOLDEN.
|
||||
|
||||
---
|
||||
|
||||
## Project spine (do not forget)
|
||||
|
||||
We did **not** start from abu or from LOS 22 as the product base.
|
||||
|
||||
1. **`003`** — LOS **23.2** vanilla on LAB
|
||||
2. **`004`/`005`** — microG + patched Play (Phonesky) + restricted spoofing → bacon zip
|
||||
3. **`007`** — our ReSukiSU root on **our** `msm-4.14`, then modules / SusFS / banks
|
||||
|
||||
**ROM zip (ours):**
|
||||
`.local-artifacts/005-spoofing/20260915-bacon/lineage-23.2-20260915-UNOFFICIAL-sunfish.zip`
|
||||
|
||||
**abu / torukk / Downloads `boot-sunfish-resukisu*.img`:** reference only (SusFS / module ideas).
|
||||
**Never** treat Downloads abu boots as “ours”.
|
||||
|
||||
---
|
||||
|
||||
## Our boot images (host + laptop)
|
||||
|
||||
| Role | File | Where |
|
||||
|------|------|--------|
|
||||
| **Penúltimo (known-good ReSukiSU, no SusFS)** | `boot-resukisu-our-20260915T183729Z.img` | Host `/srv/rom/artifacts/007-kernelsu/` (+ symlink `boot-resukisu-our-latest.img`). Copy to laptop before flash if missing locally. |
|
||||
| **Último (ReSukiSU + SusFS API bridge)** | `boot-resukisu-susfs-20260916T004038Z.img` | Host + laptop `.local-artifacts/007-kernelsu/boot-resukisu-susfs-latest.img` — sha256 `455a77a6…` |
|
||||
|
||||
Earlier same-day builds: `…T172342Z` / `…T172400Z` (superseded by `T183729Z`).
|
||||
|
||||
---
|
||||
|
||||
## What happened today (facts)
|
||||
|
||||
### Kernel / SusFS (host)
|
||||
|
||||
- Integrated **ReSukiSU** (not KSU-Next) into our tree; fixed shallow-clone bogus `KSU_VERSION=30701`.
|
||||
- Built SusFS after bridging non-GKI 4.14 SusFS (`INODE_STATE_*`, etc.) with ReSukiSU GKI-style ioctl `CMD_*` / wrappers — compile+link OK (~18m).
|
||||
- Pin notes: `.local-artifacts/007-kernelsu/susfs-pin/` (host tree under `kernel/google/msm-4.14`).
|
||||
- **Process note:** SusFS build ran before US2 hide verification (constitution prefers profiles first). Treat SusFS boot as **trial**, not claimed.
|
||||
|
||||
### LAB flash chaos (evening)
|
||||
|
||||
- Torukk **22.2 MicroG** was on device temporarily (test/capture); **not** our product path.
|
||||
- Attempted restore to **our 23.2 bacon** + SusFS boot.
|
||||
- `fastboot -w` erased userdata **without** formatting (`File system type raw not supported`) → “Can't load Android system / data may be corrupt”.
|
||||
- Wrong boot paths (`~/Downloads/boot-sunfish-resukisu.img`) = **abu/torukk**, not ours — caused confusion.
|
||||
- Sideload of our 23 zip from old recovery: signature / **downgrade** prompts (recovery compares timestamps/patch, not “22<23” marketing). Accept install-anyway / downgrade when intentional.
|
||||
- End of session: operator reported **sideload of our 23 finished and device booted**. Confirm with:
|
||||
`adb shell getprop ro.lineage.version` → expect `23.2-20260915-…`.
|
||||
- Next flash after that sideload: **our penúltimo** boot (`boot-resukisu-our-20260915T183729Z`), then later trial SusFS if needed.
|
||||
|
||||
### What is *not* done
|
||||
|
||||
- SusFS boot **not** proven stable on our 23.2 (earlier bootloop / corrupt-data episode with SusFS + messy slots).
|
||||
- US2 hide verification, modules (TEESimulator-RS / Zygisk / PIF), Island banks — still open.
|
||||
- microG **Location UI** gap on our 23.2 (see urgent next).
|
||||
|
||||
---
|
||||
|
||||
## Urgent next (new chat)
|
||||
|
||||
1. **Confirm LAB identity:** `ro.lineage.version` = our 23.2 bacon; slot; serial `11231JEC207477`.
|
||||
2. **Flash our penúltimo boot** (if not already):
|
||||
`fastboot flash boot …/boot-resukisu-our-20260915T183729Z.img` then reboot.
|
||||
3. **URGENT — Location options (`005`/`004` follow-up):**
|
||||
On `23.2-20260915` + microG 0.3.16, operator saw **no usable microG Location UI** (no remember-from-GPS / request-from-online / hotspot-style controls vs richer UI on community 22.2).
|
||||
Re-check on restored stack: screenshots + `dumpsys`; decide if packaging/overlay/settings gap.
|
||||
Docs: `docs/004-lab-selfcheck.md` § “LAB observation (follow-up — 2026-09-16)”.
|
||||
4. Reinstall manager (matching `KSU_VERSION`) + modules; resume `007` US2 → SusFS trial → attestation / Yuh+Swissquote.
|
||||
5. Do **not** re-introduce abu ROM/kernels into the flash path; keep abu trees as SusFS/reference only.
|
||||
|
||||
---
|
||||
|
||||
## Spec / doc touchpoints updated this handoff
|
||||
|
||||
- `docs/007-kernelsu-runbook.md` — our boots, SusFS trial status, abu archived as reference
|
||||
- `specs/007-kernelsu-sunfish/tasks.md` — T018 build done; T019 pending proof
|
||||
- `specs/README.md` — `007` active
|
||||
- `docs/004-lab-selfcheck.md` — Location marked urgent for return to our stack
|
||||
@@ -0,0 +1,228 @@
|
||||
sunfish-a16-rom — Spec Kit beginner guide + pre-plan briefing for ChatGPT
|
||||
Generated: 2026-08-09
|
||||
Project path: /home/aventura/Workspaces/sunfish-a16-rom
|
||||
Constitution: 0.1.5
|
||||
Active feature (.specify/feature.json): specs/001-development-environment
|
||||
|
||||
================================================================================
|
||||
1) WHAT HAPPENED WHEN WE "CREATED" THE PROJECT
|
||||
================================================================================
|
||||
|
||||
In this project we did NOT use the SSYSTEMS command /speckit.project-create.
|
||||
|
||||
We used upstream Spec Kit:
|
||||
|
||||
specify init --here --integration cursor-agent --script sh
|
||||
|
||||
That command:
|
||||
|
||||
- created .specify/ (scripts, templates, workflows, memory/constitution template)
|
||||
- installed Cursor skills under .cursor/skills/speckit-*
|
||||
- those skills are what appear in Cursor as /speckit-plan, /speckit-tasks, etc.
|
||||
|
||||
So yes: initializing a Spec Kit project is what "brings" the other /speckit-*
|
||||
commands into Cursor for THAT workspace.
|
||||
|
||||
Important:
|
||||
- Open the sunfish-a16-rom folder in Cursor (not buildout-saar) so those
|
||||
skills are available.
|
||||
- /speckit-taskstoissues is GitHub-only — do NOT use it (we use Gitea later).
|
||||
- We already wrote constitution + specs/001-003 manually. We do NOT need to
|
||||
re-run /speckit-specify to create 001.
|
||||
|
||||
================================================================================
|
||||
2) TYPICAL UPSTREAM ORDER (generic Spec Kit)
|
||||
================================================================================
|
||||
|
||||
For a brand-new feature from scratch, the usual order is:
|
||||
|
||||
1. /speckit-constitution → project principles (once / rare)
|
||||
2. /speckit-specify → create specs/NNN-name/spec.md from a prompt
|
||||
3. /speckit-clarify → optional: ask structured questions
|
||||
4. /speckit-plan → create plan.md (+ design artifacts)
|
||||
5. /speckit-tasks → create tasks.md checklist
|
||||
6. /speckit-checklist → optional quality checklist
|
||||
7. /speckit-analyze → optional consistency report
|
||||
8. /speckit-implement → execute tasks
|
||||
9. /speckit-converge → later: find remaining work
|
||||
|
||||
You do NOT need every optional step every time.
|
||||
|
||||
================================================================================
|
||||
3) ORDER FOR THIS PROJECT (sunfish-a16-rom) — RIGHT NOW
|
||||
================================================================================
|
||||
|
||||
Already done:
|
||||
[x] specify init (skills installed)
|
||||
[x] custom constitution written (do NOT overwrite with generic /speckit-constitution
|
||||
unless you intentionally re-seed — our constitution is already project-specific)
|
||||
[x] specs 001, 002, 003 written
|
||||
[x] feature.json → 001-development-environment
|
||||
[x] design frozen at constitution 0.1.5
|
||||
|
||||
Recommended next commands (only for feature 001):
|
||||
|
||||
A. (optional) /speckit-clarify
|
||||
Use if you want the agent to ask remaining ambiguities about 001 only.
|
||||
Many ambiguities were already closed in chat — can skip.
|
||||
|
||||
B. /speckit-plan
|
||||
Generates specs/001-development-environment/plan.md from the existing
|
||||
spec.md + constitution. NO VM required.
|
||||
|
||||
C. /speckit-tasks
|
||||
Generates tasks.md from the plan. NO VM required.
|
||||
|
||||
D. (optional) /speckit-analyze or /speckit-checklist
|
||||
|
||||
E. /speckit-implement
|
||||
THIS is when rom-dev01 should exist (SSH working). Implementation of 001
|
||||
assumes the VM is already provisioned outside this project.
|
||||
|
||||
Then later, switch feature and repeat plan→tasks→implement for:
|
||||
002 → 003 → …
|
||||
|
||||
How to switch feature later (when 001 is done):
|
||||
- edit .specify/feature.json:
|
||||
{ "feature_directory": "specs/002-axp-reference-capture" }
|
||||
- or use /speckit-specify only when creating a NEW feature number (004+)
|
||||
- do NOT re-specify 001/002/003
|
||||
|
||||
================================================================================
|
||||
4) WHAT EACH COMMAND DOES (short)
|
||||
================================================================================
|
||||
|
||||
/speckit-constitution Seed/update constitution from template — SKIP for now
|
||||
(ours is already custom 0.1.5)
|
||||
|
||||
/speckit-specify Create a NEW feature spec from a prompt
|
||||
(we already have 001–003)
|
||||
|
||||
/speckit-clarify Ask clarifying questions before plan
|
||||
|
||||
/speckit-plan Write implementation plan (plan.md)
|
||||
|
||||
/speckit-tasks Break plan into tasks.md
|
||||
|
||||
/speckit-checklist Generate validation checklists
|
||||
|
||||
/speckit-analyze Cross-check spec/plan/tasks consistency
|
||||
|
||||
/speckit-implement Execute tasks against the real system/repo
|
||||
|
||||
/speckit-converge Find leftover work after partial implementation
|
||||
|
||||
/speckit-taskstoissues DO NOT USE (GitHub-specific)
|
||||
|
||||
================================================================================
|
||||
5) PRE-PLAN BRIEFING FOR CHATGPT — FEATURE 001
|
||||
================================================================================
|
||||
|
||||
Please review this briefing and return:
|
||||
- anything missing/dangerous in the 001 plan approach
|
||||
- suggested plan.md section outline
|
||||
- P1 vs P2 sequencing recommendations
|
||||
- explicit "do not do" list for Cursor when running /speckit-plan and later
|
||||
/speckit-implement
|
||||
|
||||
--- PROJECT FACTS ---
|
||||
|
||||
Name: sunfish-a16-rom
|
||||
Goal: LineageOS 23.2 / Android 16 custom ROM for Pixel 4a (sunfish), aiming at
|
||||
AXP.OS Pro functionality with deliberate substitutions (Magisk→KernelSU,
|
||||
backup→NeoBackup external, etc.)
|
||||
|
||||
Meta repo (this Spec Kit tree): eventually Gitea sunfish-a16-rom
|
||||
Companion repos later: sunfish-rom-manifest, sunfish-rom-build, sunfish-rom-patches
|
||||
|
||||
Laptop role: Cursor Remote SSH, adb/fastboot, rsync, thin client
|
||||
Build host: rom-dev01 (Ubuntu 24.04) — created OUTSIDE this project via
|
||||
SSYSTEMS Salt/PVE by the human. Spec Kit must NOT create the VM.
|
||||
|
||||
001 starts ONLY when rom-dev01 already exists with:
|
||||
- Ubuntu 24.04
|
||||
- public IPv4, SSH works
|
||||
- saltenv=base already applied by SSYSTEMS
|
||||
|
||||
Sizing to plan around (do not assume more):
|
||||
6 vCPU / 52 GB RAM / 2 TB disk / 32 GB swap
|
||||
→ conservative build parallelism later (003), not in 001 yet
|
||||
|
||||
001 IN SCOPE (ROM host environment):
|
||||
- android-build user/workspace
|
||||
- Android/Lineage build packages, git, git-lfs, repo, ccache
|
||||
- /srv/rom layout (sources, artifacts, logs, tooling, reference)
|
||||
- private Gitea (bind/tunnel; not world-exposed)
|
||||
- four repos: sunfish-a16-rom, sunfish-rom-manifest, sunfish-rom-build,
|
||||
sunfish-rom-patches
|
||||
- off-VM backup/mirror of those Git repos (laptop/Borg/etc.)
|
||||
- Ansible + Semaphore (P2; smoke playbook OK first)
|
||||
- Spec Kit meta repo available on host
|
||||
- Cursor Remote SSH + rsync artifacts workflow docs
|
||||
- guest isolation posture docs/config (public NIC only; UIs not world-open)
|
||||
[human already accepted keeping this in 001]
|
||||
|
||||
001 OUT OF SCOPE:
|
||||
- Proxmox / pm-test01 / choosing public IP / company Salt VM creation
|
||||
- Lineage sync/build (003)
|
||||
- AXP capture / NeoBackup phone backup (002)
|
||||
- microG/Phonesky/KernelSU/hardening
|
||||
|
||||
P1 vs P2 in 001:
|
||||
P1: SSH + android-build + toolchain + /srv/rom + docs for thin-client workflow
|
||||
(enough to unlock 003 later)
|
||||
P2: Gitea + four repos + off-VM mirror + Ansible/Semaphore + isolation polish
|
||||
|
||||
Priority for ChatGPT review of the future plan.md:
|
||||
- Must not invent PVE/qm/Salt SSYSTEMS steps
|
||||
- Must not require Ansible on the laptop
|
||||
- Must not put .repo/out/ccache on the laptop
|
||||
- Must keep Gitea/Semaphore off public Internet by default
|
||||
- Must include off-VM git backup
|
||||
- Must use account android-build (not hard-code laptop username)
|
||||
- First LOS build remains manual later (003); 001 only prepares the host
|
||||
|
||||
Authoritative files for Cursor when planning:
|
||||
- .specify/memory/constitution.md (0.1.5)
|
||||
- specs/001-development-environment/spec.md
|
||||
- AGENTS.md
|
||||
- docs/axp-pro-parity.md and docs/hardening-backlog.md are NON-NORMATIVE
|
||||
|
||||
Suggested plan.md outline for /speckit-plan to produce:
|
||||
1. Summary / goals
|
||||
2. Assumptions (VM pre-exists)
|
||||
3. Non-goals
|
||||
4. Host layout (/srv/rom, android-build home)
|
||||
5. Package/toolchain set (LOS build deps)
|
||||
6. ccache defaults for 6 vCPU / 52 GB
|
||||
7. Gitea install + access model (SSH tunnel)
|
||||
8. Initial empty repos + push meta Spec Kit tree
|
||||
9. Off-VM backup/mirror procedure
|
||||
10. Ansible + Semaphore minimal bootstrap
|
||||
11. Isolation/firewall/DNS guest posture (docs + config)
|
||||
12. Laptop workflow (Remote SSH, rsync, adb/fastboot)
|
||||
13. Acceptance mapping to FR/SC in spec.md
|
||||
14. Handoff criteria to start 002/003
|
||||
|
||||
Please critique this outline and list concrete plan bullets Cursor should include
|
||||
or avoid.
|
||||
|
||||
================================================================================
|
||||
6) AFTER CHATGPT ANSWERS
|
||||
================================================================================
|
||||
|
||||
Human brings ChatGPT feedback into Cursor, then runs:
|
||||
|
||||
/speckit-plan
|
||||
|
||||
(optionally paste ChatGPT constraints as $ARGUMENTS)
|
||||
|
||||
Then:
|
||||
|
||||
/speckit-tasks
|
||||
|
||||
Implement only when rom-dev01 SSH works.
|
||||
|
||||
================================================================================
|
||||
END
|
||||
================================================================================
|
||||
@@ -0,0 +1,31 @@
|
||||
# sunfish-a16-rom — laptop OpenSSH (independent of SSYSTEMS Salt/GitLab)
|
||||
# Included from: ~/.ssh/config.d/a15-rom-dev01
|
||||
#
|
||||
# Web UIs (no tunnel): https://a16.ssystems.de/ and /semaphore/
|
||||
# HTTP Basic: /srv/rom/secrets/web-htpasswd.txt on host
|
||||
|
||||
# Default: root (ssh a16 / ssh a16.ssystems.de)
|
||||
Host a16 a16.ssystems.de a16-root rom-dev01-root a15-root
|
||||
HostName 49.13.104.83
|
||||
User root
|
||||
Port 37037
|
||||
IdentityFile ~/.ssh/id_ed25519_rom_dev01
|
||||
IdentitiesOnly yes
|
||||
ForwardAgent no
|
||||
|
||||
# Build user when needed: ssh a16-build
|
||||
Host a16-build rom-dev01 a15
|
||||
HostName 49.13.104.83
|
||||
User android-build
|
||||
Port 37037
|
||||
IdentityFile ~/.ssh/id_ed25519_rom_dev01
|
||||
IdentitiesOnly yes
|
||||
ForwardAgent no
|
||||
|
||||
Host a15.ssystems.de aventura.serv.ssystems.de
|
||||
HostName 49.13.104.83
|
||||
User root
|
||||
Port 37037
|
||||
IdentityFile ~/.ssh/id_ed25519_rom_dev01
|
||||
IdentitiesOnly yes
|
||||
ForwardAgent no
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user