feat(controller): rootfs integrity verification (iiab-tree-sha256-v1) + device-backup manifest#37
Merged
Conversation
Part 2 of the rootfs import/restore validation series (follow-up to #31). - deploy/domain/RootfsTreeHash: pure-JVM treehash (norm + per-member digest + order-independent domain-separated combine), byte-parity with tools/iiab_tree_hash.py. Streaming Accumulator for single-pass tar. - deploy/data/RootfsIntegrity: one-pass, dependency-free tar reader (ustar + GNU long-name + pax path/linkpath) that recomputes the treehash (excluding the integrity member) and reads the integrity declaration -> ABSENT / DECLARED_NONE / MATCH / MISMATCH / ERROR. No Apache Commons Compress: minSdk 24 has no core-library desugaring and CC reaches into java.nio.file (API 26+); we hand parse the tar like RootfsManifest does. - Tests: RootfsTreeHashTest (golden parity) + RootfsIntegrityTest over checked-in ustar/GNU/pax/mismatch/none/absent fixtures. Wiring (Result.CORRUPT + gates) and the backup writer come in the next commits.
…dator + import gate - RootfsManifest.Identity gains 'origin' (cheap device-backup signal from the first tar header — no full pass for app-made backups). - RootfsArchiveValidator: Result.CORRUPT + OK_NO_CHECKSUM; new checkIntegrity overload. Import gate (checkIntegrity=true) recomputes the treehash for builder rootfs and fails closed on MISMATCH/ERROR; device backups (origin) and the restore path skip the full pass. Matrix: absent->OK_NO_MANIFEST(soft); origin/none->OK_NO_CHECKSUM; match->OK; mismatch->CORRUPT(block). - DeployFragment import gate: CORRUPT blocks+deletes like WRONG_ARCH; OK_NO_CHECKSUM proceeds with a transparency snackbar. - strings (en/es): install_error_corrupt, install_warn_no_checksum.
App-created backups now embed installed-rootfs/iiab/.iiab-rootfs.json declaring kind/arch + origin=device-backup (and builder=knowledgetogo-app). Staged in a temp tree and packed FIRST (a second tar -C) so the validator reads it from the first header — no full decompress, no java.nio, flag-agnostic. NO treehash is computed on the device (we don't make the phone a builder); origin=device-backup is the explicit no-checksum declaration the verifier maps to OK_NO_CHECKSUM.
luisguzman-adfa
added a commit
that referenced
this pull request
Jun 24, 2026
- Status banner: Phase 0 done + Phase 1 core-complete; Phase 2 not started (~37 raw threads); Phase 3 partial (slices land but god classes grew — DeployFragment ~3022, MainActivity ~2384); M15 done, M8/M9 open. - Phase 1 line: F15 A+B (#30/#32) + rootfs validation (#31) + integrity (#37) done. - Integrity/writer entry: marked DONE via #37 (was 'next PR'). - F4 + M7: confirmed mitigated by inspection (onPause teardown + remove-before-post). - Lint workaround: added root-cause analysis with concrete carve targets (addNewTerminalSession ~727 LOC; DeployFragment bind* methods) for D1/F1. Docs only; no code change.
This was referenced Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #31. Part 2 of the rootfs import/restore validation series.
What
On-device integrity verification for manually imported rootfs/backups, plus a backup writer that stamps a manifest. No new dependencies.
Verifier (consumer)
deploy/domain/RootfsTreeHash— pure-JVMiiab-tree-sha256-v1(norm + per-member digest + order-independent, domain-separated combine). Byte-parity withtools/iiab_tree_hash.pyproven by tests.deploy/data/RootfsIntegrity— one-pass, dependency-free tar reader (ustar + GNU long-name + pax path/linkpath) that recomputes the treehash (excluding the integrity member) and reads the declaration →ABSENT / DECLARED_NONE / MATCH / MISMATCH / ERROR.java.nio.file(API 26+). We hand-parse the tar the wayRootfsManifestalready does +GZIPInputStream.Wiring (matrix)
OK_NO_MANIFEST(soft alert)origin:device-backup/algo:noneOK_NO_CHECKSUM(proceed + transparency)OKCORRUPT→ blocks (likeWRONG_ARCH)Integrity runs only at the import gate and rides identity: device backups are recognized from the first tar header (no full pass); the restore path does not re-verify. Block-on-mismatch is safe because the CI parity test retires the false-positive risk.
Writer (producer)
installed-rootfs/iiab/.iiab-rootfs.jsonwithkind/arch/built/builder+origin:device-backup, staged in a temp tree and packed first (a secondtar -C). No treehash is computed on the device — we don't turn the phone into a builder;origin:device-backupis the explicit "no checksum" declaration.Tests
RootfsTreeHashTest(golden parity) +RootfsIntegrityTestover checked-in ustar / GNU long-name / pax / mismatch / none / absent fixtures. Verifier + writer were also validated end-to-end locally against the Python reference.Deferred (documented)
Interactive "restore without checksum?" gate; strict-on-absence; >10 GB → suggest Share/rsync. Folding the rare builder-rootfs-manual-import verify into the import copy (it currently costs one extra pass for that path only).
Contract addendum to relay to the build task
origin:"device-backup"in the identity member = "no checksum by design" (andalgo:"none"in the integrity member). Backward-compatible;docs/ROOTFS_MANIFEST.mdshould record it.