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

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

No files matched your search

@@ -0,0 +1,41 @@
# Specification Quality Checklist: KernelSU-Next on sunfish (LAB)
**Purpose**: Validate specification completeness and quality before planning
**Created**: 2026-09-15
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Product names required by constitution (KernelSU-Next, SusFS, Magisk-as-non-default,
TrickyStore-class *experiment*) appear as **capability choices**, not code design.
- Checklist item “non-technical stakeholders”: banking PASS/FAIL and LAB-only
constraints are written for the owner; kernel revision pinning is an audit need.
- SC-002 “≥95% checklist rows” assumes a concrete verification checklist in
`/speckit-plan` / tasks — acceptable at specify stage.
- Ready for `/speckit-plan`. **Yuh PASS is a hard-gate** (owner 2026-09-15):
without it, root is not justified vs NeoBackup + native call-rec / FLAG_SECURE.
@@ -0,0 +1,39 @@
# Contract: Yuh hard-gate (banking)
**Feature**: `007-kernelsu-sunfish`
**Device**: LAB `11231JEC207477` only
## Hard-gate
| App | Profile | Required outcome to accept `007` |
|-----|---------|----------------------------------|
| Yuh (`com.yuh`) | Island (work user) | **PASS** — usable authenticated session |
| Swissquote | Island | **PASS** — usable authenticated session; does not waive Yuh |
| N26 / Revolut | any | Non-blocking |
## Preconditions for a valid Yuh PASS attempt
1. Build includes KernelSU-Next pin under test.
2. Yuh UID(s) have **root deny** + **verified** mount hide (`ksu-hide-surface.md`).
3. Install path prefers Aurora → do not open → Island clone → first launch in
Island (AXP-like); document deviations.
4. Attestation/SusFS experiments in use are listed with revisions.
## FAIL handling
- Capture `keystore2` / KeyMint / RKP / Yuh UI error (compare `002`).
- Iterate SusFS/attestation pins; do not mark feature done.
- Exhausted options → `007` **incomplete or cancelled**; prefer stock phone for
banks rather than shipping root without Yuh.
## PASS evidence package
- Build id + date
- Profile user id
- Stack pins (KSU, SusFS, modules)
- Short log excerpt showing absence of prior `HARDWARE_TYPE_UNAVAILABLE` class
*or* explicit note if a different success path applies
- Stored under `/srv/rom/artifacts/007-kernelsu/…`
US5 exclusively owns acceptance. Both banks must pass on the same build/stack;
failure of either keeps the feature incomplete or triggers withdrawal of root.
@@ -0,0 +1,40 @@
# Contract: KernelSU hide / umount surface
**Feature**: `007-kernelsu-sunfish`
**Consumers**: LAB validation (`quickstart.md`), future `011` signed builds
## Root grant
| Rule | Requirement |
|------|-------------|
| Default | No app has root until explicitly allowed |
| Banking | `com.yuh`, `com.swissquote.android` → **deny** on all tested `userId`s |
| Proof | Manager UI alone insufficient; show failed `su`/root API from those UIDs |
## Mount hide
| Rule | Requirement |
|------|-------------|
| Mechanism | KernelSU umount / profile hide (and SusFS when enabled) |
| Proof | From banking (or probe) UID, sensitive module/overlay paths that appear
to a normal rooted UID are **absent** or inaccessible |
| `path_umount` | Must work on this 4.14 integration or be explicitly filed as blocker |
## Non-goals
- Magisk DenyList semantics as the production contract
- LSPosed/Zygisk hide
- Claiming “legitimate system” without Yuh PASS (see `banking-yuh-gate.md`)
## Mandatory evidence checklist
For each banking package × tested user ID, record PASS/FAIL, method and artifact:
- root grant denied;
- denied root access demonstrated;
- module mount visibility before/after recorded;
- configured unmount mechanism actually removes the test mount.
All rows must PASS. A probe must reproduce the target policy and namespace;
a different UID with unrelated settings is not evidence for the banking UID.
Unavailable evidence is unverified, not PASS. Optional SUSFS checks apply only
when enabled and must identify their tested paths.
+65
View File
@@ -0,0 +1,65 @@
# Data model: 007 KernelSU / banking gate
Conceptual entities for validation and artifact tracking (not a database schema).
## KernelSU pin
| Field | Meaning |
|-------|---------|
| `project` | KernelSU-Next (or documented ReSukiSU fallback) |
| `revision` | Exact git tag or commit |
| `kernel_base` | LOS 23.2 sunfish-compatible 4.14 tree identity |
| `boot_build_id` | `ro.lineage.version` / display id of accepting image |
| `status` | `poc` → `pinned` → `withdrawn` |
## SusFS pin (optional until enabled)
| Field | Meaning |
|-------|---------|
| `enabled` | boolean on accepting build |
| `revision` | tag/commit if separate |
| `soak_hours` | observed soak before claim |
| `status` | `off` / `trial` / `claimed` / `reverted` |
## App profile (per package × userId)
| Field | Meaning |
|-------|---------|
| `package` | e.g. `com.yuh` |
| `user_id` | 0 owner, 10 Island, … |
| `root_grant` | MUST be `deny` for banking targets |
| `umount_or_hide` | `verified` / `unverified` / `failed` |
| `evidence_path` | artifact log/screenshot |
## Banking session result
| Field | Meaning |
|-------|---------|
| `app` | Yuh \| Swissquote |
| `profile` | Island / owner |
| `build_id` | ROM build under test |
| `stack` | KSU ± SusFS ± attestation modules (names + pins) |
| `outcome` | `PASS` \| `FAIL` |
| `fail_class` | e.g. KeyMint/`HARDWARE_TYPE_UNAVAILABLE`, UI, network |
| `log_refs` | paths under `/srv/rom/artifacts/007-…` |
| `date` | ISO date |
**Rule**: Feature acceptance requires one **Yuh** and one **Swissquote** row on the same build/stack with
`outcome=PASS` on LAB Island under root-denied + hide-verified stack.
## Attestation experiment run
| Field | Meaning |
|-------|---------|
| `modules_or_toggles` | TrickyStore-class + microG HA notes |
| `baseline_ref` | `002` Yuh log pack |
| `result_ref` | new log pack |
| `delta` | same error class / improved / resolved |
## State transitions (feature)
```text
ksu_poc → profiles_verified → susfs_optional → attestation_trial
→ both_banks_pass (GATE) → 007_accepted
↘ either_bank_fail_exhausted → 007_incomplete_or_cancelled
```
+110
View File
@@ -0,0 +1,110 @@
# Implementation Plan: KernelSU-Next on sunfish (LAB)
**Branch**: `007-kernelsu-sunfish` | **Date**: 2026-09-15 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/007-kernelsu-sunfish/spec.md`
## Summary
Bring **KernelSU-Next** into the LineageOS 23.2 sunfish **4.14** kernel on LAB,
verify per-app / per-user **root denial + mount hide** for banking UIDs, then
layer **SusFS** and a **TrickyStore-class** attestation experiment so that
**Yuh PASS** (Island) becomes achievable. **Yuh PASS is a hard-gate**: without
it, `007` is incomplete/cancelled — root is not justified vs NeoBackup + native
`008`/`009` and a stock banking phone.
`006` rootless-Yuh-pass is **deferred** and does not block start. Swissquote PASS is also mandatory; Revolut/N26 non-blocking. GOLDEN never flashed.
## Technical Context
**Language/Version**: Linux 4.14 kernel (C); KernelSU-Next / SusFS integration;
Android userspace manager APK; bash runbooks on `rom-dev01`
**Primary Dependencies**: LOS 23.2 sunfish kernel tree; KernelSU-Next (non-GKI
4.14-capable pin); SusFS; TrickyStore-class (or documented equivalent); `005`
userspace stack; Island; `002` Yuh/KeyMint logs
**Storage**: Host `/srv/rom/` kernel outs, module ZIPs, secrets; artifacts under
`/srv/rom/artifacts/007-…`
**Testing**: LAB flash only; KSU manager grants; mount/root probes per UID;
Yuh/Swissquote Island sessions; `keystore2`/KeyMint logcat vs `002`
**Target Platform**: Pixel 4a LAB `11231JEC207477`; Android 16 / LOS 23.2
**Project Type**: Android ROM kernel + root stack + LAB validation
**Performance Goals**: Boot + daily stability; SusFS soak ≥24h if claimed
**Constraints**: LAB only; no Magisk production; no Zygisk/LSPosed default;
banking never gets root; attributable kernel commits; Yuh PASS mandatory
**Scale/Scope**: One kernel integration POC → pin revision → SusFS →
attestation experiment → banking hard-gate on LAB
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Gate | Status |
|------|--------|
| LAB only; never GOLDEN | pass |
| KernelSU-Next is project root (not Magisk production) | pass |
| Banking apps never receive root; profiles + verified umount | pass |
| SusFS only after KSU + profiles work | pass (phased US1→US3) |
| No Zygisk/LSPosed as initial architecture | pass |
| Small attributable, reversible changes | pass (pinned commits) |
| `006` before `007` in written order | **amended explicitly in constitution 0.2.0** — rootless Yuh gate deferred; owner-approved sequencing; current-ROM snapshot required (T039) |
| Hardening Graphene/AXP full ports | out of scope → `013` |
**Post-design**: Same. Yuh hard-gate is an owner product gate layered on top of
constitution Compatibility MVP (Yuh in Insular) — aligned, stricter on `007`
acceptance.
## Project Structure
### Documentation (this feature)
```text
specs/007-kernelsu-sunfish/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│ ├── ksu-hide-surface.md
│ └── banking-yuh-gate.md
└── tasks.md # via /speckit-tasks (not this command)
```
### Host + tree
```text
# rom-dev01
/srv/rom/src/lineage/kernel/… # LOS 23.2 sunfish-compatible kernel
/srv/rom/src/lineage/… # product builds including boot.img
/srv/rom/artifacts/007-kernelsu/ # bacon outs, pins, Yuh log packs
/srv/rom/references/… # optional mirrors of KSU/SusFS/TrickyStore docs
# Meta repo
docs/002-*-*.md # Yuh/KeyMint baselines (read-only input)
docs/reference-sources.md §8–10 # community inspiration, not base
docs/a15-a16-delta.md # attestation notes as measured
```
**Structure Decision**: Kernel work lives on `rom-dev01` LOS tree; meta-repo
keeps specs, contracts, runbooks, and pin records. No Magisk tree. No megapatch
dumps in Git — pin URLs/commits + small project patches only.
## Complexity Tracking
| Violation / stretch | Why needed | Simpler alternative rejected because |
|---------------------|------------|--------------------------------------|
| Start `007` without closing `006` rootless Yuh | `002` shows Yuh fails with and without Magisk (KeyMint/RKP) | Waiting on rootless Yuh green has no known path |
| SusFS + TrickyStore-class in same feature as KSU | Owner: Yuh PASS mandatory; hide alone insufficient on GOLDEN | KSU-only “done” without Yuh → root not worth keeping |
| Yuh PASS hard-gate on EOL sunfish | Product rationale: else stock phone + `008`/`009` | Soft FAIL documentation wastes a root maintenance burden |
## Phase 0 / Phase 1
See `research.md`, `data-model.md`, `contracts/*`, `quickstart.md`.
## Remediation alignment — 2026-09-15
Constitution 0.2.0 explicitly defers `006`; T039 records our current rootless
LAB state before kernel changes, without requiring PASS. US5 alone owns banking
acceptance: both Yuh and Swissquote must pass on the same stack. US4 owns
attestation investigation/evidence, not a duplicate acceptance gate. Older
iodé/GOLDEN KeyMint logs are correlations, not proof of our ROM's failure cause.
T040 explicitly verifies the no-Zygisk/LSPosed constraint.
+64
View File
@@ -0,0 +1,64 @@
# Quickstart: 007 KernelSU + Yuh gate (LAB only)
**Device**: LAB `11231JEC207477` — never GOLDEN `11071JEC203839`
## Goal
Prove selective root + verified hide, then **Yuh and Swissquote PASS** in Island. Without both banks
passing, do not declare `007` done.
## Prerequisites
- Working `005` userspace stack on LAB (microG + Phonesky + spoofing)
- `007` boot image with pinned KernelSU-Next
- Island installed; Aurora available
- Baseline reading: `docs/002-golden-inventory.md`, `docs/002-lab-iodes-baseline.md`
## 1. Flash LAB
Use `docs/003-flash-lab.md` with the `007` artifact. Confirm:
```bash
SERIAL=11231JEC207477
adb -s "$SERIAL" shell getprop ro.lineage.version
# KernelSU manager present; grant root to one debug app only
```
## 2. Hide surface
1. Deny root for `com.yuh` and `com.swissquote.android` (all relevant users).
2. Enable umount/hide for those UIDs.
3. **Verify mounts** from a probe — see `contracts/ksu-hide-surface.md`.
## 3. SusFS (after step 2 green)
Enable SusFS per pin; confirm boot; re-check hide. Soak before claiming.
## 4. Attestation experiment
Apply TrickyStore-class (or equivalent) + any microG HA toggles under test.
Capture logcat around Yuh open (`keystore2`, KeyMint, RKP).
## 5. Banking (Island)
1. Aurora install Yuh/Swissquote → do not open on owner if following AXP order.
2. Clone into Island; first launch in Island.
3. Swissquote: must PASS a usable authenticated session.
4. Yuh: **must PASS** for feature acceptance (`contracts/banking-yuh-gate.md`).
## Pass criteria
- [ ] KSU selective root works
- [ ] Banking UIDs: root deny + verified hide
- [ ] SusFS claimed only if stable
- [ ] **Yuh PASS** in Island with evidence under `/srv/rom/artifacts/007-…`
- [ ] Swissquote PASS on the same stack
- [ ] No Magisk production image
## Failure
If either bank remains unusable after reasonable SusFS/attestation
iterations: stop, keep artifacts, mark `007` blocked — consider stock phone for
banks; do not ship “root without Yuh” as success.
Before any rooted flash, complete T039. Before acceptance complete T040.
+106
View File
@@ -0,0 +1,106 @@
# Research: 007 KernelSU-Next on sunfish
## Decision: Defer `006` rootless-Yuh gate; start `007` now
**Decision**: Do not block on a separate `006` “Yuh green without root”. Absorb
banking regression into `007`. A rootless snapshot on the current `005` LAB image is required before root;
its PASS/FAIL outcome is informational and does not block experiments.
**Rationale**: GOLDEN (Magisk) and LAB iodé (no Magisk, locked BL) both show Yuh
KeyMint/`HARDWARE_TYPE_UNAVAILABLE`. Rootless is not a known fix.
**Alternatives**: Force `006` first — rejected. Cancel banking on ROM entirely
before trying KSU stack — premature; try `007` experiment first.
## Decision: Yuh PASS is mandatory to accept `007`
**Decision**: Feature closes only when both Yuh and Swissquote work in Island on LAB under
root-denied + verified hide (+ SusFS/attestation stack as needed). Honest
residual FAIL ⇒ `007` incomplete or cancelled — not “KSU done, Yuh later”.
**Rationale**: Owner (2026-09-15): without Yuh, root adds little vs NeoBackup +
native call recording / FLAG_SECURE; denylist-style legitimacy alone is not
enough reason to carry KSU. Stock handset remains interim fallback, not
acceptance.
**Alternatives**: Soft gate / document FAIL — rejected by owner.
## Decision: Prefer ReSukiSU + TEESimulator for hard-bank PoC (2026-09-15)
**Decision**: Align LAB banking experiments with torukk/abu field results:
ReSukiSU over KernelSU-Next when Revolut-class detection matters; **TEESimulator-RS**
instead of TrickyStore; document Zygisk Next + PIF inject as possible LAB-only
exception if required for the Yuh/Swissquote gate.
**Rationale**: Owner overlap with that project; XDA 2026-08-22; constitution
already names ReSukiSU as evaluable fork.
**Alternatives**: KernelSU-Next-only in-tree first — still useful as build
practice, weaker evidence for hard banks.
## Decision: Profiles + verified umount before SusFS
**Decision**: Order: (1) KSU boots + selective root, (2) banking UIDs denied +
**mount evidence** of hide/`path_umount`, (3) SusFS, (4) attestation modules.
**Rationale**: Constitution: SusFS only after KernelSU and application profiles
work. GUI toggle alone is insufficient.
## Decision: TrickyStore-class → prefer TEESimulator-RS
**Decision**: Attestation experiment track prefers **TEESimulator-RS** (TrickyStore
compatible drop-in) per owner + torukk; select banking packages only.
**Rationale**: Community recommendation over original TrickyStore; same slot in
the stack.
## Decision: Island remains managed-profile vehicle
**Decision**: Keep Island (already on LAB/GOLDEN) for Yuh/Swissquote unless
planning discovers a blocking incompatibility; then document substitute.
**Rationale**: Matches AXP oracle workflow and existing LAB user 10.
## Decision: No Zygisk/LSPosed in initial `007`
**Decision**: Out of default scope. Prefer native ROM features for call-rec /
FLAG_SECURE later (`008`/`009`).
**Rationale**: Constitution.
## Decision: Full Graphene/AXP kernel hardening stays `013`
**Decision**: `007` only patches kernel as required for KSU / SusFS / umount.
Do not import broad hardening series here.
**Rationale**: Constitution progress order; reduces blast radius while chasing Yuh.
## Remediation alignment — 2026-09-15
Constitution 0.2.0 explicitly defers `006`; T039 records our current rootless
LAB state before kernel changes, without requiring PASS. US5 alone owns banking
acceptance: both Yuh and Swissquote must pass on the same stack. US4 owns
attestation investigation/evidence, not a duplicate acceptance gate. Older
iodé/GOLDEN KeyMint logs are correlations, not proof of our ROM's failure cause.
T040 explicitly verifies the no-Zygisk/LSPosed constraint.
## Concrete attestation candidates (not yet selected or validated)
- TrickyStore: https://github.com/5ec1cff/TrickyStore — certificate-chain
intervention; current releases closed-source. Record auditability limitations.
- TEESimulator: https://github.com/JingMatrix/TEESimulator — open-source
software KeyMint/key-attestation simulation; candidate alternative, not
authentic hardware repair. Requires external signing material not bundled.
- TEESimulator-RS: https://github.com/Enginex0/TEESimulator-RS — related
alternative; independently verify implementation, dependencies and A16 support.
- BootloaderSpoofer: https://modules.lsposed.org/module/es.chiteroman.bootloaderspoofer/
— LSPosed/Xposed approach, outside FR-009 default; not an approved candidate
without a separate explicit scope decision.
T022 selects one concrete candidate before deployment: upstream URL, immutable
commit or release with binary hash, license/source availability, dependencies,
key-material provenance/availability and rollback. Do not collect keys from
unknown sources or commit signing secrets. Evaluate candidates separately, not
as a combined stack. No candidate is verified for Yuh on our sunfish yet.
KernelSU/SUSFS and Play Integrity modules are not interchangeable substitutes
for Key Attestation. A simulator does not itself create a trusted signing chain.
+269
View File
@@ -0,0 +1,269 @@
# Feature Specification: KernelSU-Next on sunfish (LAB)
**Feature Branch**: `007-kernelsu-sunfish`
**Created**: 2026-09-15
**Status**: In progress (LAB)
**Session handoff**: `docs/session-20260916-handoff.md` (2026-09-16)
**Input**: After `005` first Google-compat stack works on LAB, skip forcing a
rootless Yuh green gate. Prioritize **ReSukiSU** (not Magisk; KSU-Next only as
history) on the LineageOS 23.2 sunfish kernel, verified hide for banking UIDs,
then SusFS / TEESimulator-class LAB experiments aimed at Yuh KeyMint/RKP
failures already logged in `002`. LAB only; never GOLDEN. Personal stock
handset for banks remains an optional operator fallback outside this feature.
**Spine reminder:** product path is **our** LOS 23.2 (`003`→`004`/`005` bacon)
then `007`. Community abu/torukk ROMs and Downloads boots are reference only.
## Context / sequencing vs `006`
Constitution originally ordered a **rootless** banking baseline (`006`) before
root (`007`). Evidence already shows:
| Device | Stack | Swissquote | Yuh |
|--------|-------|------------|-----|
| GOLDEN | AXP + Magisk DenyList | PASS (owner) | FAIL — HA / “certificate invalid”; KeyMint/`HARDWARE_TYPE_UNAVAILABLE` |
| LAB (iodé A16) | No Magisk; BL locked | — | FAIL — same KeyMint/RKP class |
So a “rootless Yuh must pass” gate is **not** a credible start condition.
This feature **absorbs** the banking regression that `006` would have owned:
measure owner + Island UIDs on **our** ROM with root hidden. A separate `006`
spec may stay deferred or become a thin historical note — it must not block
`007` work.
**Explicitly later (do not pull into this feature):** call recording (`008`),
`FLAG_SECURE` (`009`), AXP UX leftovers (`010`), project signing/AVB (`011`),
incremental Graphene/AXP/Divest **hardening** ports (`012`–`013`).
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Bootable rooted LAB image (Priority: P1)
As the developer, I can flash a LAB build whose kernel includes KernelSU-Next
compatible with non-GKI Linux 4.14 / sunfish, boot to the lock screen, and
confirm root is available only through the KernelSU manager to apps I approve.
**Why this priority**: Without a working integrated root path, hide/SusFS/banking
experiments cannot run on *our* ROM.
**Independent Test**: Flash LAB only; manager shows installed; `su` works for one
approved test app and fails for an unapproved app.
**Acceptance Scenarios**:
1. **Given** a `007` LAB flash, **When** the device boots, **Then** telephony,
Wi‑Fi, and basic UI work at least as well as the last `005` image.
2. **Given** KernelSU manager, **When** root is granted to a single debug app,
**Then** that app can obtain root and an unapproved app cannot.
3. **Given** documentation, **When** reviewed, **Then** the exact KernelSU-Next
revision (tag/commit) used for the accepted POC is recorded for reproducibility.
---
### User Story 2 - Banking apps never get root; mounts hidden (Priority: P1)
As the developer, Yuh and Swissquote (owner and Island/work profile UIDs) are
configured so they **never** receive root, and module/overlay mounts that would
expose root or custom ROM fingerprints to those UIDs are removed or hidden —
verified by a real check, not only a UI toggle.
**Why this priority**: Constitution root architecture; Magisk DenyList on GOLDEN
is oracle-only, not our production model.
**Independent Test**: Per-UID checks (process view of mounts / root binaries)
for banking packages on user 0 and work profile; screenshots/logs stored under
artifacts.
**Acceptance Scenarios**:
1. **Given** Yuh and Swissquote installed (Aurora → Island workflow preferred),
**When** root grant lists are reviewed, **Then** those packages are denied
root on every relevant user ID.
2. **Given** a module or overlay that would be visible to a normal app,
**When** the banking UID is inspected, **Then** that mount is absent or
otherwise hidden per the verified umount/profile mechanism.
3. **Given** only a manager “hide” toggle without mount evidence, **When**
validation runs, **Then** the story is **not** marked pass.
---
### User Story 3 - SusFS after profiles work (Priority: P2)
As the developer, once KernelSU profiles and verified hide work, I can enable a
SusFS-capable kernel/config on LAB and confirm the device still boots and that
selected path-hiding behaviours are measurable for banking UIDs.
**Why this priority**: Needed for hard banks on community sunfish reports; must
not destabilize before basic KSU works. Constitution: SusFS only after KernelSU
and application profiles work.
**Independent Test**: LAB boot + documented SusFS enablement + before/after
visibility check for at least one sensitive path from a banking or probe UID.
**Acceptance Scenarios**:
1. **Given** US1–US2 green, **When** SusFS is enabled on LAB, **Then** the
device boots and KernelSU manager still functions.
2. **Given** SusFS on, **When** a probe from a denied banking UID runs,
**Then** at least one previously visible root/custom indicator is hidden
(evidence logged).
3. **Given** SusFS causes repeated spontaneous reboot or severe thermal
instability, **When** triage completes, **Then** SusFS is reverted or pinned
to a known-good revision before continuing banking claims.
---
### User Story 4 - Attestation / KeyMint experiment track (Priority: P1)
As the developer, I can run a **LAB-only** attestation-compatibility experiment
(TrickyStore-class or equivalent, plus any required microG hardware-attestation
toggles) aimed at the Yuh failure mode already captured in `002` (KeyMint /
`HARDWARE_TYPE_UNAVAILABLE` / “certificate invalid”), without modifying GOLDEN.
**Why this priority**: Root hide alone did not fix Yuh on GOLDEN or iodé LAB;
attestation is the open hypothesis. **Yuh PASS is mandatory** for feature
acceptance — otherwise root is not worth carrying vs NeoBackup + native
`008`/`009` and a stock banking phone.
**Independent Test**: Reproduce Yuh launch with logcat focused on `keystore2` /
KeyMint / RKP; compare to `002` baselines; diagnostic results required with artifact paths; US5 owns PASS.
**Acceptance Scenarios**:
1. **Given** `002` Yuh failure signatures, **When** the experiment stack is
applied on LAB, **Then** a new log capture exists that either shows the same
class of error or a clear change.
2. **Given** a candidate experiment, **When** the same attestation probe and
bank attempt are repeated, **Then** record the before/after result, limitations
and rollback outcome. US4 owns diagnostic evidence, not banking acceptance.
3. **Given** persistent KeyMint/RKP messages, **When** results are interpreted,
**Then** do not infer causality or failure from those messages alone. US5
exclusively owns the end-to-end banking acceptance decision.
---
### User Story 5 - Banking regression on our ROM (Priority: P1)
As the project owner, after hide (and any accepted SusFS/attestation experiments)
I have a written regression for **Swissquote** and **Yuh** inside Island on the
`007` LAB image: install path, profile UIDs, biometrics if used, and outcome.
Revolut/N26 remain non-blocking.
**Why this priority**: Compatibility hard-gates; replaces the deferred `006`
oracle for “does banking work on our stack”.
**Independent Test**: End-to-end on LAB only; evidence under
`/srv/rom/artifacts/007-…` (and optional laptop rsync). No GOLDEN flash/wipe.
**Acceptance Scenarios**:
1. **Given** Island (or documented equivalent), **When** Swissquote is used in
the work profile with root denied + hide verified, **Then** Swissquote MUST PASS with a usable authenticated session, date and build id.
2. **Given** the same setup for Yuh, **When** login/attestation is attempted,
**Then** the session MUST **PASS**; an unusable session means
`007` is not accepted.
3. **Given** Magisk, **When** proposed as production root, **Then** it is
rejected; Magisk A/B diagnostic builds are allowed only as temporary
reference per constitution.
---
### Edge Cases
- KernelSU-Next revision incompatible with 4.14 → evaluate alternate pin /
ReSukiSU only as documented POC fork, not silent default change.
- Work-profile UIDs differ from owner → hide/root denial must be tested on both.
- `path_umount` missing/broken on 4.14 → story 2 fails until backport/verify.
- Attestation modules break Play/microg → revert experiment; keep iterating
until both banks PASS or declare `007` blocked/cancelled.
- Operator chooses a separate stock phone for banks → interim fallback only;
does **not** satisfy the Yuh hard-gate on LAB.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: Project MUST integrate KernelSU-Next into the LineageOS
23.2–compatible sunfish kernel built with the ROM (not Magisk as production
root).
- **FR-002**: Root MUST be grantable only to explicitly approved apps; banking
packages (at least Yuh and Swissquote) MUST never receive root on owner or
work-profile user IDs used in the regression.
- **FR-003**: Module/overlay mounts MUST be removable or hidden from selected
app processes, with verification beyond manager UI toggles; `path_umount` (or
equivalent) support on this kernel MUST be confirmed or explicitly failed.
- **FR-004**: The accepted KernelSU-Next revision MUST be pinned and recorded
(tag/commit) for reproducible builds.
- **FR-005**: SusFS MUST only be enabled after FR-001–FR-003 work on LAB; if
enabled, boot stability and at least one measurable hide effect MUST be
evidenced.
- **FR-006**: Evaluate an attestation candidate with exact source URL, immutable
revision or release plus binary hash, dependencies, auditability, baseline,
before/after evidence and rollback. KeyMint/RKP causality remains a hypothesis.
Banking acceptance is owned solely by FR-007 / US5.
- **FR-007**: Both Yuh and Swissquote MUST PASS usable authenticated sessions in
the LAB managed profile on the same accepted stack with root denied and hide
verified. Failure of either bank leaves `007` incomplete or cancelled.
N26/Revolut are non-blocking.
- **FR-008**: All flashing, kernel experiments, and attestation modules MUST
target LAB (`11231JEC207477`) only; GOLDEN MUST remain read-only oracle.
- **FR-009**: Zygisk/LSPosed MUST NOT be introduced as the initial architecture
unless a later feature proves no native alternative (out of default `007`
scope).
- **FR-010**: Feature docs MUST state that deferred `006` rootless-Yuh-pass is
not a prerequisite, and must link `002` Yuh/Swissquote evidence paths.
### Key Entities
- **LAB device**: Experimental sunfish; only flash target for `007`.
- **KernelSU profile**: Per-app (and per-user) root grant / umount policy.
- **Banking target apps**: Yuh (`com.yuh`), Swissquote (`com.swissquote.android`).
- **Managed profile**: Island (or equivalent) work user hosting banking apps.
- **Attestation experiment stack**: Optional LAB modules/toggles aimed at
hardware attestation / KeyMint behaviour.
- **Pinned root revision**: Exact KernelSU-Next (and SusFS, if used) identifiers.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: LAB boots a `007` image with working selective root within one
flash cycle after the accepted kernel build.
- **SC-002**: For Yuh and Swissquote on every tested user ID, root grant is
denied and mount-hide is evidenced (not toggle-only) for every applicable contract checklist row, for both packages and every tested user ID; no failed or unverified mandatory row is allowed.
- **SC-003**: **Yuh PASS** on LAB Island under the `007` stack (root denied +
verified hide + accepted SusFS/attestation experiments), with build id and
evidence — required to close the feature.
- **SC-004**: Swissquote MUST PASS a usable authenticated session on the same
image/stack as SC-003, with dated evidence; both are required for acceptance.
- **SC-005**: If SusFS is claimed in the release notes for this phase, LAB
completes ≥24h soak without SusFS-driven reboot loops, or SusFS is withdrawn
from the claim.
- **SC-006**: Artifact package contains before/after attestation probe results
and correlated banking logs, including unresolved messages and limitations.
Absence of a log string alone is not proof of successful attestation.
- **SC-007**: No Magisk-based production image is published as the project
default root path.
## Assumptions
- `005` stack (microG + patched Phonesky + restricted spoofing) remains the
userspace base on LAB before/while bringing up `007`.
- Island (already used on LAB/GOLDEN) remains the managed-profile vehicle unless
a documented substitute is chosen during implementation planning.
- If EOL sunfish cannot satisfy Yuh even with SusFS/TrickyStore-class stacks,
**`007` stays incomplete** (or is explicitly cancelled) — not “done with Yuh
documented FAIL”. Rationale: without Yuh, root adds little over NeoBackup +
native `008`/`009`; a stock handset becomes the banking plan instead.
- Operator may still use a separate stock phone as interim fallback; that does
not count as `007` acceptance.
- Full GrapheneOS/AXP/Divest kernel hardening ports remain `013`, not this
feature — `007` only changes the kernel as needed for KSU/SusFS/umount.
- Community sunfish LOS+KSU+SusFS reports are inspiration, not a drop-in base.
## Out of scope
- Flashing or modifying GOLDEN.
- Magisk/Magia as default project root.
- Making Revolut/N26 hard-gates.
- Call recording, FLAG_SECURE, WebView provider work, project AVB lock.
- Purchasing or provisioning a second physical phone (operator choice).
+252
View File
@@ -0,0 +1,252 @@
# Tasks: KernelSU-Next on sunfish (LAB) + Yuh/Swissquote gate
**Input**: Design docs from `/specs/007-kernelsu-sunfish/`
**Prerequisites**: `005` stack on LAB; `002` Yuh/KeyMint baselines; constitution
KernelSU-Next (not Magisk production)
**Organization**: Priority = **Swissquote + Yuh** on LAB. KSU/SusFS/TrickyStore
exist to serve that gate. If the gate cannot be met after the experiment track,
**cancel root** and pivot to native `008`/`009` (+ optional stock phone) — do
not ship “root without Yuh” as success.
**Out of scope**: GOLDEN flash; Magisk production; Revolut/N26 hard-gates;
full Graphene/AXP kernel hardening (`013`).
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no incomplete deps)
- **[Story]**: US1…US5 from `spec.md`
## Path conventions
- Meta: `docs/`, `specs/007-kernelsu-sunfish/`
- Host: `/srv/rom/src/lineage/` (kernel + boot), `/srv/rom/artifacts/007-kernelsu/`,
`/srv/rom/logs/007-build/`
---
## Phase 1: Setup
**Purpose**: Artifact dirs, baseline index, pin stubs
- [x] T001 Create `/srv/rom/artifacts/007-kernelsu/` and
`/srv/rom/logs/007-build/` on `rom-dev01` (android-build writable)
- [x] T002 [P] Add `docs/007-kernelsu-runbook.md` stub (LAB-only; pin table;
Yuh hard-gate; cancel-root criteria) in meta repo
- [x] T003 [P] Index `002` Yuh evidence paths in
`docs/007-kernelsu-runbook.md` (GOLDEN + LAB iodé KeyMint refs from
`docs/002-golden-inventory.md` / `docs/002-lab-iodes-baseline.md`)
- [x] T004 [P] Confirm LAB still on `005` userspace
(`pm path` gms/gsf/vending; spoof toggle) — note build id in
`/srv/rom/artifacts/007-kernelsu/preflight.txt`
- [x] T039 Before T009/T011, capture a rootless snapshot of the current LAB ROM:
both bank versions/outcomes, build type, microG/Phonesky versions and
attestation probe/logs under `pre-root/`. FAIL is allowed; record actual
results rather than inferring them from iodé/GOLDEN. Document Island as
the current managed-profile vehicle in `docs/007-kernelsu-runbook.md`.
*(2026-09-15: banks not installed → N/A; see pre-root/OUTCOMES.txt)*
---
## Phase 2: Foundational (blocks all stories)
**Purpose**: Choose 4.14-capable KernelSU-Next revision; locate LOS kernel tree;
no banking claims yet
**⚠️ CRITICAL**: No SusFS/attestation/Yuh PASS claims until KSU boots on LAB
- [x] T005 Inventory LOS 23.2 sunfish kernel path on
`/srv/rom/src/lineage/` (defconfig, branch); record in
`docs/007-kernelsu-runbook.md`
*(`kernel/google/msm-4.14` @ `28f9290ae067…`; sunfish_defconfig)*
- [x] T006 Select KernelSU-Next revision compatible with non-GKI 4.14; document
candidates + choice in `docs/007-kernelsu-runbook.md` (ReSukiSU only as
explicit fallback)
*(`legacy` branch; manual hooks preferred over kprobes)*
- [x] T007 Mirror/checkout chosen KernelSU-Next sources under
`/srv/rom/references/kernelsu-next/` (or documented path); record commit
*(@ `a54e4fa46c6c…`)*
- [x] T008 Draft integration notes (what files touch kernel vs boot.img) in
`docs/007-kernelsu-runbook.md` — attributable commits only, no megapatch
**Checkpoint**: Ready to integrate and build boot (US1)
---
## Phase 3: User Story 1 — Bootable rooted LAB image (P1) 🎯 MVP slice
**Goal**: LAB boots with KernelSU-Next; selective root works
**Independent test**: Manager present; one approved app gets root; unapproved
does not; telephony/Wi‑Fi OK
- [ ] T009 [US1] Integrate KernelSU-Next into sunfish kernel tree under
`/srv/rom/src/lineage/`; build boot/kernel; log
`/srv/rom/logs/007-build/ksu-poc.log`
- [ ] T010 [US1] Stage boot/images + SHA256 to
`/srv/rom/artifacts/007-kernelsu/<date>-ksu-poc/`
- [ ] T011 [US1] Flash LAB only (`11231JEC207477`); confirm boot +
`ro.lineage.version`; install/open KSU manager
- [ ] T012 [US1] Grant root to one debug app; deny a second; capture evidence
under `/srv/rom/artifacts/007-kernelsu/<date>-ksu-poc/root-grant/`
- [ ] T013 [US1] Pin exact KernelSU-Next revision in
`docs/007-kernelsu-runbook.md` + artifact `PIN.txt`
**Checkpoint**: US1 green before profiles/SusFS
---
## Phase 4: User Story 2 — Banking never root; mounts hidden (P1)
**Goal**: Yuh/Swissquote UIDs denied + **verified** umount/hide
**Independent test**: `contracts/ksu-hide-surface.md` — not toggle-only
- [ ] T014 [US2] Configure KSU profiles: deny root for `com.yuh` and
`com.swissquote.android` on user 0 and Island user; document steps in
`docs/007-kernelsu-runbook.md`
- [ ] T015 [US2] Enable umount/hide for those UIDs; verify `path_umount` (or
equivalent) works on this 4.14 build — note pass/fail in
`/srv/rom/artifacts/007-kernelsu/<date>-hide/umount.txt`
- [ ] T016 [US2] From banking or probe UID, capture mount/root visibility
before/after hide →
`/srv/rom/artifacts/007-kernelsu/<date>-hide/mounts/`
- [ ] T017 [US2] Mark `contracts/ksu-hide-surface.md` checklist rows against
real evidence (update runbook if contract gaps)
**Checkpoint**: Hide verified before SusFS
---
## Phase 5: User Story 3 — SusFS after profiles (P2)
**Goal**: SusFS on LAB; measurable hide; no reboot loop
**Independent test**: Boot + one path hidden; soak before claim
**Note (2026-09-16):** T018 **build** completed early (API bridge) *before* US2
hide verification — process exception. Boot artifact
`boot-resukisu-susfs-20260916T004038Z.img` is **trial only**. Prefer LAB on
`boot-resukisu-our-20260915T183729Z` until US2 green; then re-attempt T019.
abu/torukk boots are reference-only — see `docs/session-20260916-handoff.md`.
- [x] T018 [US3] Integrate SusFS into the pinned kernel path; build; log
(host detach SusFS boot 20260916T004038Z; sha `455a77a6…`)
- [ ] T019 [US3] Flash LAB; confirm boot + KSU still works; record SusFS pin in
`docs/007-kernelsu-runbook.md`
- [ ] T020 [US3] Re-verify banking UID hide with SusFS on → artifact
`/srv/rom/artifacts/007-kernelsu/<date>-susfs/`
- [ ] T021 [US3] Soak ≥24h or document revert if unstable (SC-005); update
SusFS status `trial`/`claimed`/`reverted` in runbook
**Checkpoint**: SusFS stable or withdrawn before attestation claims that depend
on it
---
## Phase 6: User Story 4 — Attestation / KeyMint experiment (P1)
**Goal**: TrickyStore-class (or equiv.) vs `002` Yuh KeyMint failure
**Independent test**: New log pack; progress toward Yuh PASS
- [ ] T022 [US4] Choose attestation experiment stack (TrickyStore-class or
documented equivalent + microG HA toggles); record source URL, immutable commit or release and binary SHA256, dependencies, key-material requirements, auditability and rollback in
`docs/007-kernelsu-runbook.md` **before T023**
- [ ] T023 [US4] Apply stack on LAB; capture `keystore2`/KeyMint/RKP logcat on
Yuh open → `/srv/rom/artifacts/007-kernelsu/<date>-attest/`
- [ ] T024 [US4] Diff against `002` failure class; write short delta note in
artifact `DELTA.md` (same / improved / resolved)
- [ ] T025 [US4] Iterate one candidate at a time based on measured probe/banking outcomes; do not use a log string alone as the failure criterion; keep each attempt under dated artifact dirs — do
not mark feature done on FAIL
**Checkpoint**: Diagnostic evidence ready for US5; persistent log messages
alone do not determine acceptance. Exhausted unsuccessful bank attempts lead
to Phase 9 or an incomplete feature.
---
## Phase 7: User Story 5 — Banking regression / hard-gate (P1)
**Goal**: **Yuh and Swissquote PASS** in Island
**Independent test**: `contracts/banking-yuh-gate.md` + `quickstart.md`
- [ ] T026 [US5] Install path: Aurora → (prefer no owner open) → Island clone
for Yuh + Swissquote; note UIDs in
`/srv/rom/artifacts/007-kernelsu/<date>-banking/layout.txt`
- [ ] T027 [US5] Swissquote Island session → **PASS required** + evidence under
`…/<date>-banking/swissquote/`
- [ ] T028 [US5] Yuh Island session → **PASS required**; evidence under
`…/<date>-banking/yuh/` (build id, stack pins, log excerpt)
- [ ] T040 Before T029 acceptance, verify FR-009: installed packages, root
module inventory, relevant processes/mounts and build configuration show
no Zygisk/LSPosed integration. Store evidence; a package-name check alone
is insufficient. Any proposed exception requires a spec decision first.
- [ ] T029 [US5] If both banks PASS: fill `data-model.md` banking row + tick
`specs/007-kernelsu-sunfish/quickstart.md` pass criteria
- [ ] T030 [US5] If either bank FAILS after T022–T025 exhausted: do **not** accept
`007`; proceed to Phase 9 cancel-root tasks
**Checkpoint**: Feature accepted only with both banks PASS
---
## Phase 8: Polish (only if both banks PASS)
- [ ] T031 [P] Update `docs/axp-pro-parity.md` root / DenyList / Yuh / Swissquote
rows to reflect KSU-Next + LAB results
- [ ] T032 [P] Update `docs/a15-a16-delta.md` attestation/`007` measured notes
- [ ] T033 Handoff note in `docs/007-kernelsu-runbook.md`: next may be `008`
call recording / `009` FLAG_SECURE; full hardening still `012`–`013`
- [ ] T034 Mark deferred `006` as superseded-by-`007` (or thin stub) in
`specs/` / roadmap note — no fake rootless Yuh success
---
## Phase 9: Cancel-root pivot (only if either banking hard-gate fails)
**Purpose**: Owner priority — without Yuh/Swissquote success, discard project
root and keep native requirements instead
- [ ] T035 Write `/srv/rom/artifacts/007-kernelsu/CANCEL-ROOT.md` (attempts,
last pins, KeyMint residual, recommendation: stock phone for banks)
- [ ] T036 Update `docs/007-kernelsu-runbook.md` + `docs/axp-pro-parity.md`:
root path **withdrawn**; Magisk/KSU not production
- [ ] T037 [P] Stub or specify next focus: `008` call recording + `009`
FLAG_SECURE (native, no LSPosed) — Spec Kit when owner starts them
- [ ] T038 Leave LAB on last known-good **non-root** (`005`) image or document
re-flash steps in runbook
---
## Dependencies
```text
Setup T001–T004 + T039
→ Foundational T005–T008
→ US1 T009–T013 (KSU boot)
→ US2 T014–T017 (hide)
→ US3 T018–T021 (SusFS)
→ US4 T022–T025 (attest)
→ US5 T026–T030 + T040 (both-bank gate)
↘ PASS → Polish T031–T034
↘ FAIL → Cancel-root T035–T038
```
- US3 may be skipped only if US4/US5 PASS without SusFS (document why)
- US4/US5 are the product priority; US1–US2 are enablers
## Parallel opportunities
- T002, T003, T004 after T001
- T031, T032 after both banks PASS
- T037 anytime during cancel-root phase
## MVP
**Minimum useful slice**: T001–T013 (KSU boots on LAB).
**Product MVP**: T027 Swissquote PASS and T028 Yuh PASS on the same stack.
Either unresolved failure → Phase 9 or remain incomplete, never “007 done”.
## Suggested next command after tasks
`/speckit-analyze` (optional) → `/speckit-implement` starting at T001 on
`rom-dev01` (kernel work is host-side; LAB flash when boot ready).