Ship Magisk like GOLDEN; KernelSU optional recycle only; parallel to sunfish-a16-rom standby.
13 KiB
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-environmentvia.specify/feature.jsonand that constitution is0.1.7in.specify/memory/constitution.md - T002 [P] Create host-facing doc stub
docs/001-host-runbook.mdin meta repo (preflight results, paths, Gitea tunnel notes — fill during implement) - T003 [P] Create FR/SC evidence checklist stub
docs/001-verification-matrix.mdmapping each FR-/SC- fromspecs/001-development-environment/spec.mdto 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-dev01as admin, capture preflight baseline into/srv/rom/logs/preflight/(create/srv/rom/logswith 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 indocs/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 SSH key login from laptop; /srv/rom owned correctly; meta tree at fixed path.
Independent test: ssh android-build@rom-dev01 from laptop; /srv/rom/artifacts writable; /home/android-build/sunfish-a16-rom contains Spec Kit tree (after T013).
Implementation
- T007 [US1] Create unprivileged user
android-buildwith home/home/android-build(admin); document uid/gid indocs/001-host-runbook.md - T008 [US1] Configure SSH public-key access for
android-buildusing the developer's existing public key only (do not copy private keys; do not modify global sshd/saltenv=basepolicy unless required). Verify from the laptop thatssh android-build@rom-dev01succeeds. Document CursorHostentry (User android-build) indocs/001-host-runbook.md - T009 [US1] Create
/srv/rom/{src,references,tooling,ccache,artifacts,logs,secrets}with ownership forandroid-buildon writable trees;secrets/restricted/empty — document modes indocs/001-host-runbook.md - T010 [US1] Verify:
namei -l /srv/rom /srv/rom/artifactsandsudo -iu android-build touch /srv/rom/artifacts/.write_testsucceeds; nochmod 777 - T011 [US1] Document account model (admin vs
android-buildvs service users) indocs/001-host-runbook.md— never build Android as root - T012 [US1] Copy laptop staging Git tree to
/home/android-build/sunfish-a16-rompreserving.git(rsync/scp/bundle); verifytest -f /home/android-build/sunfish-a16-rom/specs/001-development-environment/spec.md - T013 [US1] Ensure
/srv/rom/toolingis not used as Spec Kit checkout; note distinction indocs/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: ssh android-build@rom-dev01 → git, git lfs, repo, python3, ccache -s, and LOS-doc Java/prereqs succeed.
Implementation
- T014 [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 - T015 [US2] Install/configure
repoforandroid-buildper current docs; verifyssh android-build@rom-dev01 'repo --version' - T016 [US2] Ensure
git+git-lfsforandroid-build; verifyssh android-build@rom-dev01 'git lfs version' - T017 [US2] Configure ccache:
CCACHE_DIR=/srv/rom/ccache, ownershipandroid-build, size cap; document env in/home/android-build/.bashrcor/home/android-build/.profileanddocs/001-host-runbook.md - T018 [US2] Verify:
ssh android-build@rom-dev01 'ccache -s'shows configured cache dir - T019 [US2] Document FR-007 capacity (6 vCPU / 52 GB / 32 GB swap) and defer
-j/OOM tuning to003indocs/001-host-runbook.md— do not run a Lineage build - T020 [US2] Clean-shell toolchain smoke checklist executed; paste command outputs into
/srv/rom/logs/toolchain-smoke.txtand tick FR-002/SC-001 indocs/001-verification-matrix.md
Phase 5: User Story 5 — Laptop thin client (P1/P2 overlap — do after US1–US2)
Story goal: Cursor Remote SSH as android-build + artifact rsync proven; Pixel stays on laptop USB.
Independent test: Remote SSH edit on host as android-build; dummy artifact SHA256 matches after rsync; laptop has adb/fastboot binaries.
Implementation
- T021 [US5] Document Cursor Remote SSH →
/home/android-build/sunfish-a16-romwithUser android-buildindocs/001-host-runbook.mdand updatespecs/001-development-environment/quickstart.mdif needed - T022 [US5] Create
/srv/rom/artifacts/dummy-001.txtasandroid-build; recordsha256sumin/srv/rom/logs/rsync-smoke.txt - T023 [US5] From laptop,
rsyncdummy artifact; verify SHA256 match; record laptop path in/srv/rom/logs/rsync-smoke.txtanddocs/001-verification-matrix.md(SC-002) - T024 [US5] On laptop only: run
adb --versionandfastboot --version(do not connect or flash the Pixel); record versions indocs/001-host-runbook.md. Document adb/fastboot-on-laptop / no USB passthrough rule (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; sunfish-rom-build committed+pushed; laptop pull mirrors; unprivileged Semaphore smoke from canonical repo.
Independent test: Four repos on Gitea; meta history pushed; sunfish-rom-build fetch shows smoke playbook commit; laptop git clone --mirror works; Semaphore runs unprivileged smoke.
Implementation
- T025 [US3] Install Gitea on
rom-dev01with systemd + persistent data; bind UI to loopback/non-public; document unit/paths indocs/001-host-runbook.md - T026 [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) indocs/001-host-runbook.md - T027 [US3] Verify: local
curlto Gitea UI succeeds; confirm not relying on public Internet exposure; record bind address indocs/001-host-runbook.md - T028 [US3] Document Git transport chosen after host inspection (HTTP via SSH tunnel and/or tunneled Git SSH); do not open public
:2222or blindly editsaltenv=basesshd — write choice indocs/001-host-runbook.md - T029 [US3] Create Gitea repos:
sunfish-a16-rom,sunfish-rom-manifest,sunfish-rom-build,sunfish-rom-patches - T030 [US3] Push
/home/android-build/sunfish-a16-romhistory to Giteasunfish-a16-rom; setoriginto Gitea; verify remote in that directory - T031 [US3] Seed minimal structure in a working tree of
sunfish-rom-buildfor Ansible (e.g.ansible/playbooks path) — not inside Spec Kit meta repo - T032 [US3] Install Ansible on
rom-dev01; document version indocs/001-host-runbook.md - T033 [US3] Add unprivileged smoke playbook under
sunfish-rom-build(gather_facts + asserts for/srv/rom,android-build, toolchain); no become/sudo secrets - T034 [US3] Run smoke playbook successfully via
ansible-playbookCLI; log output to/srv/rom/logs/ansible-smoke.txt - T035 [US3] Commit and push the initial
sunfish-rom-buildstructure and smoke playbook to its canonical Gitea repository; verify the pushed commit is visible from a fresh fetch/clone (document clone URL/path indocs/001-host-runbook.md) - T036 [US3] Install Semaphore; bind like Gitea (loopback/tunnel); no public exposure; document in
docs/001-host-runbook.md - T037 [US3] Wire Semaphore so it executes the smoke playbook originating from the canonical
sunfish-rom-buildrepository, using the simplest private mechanism supported by the actual installation (token/HTTP/SSH — decide at implement). Run once successfully; evidence in/srv/rom/logs/semaphore-smoke.txt(FR-005). Still unprivileged / no sudo password in Semaphore - T038 [US3] From laptop, create bare mirrors with
git clone --mirrorfor all four repos (laptop initiates connection); rungit remote update+git fsck; document mirror paths indocs/001-host-runbook.md(FR-010/SC-007) - T039 [US3] Confirm laptop staging
/home/aventura/Workspaces/sunfish-a16-romis retained until T030+T035+T038 verified; only then optionally mark staging as non-canonical indocs/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
- T040 [US4] Document interfaces/routes: project workflow requires only public NIC —
docs/001-host-runbook.md+ evidence indocs/001-verification-matrix.md(SC-006) - T041 [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 - T042 [US4] Re-verify Gitea/Semaphore binds remain non-public; SSH admin +
android-build+ tunnel still work — updatedocs/001-verification-matrix.mdFR-009/SC-006 - T043 [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
- T044 [P] Fill all FR-/SC- evidence rows in
docs/001-verification-matrix.md(including SC-005: no PVE/qm/Salt VM tasks were performed) - T045 [P] Align
specs/001-development-environment/quickstart.mdwith final ports/paths/tunnel commands actually used - T046 Restart Gitea (+ Semaphore) via systemd; confirm recovery; optional reboot when safe; note results in
/srv/rom/logs/restart-smoke.txt - T047 Declare handoff in
docs/001-host-runbook.md:001complete → proceed to002, do not start Lineage sync/build - T048 Verify that no credentials/tokens/private keys are present in the current trees OR committed history of
sunfish-a16-romandsunfish-rom-build. Review current files plus reachable Git history; if a secret was ever committed, remove it from history and rotate/revoke it before closing001. Method may be manual/git log -p/git rev-listreview (no mandatory Gitleaks/TruffleHog)
Dependencies & story order
Phase 1 (laptop docs)
↓
Phase 2 preflight (host)
↓
US1 user + SSH key + /srv/rom + meta copy
↓
US2 toolchain ──────────────┐
↓ │
US5 thin-client smokes ←───┘ (needs artifacts + meta path + android-build SSH)
↓
US3 Gitea → repos → Ansible in sunfish-rom-build → commit/push → Semaphore → laptop mirrors
↓
US4 isolation hardening/validation
↓
Polish / handoff → STOP until implement; next feature 002 after 001 done
MVP (minimum useful host): complete through US2 + US5 (T007–T024) even if Gitea delayed — but formal 001 done requires P2 (US3+US4+polish) per plan.
Parallel opportunities
- T002/T003 on laptop before VM
- After T009: T011 docs can parallel T012 copy if disk ready
- T014–T016 package/
repo/git-lfspartly serial (apt) then T017 ccache - T044/T045 polish docs in parallel after evidence exists
FR/SC coverage map
| ID | Tasks |
|---|---|
| FR-001 | T007–T011, T008 |
| FR-002 | T014–T018, T020 |
| FR-003 | T009–T010, T013 |
| FR-004 | T025–T030 |
| FR-005 | T031–T037 |
| FR-006 | T021–T024 |
| FR-007 | T019 |
| FR-008 | T012, T030 |
| FR-009 | T040–T043 |
| FR-010 | T038–T039 |
| SC-001 | T020 |
| SC-002 | T022–T023 |
| SC-003 | T029–T030 |
| SC-004 | T021, T024, T047 |
| SC-005 | T005, T044 |
| SC-006 | T040–T043 |
| SC-007 | T038 |
Implementation strategy
- Do not execute host tasks until SSH to
rom-dev01works. - After analyze approval: STOP until VM exists, then
/speckit-implement. - Follow P1 then P2; stop/report on Salt conflicts.
- Do not plan
002until001implement + verification complete.