# 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 - Host: `a15.ssystems.de` (`49.13.104.83`), SSH port **37037**, guest name `rom-dev01` - Laptop key: `~/.ssh/id_ed25519_rom_dev01` + Host aliases in `misc/config.d/a15-rom-dev01` (see `docs/001-host-runbook.md`) - Laptop has `rsync`, `ssh`, Cursor Remote SSH, `adb`/`fastboot` ## P1 validation path ### 1. Preflight captured ```bash ssh rom-dev01-root 'less /srv/rom/logs/preflight/preflight-latest.txt' ``` ### 2. Build user workspace ```bash ssh rom-dev01 'whoami; hostname; test -f ~/sunfish-a16-rom/specs/001-development-environment/spec.md && echo SPEC_OK' ``` ### 3. Toolchain smoke (clean shell) ```bash ssh rom-dev01 'bash -l -c "git --version; git lfs version; repo --version; python3 --version; ccache -s"' ``` Expected: all commands succeed without sudo. See `/srv/rom/logs/toolchain-smoke.txt`. ### 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 test -d /home/android-build/sunfish-a16-rom/.git test -f /home/android-build/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 -L 3000:127.0.0.1:3000 rom-dev01-root # browser: http://127.0.0.1:3000/ (user sunfish-admin; password in host /srv/rom/secrets/) ``` Gitea binds **only** `127.0.0.1:3000`. Git over HTTP to that URL (no public `:2222`). ### 9. Four repos In Gitea: `sunfish-a16-rom`, `sunfish-rom-manifest`, `sunfish-rom-build`, `sunfish-rom-patches` (under `sunfish-admin/`). ### 10. Ansible CLI smoke ```bash ssh rom-dev01 'cd ~/sunfish-rom-build && ansible-playbook -i ansible/inventory.ini ansible/smoke.yml' ``` ### 11. Semaphore smoke (unprivileged) ```bash ssh -L 3001:127.0.0.1:3001 rom-dev01-root # http://127.0.0.1:3001/ project sunfish-rom / template env-smoke ``` Semaphore clones canonical `sunfish-rom-build` from Gitea and runs the smoke playbook without sudo. Evidence: `/srv/rom/logs/semaphore-smoke.txt`. ### 12. Off-VM mirrors Laptop path: `/home/aventura/Archives/sunfish-rom-mirrors/*.git` (rsync from `/srv/rom/artifacts/gitea-mirrors/` on host). ```bash # refresh mirrors (host builds mirrors; laptop pulls via rsync — no token on laptop) rsync -a android-build@a15.ssystems.de:/srv/rom/artifacts/gitea-mirrors/ \ ~/Archives/sunfish-rom-mirrors/ git -C ~/Archives/sunfish-rom-mirrors/sunfish-a16-rom.git fsck ``` ### 13. Restart survival ```bash ssh rom-dev01-root 'systemctl restart gitea semaphore; curl -fsS -o /dev/null http://127.0.0.1:3000/; curl -fsS -o /dev/null http://127.0.0.1:3001/' ``` Evidence: `/srv/rom/logs/restart-smoke.txt`. ### 14. Isolation checklist - No required internal NIC for workflow - Gitea/Semaphore binds only `127.0.0.1` - SSH still works after service restarts - Day-to-day docs do not require company VPN/internal DNS/LDAP/GitLab ## Done means `001` complete → start **`002`** (AXP capture). Do **not** start Lineage `repo sync` / build as part of `001` success.