# 009 handoff — 2026-10-08 evening Start here. Older remaining-work docs still describe the tree from before LAB booted the 2026-10-08 zip. This file is the execution map for the final ROM. Do not commit unless the owner asks. Do not flash GOLDEN. **Before every OTA bacon on host:** re-read [`009-ota-rebuild-checklist.md`](009-ota-rebuild-checklist.md) (includes bundled apps / `apps.mk` + US-S4-3 as of 2026-10-10). **Device roles (2026-10-16):** LAB = owner daily driver (no wipe/flash without ask). GOLDEN runs our build (debug OK). AXP oracle = a16 refs, not live GOLDEN. Polish backlog: [`009-lab-polish-20261016.md`](009-lab-polish-20261016.md) (configstore + EuiccDisabler fixes in WT for next bacon). ## Hard rules already paid for - LAB `11231JEC207477` = owner daily driver — no wipe/flash without explicit ask. GOLDEN `11071JEC203839` = test phone (our build OK). AXP oracle = `a16.ssystems.de` refs, not live GOLDEN. Use `adb -s ` deliberately. - Do not factory-reset LAB except an **owner-driven scratch** (recovery wipe + sideload closure zip). The recovery screen "Can't load Android system / data may be corrupt / reason=init_user0_failed" is **not** corrupt data. - Never lower `VENDOR_SECURITY_PATCH` below `2023-09-05`. - KernelSU stays out of Magisk ship boots. - Do not run AXP `Deblob.sh` defaults. - Do not start a second ninja on the same `out/`. - Sideload the full zip. A boot-only flash does not carry userspace. - User builds reject an undeclared downgrade (error 28). - `fastboot flash vendor` of a sparse image: `fastboot reboot fastboot` (`is-userspace=yes`) and `fastboot -S 128M`. A 256 MB chunk drops USB. Do not `fastboot -w`. Do not flash another build's vbmeta in the same test. - Host: `ssh -F docs/ssh/config a16-build`. Long builds via `/srv/rom/artifacts/bin/rom-detach` (tmux). Do not leave `mka` on a laptop SSH. - Keep the last booting zip plus two test builds. Laptop disk was tight. Host artifacts are canonical. ## Running now **Polish full bacon (2026-10-16, host):** session `bacon009polish20261016`, stage `worktree-20261016-polish`, `LOS_DATE=20261016`, fixes in [`009-lab-polish-20261016.md`](009-lab-polish-20261016.md). Status/log: `/srv/rom/artifacts/detach-bacon009polish20261016.*`. Laptop relaunch: `scripts/009-sync-ota-stage-to-host.sh` + `scripts/009-relaunch-polish-bacon.sh`. Migration export: [`009-laptop-migration-20261016.md`](009-laptop-migration-20261016.md). **Closure baseline (booted, Swissquote Island PASS):** wave 3 zip `20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys` SHA256 `7cd20e4d218bc04f0b4a31838a5bb9040db36148a2b38d90342b3bc9f224a5fd`. LAB slot `_a`, `boot_completed=1`. Owner confirmed Swissquote no longer exits `-69` in Island after wave 3 (Lineage tools removal). Parity notes: `docs/009-closure-parity-20261009.md`. Do not sideload this zip again. **Closure checklist (2026-10-09 evening):** | Item | Status | |------|--------| | Keys → `/srv/rom/secrets/android-certs` | done | | Interim scratch (wave 3 only, `/data` limpio) | **done** 2026-10-09: sideload `7cd20e4d…` `Total xfer: 2.00x` — reboot system from recovery | | **Final scratch** (wave 4 + malloc zip) | **sideloaded** 2026-10-09 ~20:10 local on LAB `11231JEC207477`. Boot both slots `75dd81bf…`. Zip `47a7e545…` `Total xfer: 2.00x`. Reboot system from recovery, then owner test | | `~/.android-certs.pre-secrets-20261009` removed on host | done | | GOLDEN package/cmdline parity | needs GOLDEN USB or reference dump | | `bacon009wave4b` | **stopped** 2026-10-09 ~16:11 UTC (avoid duplicate full ROM) | | `bacon009final` (wave 4 + malloc) | **FLASH_READY** `20261009T172104Z-axp-stage1-combo4-cve-hi-releasekeys`. Bacon exit 0; wrapper exit 1 was postflight `simg2img` on raw-ext4 `vendor.img` (script fixed: sparse-magic check). Postflight tail re-run 17:50 UTC: wave 4 + US-S4-2 OK. Bootanimation stays Lineage (no AXP asset in GOLDEN/PRO payload) | | Physical-SIM call gate | owner — before more radio deblob | | Git commit of repo closure deltas | owner asked 2026-10-09 | Check detach logs under `/srv/rom/artifacts/detach-bacon009*.log`. Do not run two ninjas on the same `out/`. Last closure build `bacon009tools` finished `exit=0` `2026-10-09T14:54:03Z`. `bacon009deblob4` finished `exit=0` at `2026-10-09T12:01:31Z`. Zip `/srv/rom/artifacts/009-axp-los23-port/20261009T120025Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261009-sunfish.zip` SHA256 `bd1ce97896b5da31d4c22d4ffc3f2050ad204eea45768bbf86f7527f44b70c51`. Sideloaded to LAB at 14:58 local (`Total xfer: 2.00x`). Owner confirmed boot. Slot `_b`. `ro.build.date` `Fri Oct 9 11:04:11 UTC 2026`. The nine wave-2 paths are absent from the image. `/data` leftovers `com.google.android.ims` and `com.google.android.apps.carrier.carrierwifi` were uninstalled for user 0 and user 10. `ims` and `qcrilmsgtunnel` remain. Previous slot `_a` is the wave-1 zip. If this slot dies later, `fastboot -s 11231JEC207477 --set-active=a`. Do not wipe. Do not sideload this zip again. Wave 2 drops CarrierServices, CarrierSettings, CarrierWifi, CarrierSetup, RilConfigService, grilservice, ImsServiceEntitlement, PresencePolling, and RcsService. Qualcomm radio packages stay. AVB flags 0. Boot of this zip confirmed on LAB slot `_b`. Log `/srv/rom/artifacts/detach-bacon009deblob4-20261009T110253Z.log`. `bacon009deblob3` finished `exit=0` at `2026-10-09T10:18:22Z`, was sideloaded to LAB at 12:33 local (`Total xfer: 2.00x`), and the owner confirmed boot. Slot `_a`. `ro.build.date` is `Fri Oct 9 09:18:53 UTC 2026`. `/product/priv-app/EuiccGoogle` and `/system_ext/priv-app/EuiccGoogleOverlay` are absent. The `/data` leftover `com.google.android.euicc` was uninstalled for user 0 and Island user 10 (`pm uninstall` Success, `pm path` empty). EuiccSupportPixel, EuiccSupportPixelPermissions, and OpenEUICC remain. `im.angry.openeuicc/.ui.PrivilegedMainActivity` stayed up and opened `DownloadWizardActivity` (empty card). That is the wave-1 pass. Do not sideload this zip again. Next gate is a physical-SIM call, then VoLTE and VoWiFi, before any wave-2 bacon. If this slot dies later, `fastboot -s 11231JEC207477 --set-active=b` (flags-0 zip). Do not wipe. `bacon009deblob2` finished `exit=0` at `2026-10-09T09:09:32Z`. Do not sideload it. Zip `/srv/rom/artifacts/009-axp-los23-port/20261009T090831Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261009-sunfish.zip` SHA256 `722e6d2e5cd639c3dfcea8af1585d5a741ea3ffd13ff5e0fad62d2c76722b70e`. Flags 0. `EuiccGoogle.apk` and `EuiccGoogleOverlay` are still in the image. `bacon009deblob` finished `exit=0` at `2026-10-09T07:38:53Z`. Do not sideload it: flags are 0, but both Google LPA packages are still in the images. Zip `/srv/rom/artifacts/009-axp-los23-port/20261009T073753Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261009-sunfish.zip` SHA256 `63851d964a259aefa8247883401481296dd7c6bb51dbcc13ee901361c7d8ab50`. `bacon009timeouts` finished `exit=0` at `2026-10-08T22:02:51Z`. Zip, not flashed: `/srv/rom/artifacts/009-axp-los23-port/20261008T220151Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261008-sunfish.zip` SHA256 `1717d23db2024f524dfe48364b13ee66c998364adfc10c3f9bde676a3d926a58`. Same hash on the `lineage-23.2-20261008-PRO-sunfish.zip` twin. vbmeta flags still 3. It carries the timeout settings and Droidify 0.7.8. `bacon009avb0` finished `exit=0` at `2026-10-09T00:26:40Z`. Log line `avb_infra=... flags=0`. Sideloaded to LAB `11231JEC207477` on 2026-10-09 morning. `Total xfer: 2.00x`. Before the sideload the running slot was `_a` (cmdline zip). Recovery adb came back unauthorized, so the owner reboots from the recovery menu. If it sticks on the Google logo, `fastboot -s 11231JEC207477 --set-active=a`. Do not wipe. Zip: `/srv/rom/artifacts/009-axp-los23-port/20261009T002537Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261008-sunfish.zip` SHA256 `1aabda75c672e1e7d7a7df046a3428ef50fa47aaa3501808ff3d12bbb075e96b`. Local copy `/tmp/axp-flash/AXP-Resurection-Pro-23.2-20261009-avb0-sunfish.zip`. No ninja is running. The deblob Soong files are still only on the laptop. ## What is on LAB right now **Closure baseline (wave 3)** unless a scratch reinstall is in progress. | | | |---|---| | Artifact dir | `20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys` | | Zip | `AXP-Resurection-Pro-23.2-20261009-sunfish.zip` | | SHA256 | `7cd20e4d218bc04f0b4a31838a5bb9040db36148a2b38d90342b3bc9f224a5fd` | | Host path | `/srv/rom/artifacts/009-axp-los23-port/20261009T145241Z-axp-stage1-combo4-cve-hi-releasekeys/` | | Slot (last known) | `_a` after wave 3 sideload | | deblob | wave1 euicc + wave2 carrier/rcs + wave3 lineage tools | | AVB | flags `0` on shipped `boot.img` | | Swissquote Island | **PASS** after wave 3 (owner confirmed); prior `-69` was Lineage tools on system | Wave 3 removes `bash`, `htop`, `nano`, `unrar`, `system/addon.d/50-lineage.sh`. `curl` and `vim` stay. Wave 4 diag/`bpftool`/… are **still present** on this image; use `scripts/009-bacon-wave4-deblob.sh` for a candidate without them. **Rollback slots (do not wipe casually):** other slot may hold an older zip (wave 2 on `_b`, wave 1, or flags-only builds). `fastboot -s 11231JEC207477 --set-active=a|b` only if the active slot boot-loops. **Scratch reinstall (owner 2026-10-09):** bootloader → `fastboot flash boot_a` and `boot_b` with closure `boot.img` → recovery → **Factory reset** → sideload the closure zip above → **Reboot system** from recovery (not `adb reboot` if adb is unauthorized). Re-verify Magisk, Island, Swissquote after setup. **Physical-SIM call gate:** place a normal mobile call (not only Wi‑Fi) before any further Qualcomm radio deblob. Record pass/fail in this file. Parity matrix: `docs/009-closure-parity-20261009.md`. ## 1. hardened_malloc — 2 GiB rebacon finished, not flashed `bacon012malloc3` finished `exit=0` at `2026-10-08T18:43:47Z` (58 min, ccache). Zip: `/srv/rom/artifacts/009-axp-los23-port/20261008T184238Z-axp-stage1-combo4-cve-hi-releasekeys/AXP-Resurection-Pro-23.2-20261008-sunfish.zip` SHA256 `f85a0233be1ca83d6a866c081e7cf314e9b5e547a4d6324addb7139ed90030e9`. Vendor SPL `2023-09-05`. Not sideloaded. The phone is still on the morning zip in slot `a`. The first malloc zip boot-looped. `bacon012malloc2` (`20261008T170027Z`, SHA256 `28c7f0bfa11c60f24e86d35c080cd1e52c244c3640168e34673e4ef0252d690c`) was sideloaded to LAB slot `b` at 19:17 local and rebooted at the Google logo. Recovered without a wipe: `fastboot --set-active=a`, morning zip booted (`boot_completed=1`, vendor SPL `2023-09-05`). Slot `b` still holds the bad build and is not marked successful. Do not set it active. Cause: sunfish msm-4.14 is `CONFIG_ARM64_VA_BITS=39` (3-level page tables), on LAB and on GOLDEN. Upstream `Android.bp` uses `CONFIG_CLASS_REGION_SIZE=34359738368` (32 GiB), which needs 48-bit VA; the README says the defaults do not work on 39-bit. DivestOS Patch.sh (LineageOS-17.1/20.0/21.0) does `sed -i 's/34359738368/2147483648/' Android.bp` ("revert 48-bit address space requirement"). GOLDEN ships hardened_malloc on the same 39-bit kernel and its `system_server` holds about 210 GiB of `---p` reservations, which matches 2 GiB regions. `config/light.mk` is still 32 GiB; it is not a fix. Fixed in `apply_012_hardened_malloc.py` and applied on the host tree: - region size `2147483648`; the script exits if it is not 2 GiB; - The `// 32GiB` comment next to `2147483648` was replaced after `bacon012malloc3` exited. The line now says `// 2GiB, 39-bit VA (DivestOS/AXP)`. - the exclusion helper had been inserted between `__attribute__((noinline))` and `__libc_preinit_impl`, which moved `noinline` off the function bionic needs it on. The applier now places the helper before the attribute, repairs the misplaced form, and exits if `noinline` is lost. Next: sideload the `20261008T184238Z` zip to LAB only (it lands on slot `b`), then smoke boot, USB, Magisk, camera, and that surfaceflinger stays on Scudo. If it loops at the Google logo again, `fastboot --set-active=a`. Do not factory-reset. Original notes for the first attempt follow. Session `bacon012malloc2`, started `2026-10-08T10:25:49Z`. - Status: `/srv/rom/artifacts/detach-bacon012malloc2.status` - Log: `/srv/rom/artifacts/detach-bacon012malloc2-20261008T102549Z.log` - At 13:55 local: still `running`, ninja ~10 % (6453/63504), no error. `libc` had already linked at `2026-10-08T10:30:05Z`. - A 30-minute watcher lived in the 2026-10-08 chat. If that chat is gone, read the status file. Do not start another ninja. Wrapper: `scripts/009-bacon-hardened-malloc.sh`. It applies `vendor/sunfish-a16/patches/012-hardened-malloc/apply_012_hardened_malloc.py`, builds `libc`, then execs the main Stage1 bacon. The host tree is already patched, so a plain re-run of the main bacon script also ships malloc. Do not revert `bionic` unless this experiment is abandoned. Pin: GrapheneOS `hardened_malloc` `1d7fc7ffe0f8068a32ab2ba33df7515e7bad3f5f` (branch 14 tip, "support GCC15"). 64-bit libc uses it; 32-bit stays Scudo. `frameworks/av` `RLIMIT_AS` hunk does not exist on this LOS 23 tree and was not ported. Sunfish has no MTE; the `device_has_arm_mte` product variable was stripped from `Android.bp`. Exclusions, required: `/system/bin/surfaceflinger` exact path, and any exe whose path contains `camera`. Real LAB paths: `/vendor/bin/hw/android.hardware.camera.provider@2.7-service-google` and `/system/bin/cameraserver`. Env `DISABLE_HARDENED_MALLOC` also disables it. `init.rc` sets `vm.max_map_count` to `1048576`. Previous failure, already fixed: `h_malloc_info` was undeclared (`h_malloc.h` omits it on Android). Declaration is in `malloc_common.h`. The dead log is `detach-bacon012malloc-20261008T101328Z.log`. Do not treat that log as the current job. This bacon does **not** contain the Swissquote cmdline fix, the Settings timeout patches, deblob, or AVB flags 0. When it finishes with `exit=0`: verify the zip hash, sideload only LAB, then smoke boot, USB, Magisk, camera, and that surfaceflinger is still on Scudo. Keep the 20261008 zip until that smoke passes. If the bacon fails, diagnose before relaunching. Do not factory-reset. ## 2. Swissquote — next bacon only after malloc boots Measured 2026-10-08 with both phones online. Same app on both: `com.swissquote.android` 9.10.0 (`versionCode=91000000`). Both have Island user 10, Zygisk, DenyList on, and the same module set except GOLDEN also has `flag-secure-disabler`. DenyList on both already has - `com.swissquote.android|com.swissquote.android` - `com.swissquote.android|com.swissquote.android_zygote` DenyList has no user id. It covers Island. Vector's scope is `user_id=0` on both, and GOLDEN does not even have Swissquote installed on user 0 (only user 10) and it still passes. The module screen that cannot pick work-profile apps is a red herring. Do not chase it. ### Proven ROM difference GOLDEN `/system/bin/init` contains `chmod("/proc/cmdline", 0440)`. LAB's init does not. Magisk's binary on neither phone contains that string. No module script was found chmod'ing it. | | LAB | GOLDEN | |---|---|---| | `/proc/cmdline` mode | `0444` root:radio | `0440` root:radio | | shell can read it | yes, sees `verifiedbootstate=orange` | no (`Permission denied`) | | `init.rc` | `chown root radio` only | same `chown`, no chmod line | Both `init.rc` files only chown. The mode change is a C call inside GOLDEN's init. Clone that call. Do not implement it as a Magisk module. The owner asked for that specifically. Where it lives: `apply_009_cmdline_mode.py`, called by the ship bacon. It inserts AOSP's `CHECKCALL(chmod("/proc/cmdline", 0440))` in `first_stage_init.cpp` immediately after the proc mount. That CHECKCALL is what logs `chmod("/proc/cmdline", 0440) failed`, the string found in GOLDEN's init. LOS 23.2 already chmod's `/proc/bootconfig` and did not chmod cmdline. `bacon009cmdline` is the build for this and keeps the 2 GiB hardened_malloc already in the tree. Do not flash it until it finishes and the owner asks. The compiling malloc tree does not have this call (`init.cpp` has no `cmdline` match; `init.rc` only has the chown at line 1282). ### 2026-10-08 22:30 — writer found, do not bake the spoof into the ROM Play Integrity Fix `service.sh` (same file on both phones) runs after `sys.boot_completed=1` and calls `resetprop_if_diff`. That helper does nothing when the property is empty: ``` [ -z "$CURRENT" ] || [ "$CURRENT" = "$EXPECTED" ] || resetprop -n "$NAME" "$EXPECTED" ``` `spoofProps=false` does not gate this block. Both phones now use the same PIF print: `oriole` Pixel 6 CANARY, `ZP11.260618.005`. The earlier `tegu` / `stallion` note is stale. GOLDEN's bootloader cmdline creates the properties, so the module rewrites them. LAB's cmdline never creates `vbmeta.device_state` or `veritymode`, so the same script skips them. | `getprop` | LAB | GOLDEN | |---|---|---| | `ro.boot.verifiedbootstate` | `green` (was `orange`) | `green` (was `orange`) | | `ro.boot.flash.locked` | `1` | `1` | | `ro.boot.vbmeta.device_state` | empty | `locked` (cmdline said `unlocked`) | | `ro.boot.veritymode` | empty | `enforcing` (real cmdline value, not a spoof) | | `sys.oem_unlock_allowed` | empty on the 22:32 read | `0` (cmdline-era value was `1`) | Vector's `/data/adb/lspd/log/props.txt` on GOLDEN still records the real values (`orange`, `unlocked`, `enforcing`, `oem_unlock_allowed=1`). They are not in `/data/property/persistent_properties`. Island sees the rewritten `getprop` because the property area is global. It cannot open `/proc/cmdline` (`0440`), so it never sees the raw `unlocked` / `orange`. The owner said Swissquote on GOLDEN also worked with no Magisk modules. The PIF rewrite is therefore not the first fix. Hope is that the init chmod alone is enough. Do not set `sys.oem_unlock_allowed=0` in the ROM; it conflicts with the OEM-unlock escape hatch. Do not add the missing cmdline tokens in this bacon. If Island still fails after the chmod, those tokens belong to the separate AVB flags experiment. TEESimulator 71 on LAB (`71-17be1f0`) did not change the outcome. Its target list is still only `com.google.android.gms`, `com.android.vending`, and `io.github.vvb2060.keyattestation`. GOLDEN is still TEE 67 with the same three targets. The app is not in that list. Test only inside Island. GOLDEN does not have the app on user 0, and the owner said it has never worked in the main profile there. LAB currently has it on user 0 and user 10. `ps` shows `magiskd`, `su`, `zygiskd64`, `teesim`, and `vectord` on both phones, so a visible process list does not explain why Island passes on GOLDEN. ### 2026-10-08 22:53 — chmod booted, Island still closes Slot `_a`, zip SHA256 `40ed3213…ccfa`. `/proc/cmdline` is `0440`; shell gets permission denied; root still reads `orange`. The app still exits in Island and in the main profile. The 22:52 log is the same sequence as before the chmod: DenyList hit, Play services `261200000` vs microG `252432034`, `libsigner.so`, SELinux and `/cache` denied, `ps`, suppressed toast, process dies. GOLDEN's microG is older (`252432033`) and Island works there, so the version warning is not the gap. What Island can still see: `ro.boot.vbmeta.device_state` and `ro.boot.veritymode` are empty on LAB. GOLDEN's bootloader cmdline creates both (`unlocked` and `enforcing`) even with no modules. Do not chase that inside the timeouts bacon. It stays with the AVB flags 0 experiment. ### If the app still fails after the chmod These are owner-installed modules, not ROM payload (`docs/009-magisk-preinstall-runbook.md`): 1. TEESimulator version is already ruled out. LAB is `71-17be1f0`, GOLDEN is `67-4f42350`, same three targets, and 71 changed nothing. Config holds a keybox; do not copy it into git or into a doc. 2. PIF print is already the same on both (`oriole` Pixel 6 CANARY). Do not chase `stallion`. A wrong CANARY print on sunfish already broke this surface once (`comet`); that is not the current gap. Banking flow if the app is reinstalled (constitution): Aurora, do not open, DenyList including processes before the first process, clone into Island (`com.oasisfeng.island.fdroid`, not Insular), first launch inside Island, Play update from the work profile. Spec 009 still marks banking deferred. The owner asked to make Swissquote work on LAB anyway. Yuh on GOLDEN needed Vector's bootloader spoofer on top of DenyList; Swissquote on GOLDEN did not. ## 3. After that, one bacon each Do not stack these into the malloc zip or into each other. 1. **Settings timeouts and sensitive QS tiles.** Already inside `bacon009timeouts` (see "Running tonight"). Defaults stay off except the sensitive QS tiles, which ask for the PIN on the lock screen. After boot, confirm the three settings exist and Droidify is 0.7.8. 2. **Selective deblob.** Own bacon, after the timeouts zip exists. Study and the wave-1 Soong override are in the section below. Do not run `Deblob.sh`. Do not put wave 2 in the same bacon. 3. **AVB flags 0.** Script is ready, not launched. `scripts/009-bacon-avb-flags0.sh` exports `AXP_AVB_FLAGS=0` and `WITH_AVB=true`. That is the only Lineage switch: `BoardConfigLineage.mk` skips `--flags 3`. Same `avb.pem`, same `SHA256_RSA4096`. Pubkey sha1 `ee85ac5a2dcec0846e95dd575f874a659026d790`. The default ship script still expects flags 3 unless that env is set. Do not rsync the ship script over `/srv/rom/artifacts/bin/` while `bacon009timeouts` is running. Launch only after that status file shows `exit=0`, and do not flash until the owner asks. On LAB check Magisk, a full sideload, dm-verity, and whether the raw cmdline gained `veritymode` and `vbmeta.device_state`. Relock stays **wont**. If it boot-loops, set the active slot back to the previous zip. Measured on the current LAB image, before that experiment: `getprop ro.boot.vbmeta.device_state` and `getprop ro.boot.veritymode` are empty. `ro.boot.verifiedbootstate=green` is the PIF spoof; the raw cmdline is still `verifiedbootstate=orange`. These two missing tokens are bootloader cmdline properties. Flags 3 is `HASHTREE_DISABLED|VERIFICATION_DISABLED`. GOLDEN's raw cmdline, read earlier the same night, contains `androidboot.vbmeta.device_state=unlocked` and `androidboot.veritymode=enforcing`. Do not write `locked` or `enforcing` into the ROM, and do not set `sys.oem_unlock_allowed=0`. 4. **Lock-scope concurrency review.** `vendor/sunfish-a16/patches/009-kernel-hardening/ports/cve-2022-49980-lock-scope.patch`. Boot and USB already passed on LAB. Review the companion. Do not revert it unless a new failure shows up. The one-liner stays denylisted. 5. **Leftover high-offset kernel CVEs.** Small reviewed batches (≤10), strict applicator, boot each batch. nf_tables leftovers stay skipped. Failed Stage1 probes (allocsize/0007, ro/0007+0034, slab) are low priority. Do not reflash `20260918*-axp-kh-cve` or `kh-full`. 6. **Droidify.** `bacon009timeouts` ships `0.7.8` (`versionCode=780`, targetSdk 37). Host file `/srv/rom/prebuilts/axp-apps/Droidify.apk`, SHA256 `3e7934ff9b811c2f77794793381241095a02bac2d163bf922cb5a5a0ed25ca82`. The previous `0.7.7` apk is kept beside it as `Droidify-0.7.7.apk`. Aurora and Fossify stay. 7. **GPG SHA256 sums** of published zips, the way AXP does. Owner on 2026-10-09: not needed now. Do not start it. AXP's current publish path is a SHA512 file plus `gpg --verify` on that file (`docs/knowledge/signatures`). 8. **Release-key custody.** Signing works (the booted zip is `release-keys`). Keys are still `$HOME/.android-certs/` on rom-dev01 plus a gitignored copy under `vendor/lineage-priv/keys` and `vendor/sunfish-a16/certs`. Move the private material to `/srv/rom/secrets/` and confirm the encrypted offline copy. Never commit `.pk8`. Cert tar already at `/home/android-build/backups/android-certs-20260929T1637Z.tar.gz`. 9. **SetupWizard language bounce** after Wi-Fi connect. Wi-Fi stays up. Non-blocking. Looked at on 2026-10-08: `lineage_wizard_script.xml` goes locale, then SIM, then network, and every network result advances to datetime. There is no result edge that returns to language. Do not invent a patch. `LocaleActivity` can still call `updateLocale` from the SIM MCC while that page is open; that is a different moment from the Wi-Fi step. 10. **LOS 23 nightly rebase**, then re-apply this pack. Do it after the malloc and cmdline bacons, not during them. 11. **Regenerate** `plan.md` / `tasks.md` after any `spec.md` edit. Spec Kit order stands. Do not use upstream `taskstoissues`. ## Selective deblob — studied 2026-10-08 Do not run AXP `Deblob.sh`. It is not in the public AXP-OS repos or in `/srv/rom/references/axp/archive/codeberg/git`, and its usual defaults drop CNE, IZat/XTRA, and sometimes Widevine. Shipped GOLDEN still has `com.qualcomm.qti.cne`. Spec FR-018 and the constitution forbid deleting the IZat/XTRA/xtwifi blobs. The positive list is the owner's finish list. The `[ -e $f ]` loop that printed ABSENT for every vendor binary was a quoting bug. `ls` of the literal path is the check: "Permission denied" means the file exists and shell cannot stat it; "No such file" means gone. ### Positive list — do not override, do not delete Present on the booted LAB image (`11231JEC207477`). GPS daemons and `imsrcsd` were also checked on GOLDEN before it was unplugged. | Keep | LAB evidence | GOLDEN | |---|---|---| | `xtra-daemon`, `lowi-server`, `loc_launcher` | `/vendor/bin/…` exists (permission denied) | those three paths are "No such file" on GOLDEN. Keep them. Default is the precise Lineage stack. The two Settings switches below, both default off, are how the owner turns that assistance off and matches the AXP posture without deleting the binaries. | | `xtwifi.conf` | copied by `sunfish-vendor.mk` to `/vendor/etc/xtwifi.conf` | absent on GOLDEN (`No such file`). Keep the copy rule. The location switches are what turn the assistance off. | | Widevine | `/vendor/bin/hw/android.hardware.drm-service.widevine` exists. Soong module `android.hardware.drm-service.widevine` | same path exists | | IMS | `/system_ext/priv-app/ims/ims.apk` (`org.codeaurora.ims`); `/vendor/bin/ims_rtp_daemon`, `imsdatadaemon`, `imsqmidaemon`, `imsrcsd` all exist | `imsrcsd` is absent on GOLDEN. Keep it. It is the Qualcomm RCS daemon, and the positive list says IMS. | | IPA | `/vendor/bin/ipacm` exists | directory listing earlier the same night also showed it on GOLDEN | | IWlan | `/vendor/app/IWlanService/IWlanService.apk` (`vendor.qti.iwlan`); `vendor.qti.hardware.data.iwlan@1.0.so` exists on both | keep | | CNE | `/vendor/app/CneApp/CneApp.apk` (`com.qualcomm.qti.cne`). Soong `CneApp`, `libcne*` | package was on GOLDEN too | | eUICC hardware | `/system_ext/priv-app/EuiccSupportPixel/EuiccSupportPixel.apk` and `EuiccSupportPixelPermissions` (`com.google.euiccpixel`, `.permissions`) | both phones | | OpenEUICC | `/system_ext/priv-app/OpenEUICC/OpenEUICC.apk` (`im.angry.openeuicc`) | both phones | | Radio packages already on both | `com.qualcomm.qti.telephonyservice`, `com.qualcomm.timeservice`, `com.qualcomm.uimremoteclient`, `com.qualcomm.uimremoteserver`, `com.android.carrierconfig`, `com.android.carrierdefaultapp`, `com.android.providers.telephony` | keep | GPS precision stays the default. `apply_009_supl_privacy.py` is already in the ship bacon. Both switches live in Location settings and start off, so SUPL, LPP, XTRA and IZat keep running: - "Force disable Secure User Plane Location (SUPL)" (`force_disable_supl`). On sets `SUPL_MODE=0`. IMSI and the phone number are never sent to a SUPL server, whether this switch is on or off. - "Stop extra location assistance" (`force_disable_location_assist`). On sets `LPP_PROFILE=0` (LPPE goes with that session), skips the framework XTRA download, and stops `loc_launcher` (`xtra-daemon`, lowi, IZat). Satellite fixes keep working. Turning it off starts `loc_launcher` again. That second switch is the AXP location posture. Do not delete the blobs and do not change either default to on. `/vendor/lib64/libimsmedia_jni.so` is missing on both phones. The JNI libs ship inside the ims app (`system_ext_priv-app_ims_lib_arm64_libimsmedia_jni_so`). That is not a deletion. ### Wave 1 — booted 2026-10-09, pass `bacon009deblob3` (`20261009T101715Z`, SHA256 `efbec33ac2bafc75ee2f90970a9286f51fe8073b61fc3ed11c01689c9e8a28cf`) is the running LAB slot `_a`. `EuiccGoogle` and `EuiccGoogleOverlay` are absent from the image. The `/data` update survived the sideload and was removed for user 0 and user 10. EuiccSupportPixel and OpenEUICC stayed. OpenEUICC opened onto `DownloadWizardActivity`. Empty card is the pass. The notes below are the failed attempts; do not rebuild them. Why the old override did nothing: `EuiccGoogle` is a Soong `android_app_import` in `vendor/google/sunfish/Android.bp` (`product_specific: true`). `NoEuiccGoogle` was a Make `BUILD_PHONY_PACKAGE`. Make's `LOCAL_OVERRIDES_PACKAGES` only filters Make modules (`build/make/core/main.mk` `module-overrides`). `out/soong/soong.lineage_sunfish.variables` contains both `NoEuiccGoogle` and `EuiccGoogle` in the product package list, and `PackageNameOverrides` is empty. Laptop tree now, not rsynced: - `vendor/sunfish-a16/deblob/Android.bp` — `NoEuiccGoogle` (`product_specific`) overrides `EuiccGoogle`; `NoEuiccGoogleOverlay` (`system_ext_specific`) overrides `EuiccGoogleOverlay`. It does not name `EuiccSupportPixel`. - `vendor/sunfish-a16/apps.mk` installs both phonies. - The Make phony was removed from `vendor/sunfish-a16/Android.mk`. Do not put an `Android.bp` beside that `Android.mk`; Soong would skip the prebuilt APKs in the same directory. After the timeouts bacon exits, rsync those three files, then a deblob bacon. Do not flash until asked. On the installed-files list, confirm `EuiccGoogle.apk` and `EuiccGoogleOverlay.apk` are gone and `EuiccSupportPixel.apk` and `OpenEUICC.apk` remain. The `/data` update can survive a sideload. If `pm path com.google.android.euicc` still points at `/data/app`, `adb -s 11231JEC207477 shell pm uninstall --user 0 com.google.android.euicc` after boot. The owner has no eSIM profile, so do not block on downloading one. Open OpenEUICC: it must start and not crash. An empty card or "no profiles" is a pass. `pm path` must still show EuiccSupportPixel and OpenEUICC. ### Wave 2 — not in the wave-1 bacon Rechecked read-only on GOLDEN `11071JEC203839` at 2026-10-08 23:24 local, with LAB unplugged. `pm path` printed no path for every row below, and `ls` returned `No such file` for `xtra-daemon`, `lowi-server`, `loc_launcher`, `imsrcsd`, and `/vendor/etc/xtwifi.conf`. Present on GOLDEN, same as LAB: EuiccSupportPixel, EuiccSupportPixelPermissions, OpenEUICC (`/system_ext/priv-app/OpenEUICC_AXP-OS/OpenEUICC_AXP-OS.apk`), CneApp, `org.codeaurora.ims`, IWlanService, QtiTelephonyService, TimeService, both uimremote packages, CarrierConfig, CarrierDefaultApp, TelephonyProvider, `ims_rtp_daemon`, `imsdatadaemon`, `imsqmidaemon`, `ipacm`, and the Widevine HAL. One bacon, after wave 1 has booted and a physical-SIM call, VoLTE, and VoWiFi have passed. No eSIM profile is required. Same Soong-phony pattern, matching partition flag. Google, not the Qualcomm IMS stack: | Module | Partition flag | LAB path | Package | |---|---|---|---| | `CarrierServices` | `product_specific` | `/product/priv-app/CarrierServices` (active path is `/data/app/…/com.google.android.ims…`) | `com.google.android.ims` | | `CarrierSettings` | `product_specific` | `/product/priv-app/CarrierSettings/CarrierSettings.apk` | `com.google.android.carrier` | | `CarrierWifi` | `product_specific` | active path `/data/app/…/com.google.android.apps.carrier.carrierwifi…` | `com.google.android.apps.carrier.carrierwifi` | | `CarrierSetup` | `system_ext_specific` | `/system_ext/priv-app/CarrierSetup/CarrierSetup.apk` | `com.google.android.carriersetup` | | `RilConfigService` | `system_ext_specific` | `/system_ext/priv-app/RilConfigService/RilConfigService.apk` | `com.google.RilConfigService` | | `grilservice` | `system_ext_specific` | `/system_ext/priv-app/grilservice/grilservice.apk` | `com.google.android.grilservice` | AOSP, not vendor blobs. Override only after the same call test: - `ImsServiceEntitlement` in `packages/apps/ImsServiceEntitlement/Android.bp`, installed at `/product/priv-app/ImsServiceEntitlement/ImsServiceEntitlement.apk` (`com.android.imsserviceentitlement`). - `com.android.service.ims` is `/system_ext/app/RcsService/RcsService.apk`. - `com.android.service.ims.presence` is `/system_ext/app/PresencePolling/PresencePolling.apk`. Grep `name: "RcsService"` and `name: "PresencePolling"` before writing the phony. The names were not in `packages/services/Telephony/Android.bp`. Leave these alone until a zip that removed only the Google rows above has made a call. They were absent on GOLDEN, and they sit next to radio: - `atfwd` → `/system_ext/app/atfwd/atfwd.apk` (`com.qualcomm.atfwd`) - `qcrilmsgtunnel` → `/system_ext/priv-app/qcrilmsgtunnel/qcrilmsgtunnel.apk` - `uceShimService` → `/system_ext/app/uceShimService/uceShimService.apk` - `com.qualcomm.qti.services.secureui` → same directory name under `/system_ext/app/` - `CACertService` → `/vendor/app/CACertService/CACertService.apk` (`vendor.qti.hardware.cacert.server`, `soc_specific: true`) Do not remove `ims`, `QtiTelephonyService`, `CneApp`, `xtra-daemon`, `lowi-server`, `loc_launcher`, `imsrcsd`, Widevine, or `EuiccSupportPixel` in either wave. ## Already on the booted zip — do not redo - Magisk 30.7 preroot (`/system_ext/bin/magisk`). GOLDEN oracle is still Magisk 29.0. Ship stays 30.7 unless 30.7 itself breaks a bank after the cmdline fix. Dormant until Additional Setup. - microG GmsCore `0.3.17.252432` (`252432034`), not `-hw`. - Phonesky from `/srv/rom/prebuilts/phonesky/`. Never git. - OpenEUICC privileged, platform cert, deps SDK forced to 36 (`prebuilts/openeuicc-deps` `5402167` was generated for SDK 37). - Sigspoof (`apply_005_sigspoof.py`) and call recording / FLAG_SECURE (`apply_008_call_rec_flag_secure.py`) are in the ship script. FLAG_SECURE override is a project extra, default off. - Private DNS, connectivity check, the two location switches (both default off, so SUPL / XTRA / IZat stay on for precision), Yama `persist.native_debug`, disable-app. - Jelly stays. Gallery is Fossify. Gallery2 APK stays absent. WebView stays LOS 23. No NeoLauncher. No `axp.os` OTA endpoints. - Vendor SPL guard: `apply_009_axp_identity.py` rewrites a `2023-08-05` rollback back to `2023-09-05` and exits otherwise. AXP GOLDEN really is `2023-08-05`. This divergence is deliberate. - `LINEAGE_BUILDTYPE=PRO`, `user`, project AVB key, flags 3. - Stage1 + combo4 + FORTIFY + CVE-clean + hi-batch1–3 + US-S5-1 Yama/slab + lock-scope. `KSYM_NAME_LEN` stays 192. Stage1 must use `patch --forward` and must omit `misc/0021` (already in the LOS base; GNU patch would reverse it and shrink KSYM 192→128). ## init_user0 — do not rediscover The 17:15 zip (`SHA256 2c16d2385094197181c07dde4e9604137883eefedc2b346cc1071e38abb57a0b`) lowered vendor SPL from `2023-09-05` to `2023-08-05`. Keymaster blobs on the existing install refuse that rollback. `vdc cryptfs init_user0` fails and recovery writes `boot-recovery --prompt_and_wipe_data --reason=init_user0_failed`. Proof, same userdata: nols boot failed, full 13:31 boot on the 17:15 userspace failed, flashing only the 13:31 vendor (`2023-09-05`) made Android boot. Data was fine. The 13:31 zip (`SHA256 2c4eb9cb831e96a57c2c068e5c044ae5d29ef140f53817e9246cac3c61dbe008`) is the older known-good, without lock-scope. Quarantine `20261007T161115Z` (`SHA256 df2ad13f6afeb2d25f5e8f7a32ee2caa0b926550000e5cb3078c8a56d8efffd7`) stays unflashed. Emulator and an on-screen boot debugger do not explain this. The emulator cannot boot the sunfish 4.14 / keymaster / userdata stack. The debug console is UART `ttyMSM0`. pstore on this LAB was encrypted and unreadable. `docs/007-debug-boot-panic-screen.md`. ## Uncommitted work the next session must keep Not committed. Do not revert while picking up a later item. - `apply_009_axp_identity.py` — vendor SPL stays `2023-09-05`. - `scripts/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh` — lock-scope applied, vendor SPL grep, Jelly/Fossify gates, the userspace applies listed above. - `scripts/009-bacon-hardened-malloc.sh` and `vendor/sunfish-a16/patches/012-hardened-malloc/`. - `tests/test_009_next_bacon_guards.py`, `tests/test_012_hardened_malloc.py`, `tests/test_009_a15_reboot_fixups.py`, `tests/test_009_a15_small_ports.py`. - Host tree under `/srv/rom/src/lineage` is dirty with the malloc apply and the identity/kernel applies. Laptop scripts were rsynced to `/srv/rom/artifacts/bin/`. ## Docs hygiene (2026-10-10) Index refreshed: `docs/README.md`, `specs/README.md`, `docs/archive/README.md`. Upstream rebase / first OTA: `docs/009-upstream-rebase-ota.md`. Remaining roadmap: `docs/009-axp-graphene-remaining.md` (rewritten). Still treat as **historical** (banners added): all `009-fortify-*`, `009-cve-bisect-plan.md`, `009-lab-acceptance-20261002-*`, `009-user-zip-audit-20261007.md`. **Parallel (keep, not historical trash):** `007-*` + `docs/007-parallel-on-009.md` — ReSukiSU/SusFS retry on current Magisk ROM; never into Magisk ship bacon. Still polish when touching them: `009-hardening-signing-checklist.md` and `009-gate-g-kernel-attribution.md` mid-body tables may still show older `test-keys` / Oct-1 artifacts — prefer closure parity for measured LAB state. `009-version-pins.md` — microG / Magisk 30.7 / Phonesky OK; add upstream LOS pin when the next rebase starts.