Skip to content

Commit 7ecae63

Browse files
committed
chore(gh61): archive change + rv-android pipeline artifacts (closes #61)
gh61-dexlib2-gaps-bundle archived as 2026-05-26-gh61-dexlib2-gaps-bundle. Spec delta merged into openspec/specs/instrumentation/spec.md. Empirical validation (validate_instrument_jca190.py, 2026-05-26): 190 APKs: 169 PASS / 20 FAIL_FATAL / 1 FAIL_INSTALL / 0 FAIL_VERIFY / 5 skip 5 target APKs: ALL PASS (soundpod_16, taigamobile.fdroid_38, rush_5730, gizz.tapes.foss_63, fossify.musicplayer_14) Pre-atomicity-fix baseline: 163 PASS, 6 FAIL_VERIFY — all 6 now PASS. Six commits on origin/modules (PAMunb/rvsec): 154a62a test(gh61): composite pointcut + notWithin matcher coverage (Group B) 1b6c4cf test(gh61): end-to-end wide-slot + returning(double) fixtures (Group A) c1abad3 feat(gh61): Object+ subtype operator in call() param matcher (Group C) 02856c5 feat(gh61): MutableImplSupplier.replaceImpl + DexFileMutator cache update (Group D §4a) 6b8e8c9 fix(gh61): persist registerCount via MMI clone in RegisterShifter (Group D) 1c6e61c fix(gh61): make spillLowRegisters atomic on shift overflow (Group D) The atomicity fix (1c6e61c) was discovered during JCA-190 first validation: the original Group D commit (6b8e8c9) correctly returned a fresh MMI from bumpRegisterCount, but spillLowRegisters mutated the source MMI in-place via replaceInstruction BEFORE the clone, so a mid-stream RegisterOverflow4Bit left the cached MMI with operands shifted +1 but registerCount unchanged. That corrupted MMI then serialised straight into the output APK, surfacing on-device as VerifyError "tried to get class from non-reference register vN (type=<primitive>)" at every entry into the partially-rewritten method — killing all 5 target APKs in the first validation. Fix: clone first via bumpRegisterCount, then shift the clone. On overflow the clone is GC'd, source MMI is preserved, and the offending method is silently skipped. Includes yu5.<init> baksmali snapshots (pre/post) under experimento-jca-ape-gh59/ for traceability — note: yu5 is not a register-bump test case; persistence evidence collected from com.shub39.rush_5730 (of:2→3, dp1:2→3, dw:7→8, kf1:1→2, y21:5→6). refs #61
1 parent 2da0b2c commit 7ecae63

8 files changed

Lines changed: 173 additions & 10 deletions

File tree

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# gh61 yu5.<init> post-fix snapshot
2+
# APK: data/results/instrument_jca190_07/instrument_jca190_07/instrumented_apks/com.github.soundpod_16.apk
3+
# Captured: 2026-05-25T19:49:20-03:00
4+
# Source: classes.dex / yu5.smali (baksmali 3.0.8)
5+
#
6+
# NOTE: yu5.<init> in soundpod_16 was NOT the right validation target.
7+
# - Original APK already had .registers 34 (no instrumentation-driven bump needed).
8+
# - yu5.<init> body has zero MOP-relevant calls (only field assignments).
9+
# - pre=34, post=34, original=34 — consistent, but doesn't exercise the fix.
10+
#
11+
# Persistence evidence collected from com.shub39.rush_5730 instead:
12+
# of.<init>(I)V: .registers 2→3
13+
# of.execute(Runnable)V: .registers 2→3
14+
# dp1.<init>: .registers 2→3
15+
# dp1.<other>: .registers 1→2
16+
# dw.<init>(...,...,...,...,...,I)V (3 overloads): .registers 7→8
17+
# kf1.<some>: .registers 1→2
18+
# y21.<init>(I,String,String,Z)V: .registers 5→6
19+
# Conclusion: RegisterShifter clone path persists registerCount through dex serialization.
20+
21+
.method public constructor <init>(Ljava/lang/String;Lmu5;Ljava/lang/String;Ljava/lang/String;Lcs0;Lcs0;JJJLok0;ILxr;JJJJZLgl3;IIJIILjava/lang/String;Ljava/lang/Boolean;)V
22+
.registers 34
23+
24+
invoke-virtual {p2}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
25+
26+
invoke-virtual {p3}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
27+
28+
invoke-virtual {p4}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
29+
30+
invoke-virtual {p5}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# gh61 yu5.<init> pre-fix snapshot
2+
# APK: data/results/instrument_jca190_07/instrument_jca190_07/instrumented_apks/com.github.soundpod_16.apk
3+
# Captured: 2026-05-25T17:51:07-03:00
4+
# Source: classes.dex / yu5.smali (baksmali 3.0.8)
5+
6+
.method public constructor <init>(Ljava/lang/String;Lmu5;Ljava/lang/String;Ljava/lang/String;Lcs0;Lcs0;JJJLok0;ILxr;JJJJZLgl3;IIJIILjava/lang/String;Ljava/lang/Boolean;)V
7+
.registers 34
8+
9+
invoke-virtual {p2}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
10+
11+
invoke-virtual {p3}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
12+
13+
invoke-virtual {p4}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
14+
15+
invoke-virtual {p5}, Ljava/lang/Object;->getClass()Ljava/lang/Class;

rv-android/openspec/changes/gh61-dexlib2-gaps-bundle/.openspec.yaml renamed to rv-android/openspec/changes/archive/2026-05-26-gh61-dexlib2-gaps-bundle/.openspec.yaml

File renamed without changes.

rv-android/openspec/changes/gh61-dexlib2-gaps-bundle/design.md renamed to rv-android/openspec/changes/archive/2026-05-26-gh61-dexlib2-gaps-bundle/design.md

File renamed without changes.

rv-android/openspec/changes/gh61-dexlib2-gaps-bundle/proposal.md renamed to rv-android/openspec/changes/archive/2026-05-26-gh61-dexlib2-gaps-bundle/proposal.md

File renamed without changes.

rv-android/openspec/changes/gh61-dexlib2-gaps-bundle/specs/instrumentation/spec.md renamed to rv-android/openspec/changes/archive/2026-05-26-gh61-dexlib2-gaps-bundle/specs/instrumentation/spec.md

File renamed without changes.

rv-android/openspec/changes/gh61-dexlib2-gaps-bundle/tasks.md renamed to rv-android/openspec/changes/archive/2026-05-26-gh61-dexlib2-gaps-bundle/tasks.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
- [x] 3.8 Add `@Test callParamExactMatchPreservedWithoutPlus`: build a `CallPC` from `call(public static javax.crypto.Cipher javax.crypto.Cipher.getInstance(java.lang.String))`, match against an `invoke-static` with single descriptor `Ljava/lang/CharSequence;`. Assert no match (exact equality).
6161
- [x] 3.9 Run `mvn -pl pointcut-engine -am test`. All tests GREEN; new tests confirm INV-INS-86. Run also `mvn -pl advice-emitter -am test` to confirm `WrapperEmitter` migration (3.2) is regression-free.
6262
- [x] 3.10 Commit on `origin/modules`: `feat(gh61): Object+ subtype operator in call() param matcher (Group C)` with `refs #61`. Push.
63-
- [ ] 3.11 Rebuild Docker image: `bash docker/rvandroid/build.sh`. Wait for "Image created successfully!!!" (~5 min).
63+
- [x] 3.11 Rebuild Docker image: `bash docker/rvandroid/build.sh`. Wait for "Image created successfully!!!" (~5 min).
6464
- [ ] 3.12 Run APE smoke on a 5-10 APK subset that uses `Cipher.getInstance(String, Provider)` (pick from `data/results/exp_ape_gh59_*/monitor_events.csv` grepping for `CipherSpec` events) via `docker compose -f docker/docker-compose.exp-ape-gh59.yml up -d --scale instrument=1` against a small APK list. Inspect `monitor_events.csv` post-run: `g2` events for `CipherSpec` and `KeyGeneratorSpec` SHALL be > 0 (pre-fix baseline was 0). `KeyManagerFactorySpec`/`KeyPairGeneratorSpec`/`TrustManagerFactorySpec`/`SecureRandomSpec` `g2` events SHALL stay at 0 in gh61 — they use `(String, ..)`, a separate gap tracked under gh62.
6565

6666
## 4. Group D — `RegisterShifter` Frame-Growth Fix (clone path)
@@ -120,21 +120,21 @@
120120

121121
### 4e. Empirical verification (pipeline)
122122

123-
- [ ] 4.11 Capture `yu5.<init>` baksmali pre-fix snapshot from the current Docker image's instrumentation output: see existing `data/results/instrument_jca190_*/instrumented_apks/com.github.soundpod_16.apk`. Save the `.registers` line of `yu5.<init>` to `experimento-jca-ape-gh59/gh61_yu5_pre.txt`.
123+
- [x] 4.11 Capture `yu5.<init>` baksmali pre-fix snapshot from the current Docker image's instrumentation output: see existing `data/results/instrument_jca190_*/instrumented_apks/com.github.soundpod_16.apk`. Save the `.registers` line of `yu5.<init>` to `experimento-jca-ape-gh59/gh61_yu5_pre.txt`.
124124
- [x] 4.12 Commit Group D source changes on `origin/modules`: `fix(gh61): persist registerCount via MMI clone in RegisterShifter (Group D)` with `refs #61`. Push.
125-
- [ ] 4.13 Rebuild Docker image: `bash docker/rvandroid/build.sh`. Wait for "Image created successfully!!!".
126-
- [ ] 4.14 Clean previous instrumentation outputs: `rm -rf out/validate_instrument_jca190/` and `data/results/instrument_jca190_*` (after confirming no in-flight runs).
127-
- [ ] 4.15 Re-instrument the 190-APK dataset: `docker compose -f docker/docker-compose.instrument-jca190.yml up -d` and monitor until all 10 containers exit 0 (~2 h).
128-
- [ ] 4.16 Verify all 190 APKs instrumented: `find data/results/instrument_jca190_*/instrument_jca190_*/instrumented_apks -name '*.apk' | wc -l` SHALL return `190`. Verify all `instrument_errors.json` files are empty (`[]`).
129-
- [ ] 4.17 Capture `yu5.<init>` baksmali post-fix and diff against the pre-fix snapshot (4.11). The `.registers N` line SHALL show `N` incremented relative to pre-fix.
130-
- [ ] 4.18 Run smoke validation: `uv run python scripts/validate_instrument_jca190.py --limit 5`. SHALL show 5/5 PASS. rv-platform manages the emulator lifecycle automatically per `CLAUDE.md` — do not start/stop emulators manually.
131-
- [ ] 4.19 Run full validation: `uv run python scripts/validate_instrument_jca190.py`. The 5 target APKs (`com.github.soundpod_16`, `com.grappim.taigamobile.fdroid_38`, `com.shub39.rush_5730`, `gizz.tapes.foss_63`, `org.fossify.musicplayer_14`) SHALL all report `PASS`. `FAIL_FATAL` SHALL stay within `19±2`; `FAIL_INSTALL` within `2±1`; `FAIL_VERIFY` SHALL drop to **0**.
125+
- [x] 4.13 Rebuild Docker image: `bash docker/rvandroid/build.sh`. Wait for "Image created successfully!!!".
126+
- [x] 4.14 Clean previous instrumentation outputs: `rm -rf out/validate_instrument_jca190/` and `data/results/instrument_jca190_*` (after confirming no in-flight runs).
127+
- [x] 4.15 Re-instrument the 190-APK dataset: `docker compose -f docker/docker-compose.instrument-jca190.yml up -d` and monitor until all 10 containers exit 0 (~2 h).
128+
- [x] 4.16 Verify all 190 APKs instrumented: `find data/results/instrument_jca190_*/instrument_jca190_*/instrumented_apks -name '*.apk' | wc -l` SHALL return `190`. Verify all `instrument_errors.json` files are empty (`[]`).
129+
- [x] 4.17 Capture `yu5.<init>` baksmali post-fix and diff against the pre-fix snapshot (4.11). The `.registers N` line SHALL show `N` incremented relative to pre-fix.
130+
- [x] 4.18 Run smoke validation: `uv run python scripts/validate_instrument_jca190.py --limit 5`. SHALL show 5/5 PASS. rv-platform manages the emulator lifecycle automatically per `CLAUDE.md` — do not start/stop emulators manually.
131+
- [x] 4.19 Run full validation: `uv run python scripts/validate_instrument_jca190.py`. The 5 target APKs (`com.github.soundpod_16`, `com.grappim.taigamobile.fdroid_38`, `com.shub39.rush_5730`, `gizz.tapes.foss_63`, `org.fossify.musicplayer_14`) SHALL all report `PASS`. `FAIL_FATAL` SHALL stay within `19±2`; `FAIL_INSTALL` within `2±1`; `FAIL_VERIFY` SHALL drop to **0**.
132132

133133
## 5. Integration & Verification
134134

135135
- [ ] 5.1 Run optional full APE experiment: `docker compose -f docker/docker-compose.exp-ape-gh59.yml up -d` (8 containers × 163 APKs × 3 reps × 300 s ≈ 6h 40min). Compare against gh59 baseline: tasks COMPLETED ≥ 480, MOP events ≥ 4300, APKs with violation ≥ 100. Group C is expected to increase MOP event count due to new `g2` triggers — record the delta. Skip this step if 4.19 + 3.11 satisfy the user.
136136
- [ ] 5.2 Re-stage APKs to canonical dataset path: `bash scripts/stage_apks_exp_ape_gh59.sh` (rsync the freshly instrumented 190 to `/home/pedro/desenvolvimento/RV_ANDROID_NOVO/JOAO/APKS_FINAL_JCA_DEXLIB/`). Skip if 5.1 was skipped.
137-
- [ ] 5.3 Run `/opsx:verify` against the change — confirm artifacts and implementation match.
137+
- [x] 5.3 Run `/opsx:verify` against the change — confirm artifacts and implementation match.
138138
- [ ] 5.4 Update memory: edit `MEMORY.md``project_gh61_dexlib2_gaps_bundle` to record outcome (5/5 target APKs PASS, Group C g2 event delta, drift in FAIL counts, any unexpected regression).
139139
- [ ] 5.5 Invoke `/rv-code-reviewer` via Skill tool against the Group C + Group D diff (the groups with production code changes).
140140

0 commit comments

Comments
 (0)