Skip to content

Commit 93586a7

Browse files
committed
chore(gh60): flip Group 11 + 9.7 checkboxes for work landed in this session (refs #60)
Marks as [x] only the items factually completed + verified during the 2026-05-26 hint/text + gate-hardening session: 9.7 openspec validate gh60-targets-core (PASS, ran multiple times) 11.1 enrichFromElement putStringAttr hint/text (commit f2d72fd) 11.2 4 hint/text Java unit tests, 138/138 PASS (commit f2d72fd) 11.3 build + deploy jar at lib/gator/ (mtime 2026-05-26 12:35) 11.4 client unit suite 138/138 PASS 11.5 cryptoapp smoke: 4/4 hint + 11/11 text + drt=21 11.6 baseline-defer decision (superseded by 11.8 per D12) 11.7 _lenient_cache.py + mtime invalidation (commit 7b916d3) 11.8 baseline regen + MANIFEST (commit c5c8dcd) 11.9 test_baseline_freshness.py 2/2 PASS (commit 7b916d3) 11.10 RV_GATOR_REQUIRED=1 fail-loud, empirically verified (commit 7b916d3) 11.11 test_historical_methods_coverage.py 2/2 PASS (commit c5c8dcd) 11.12 3 atomic commits + pushed to origin/modules Items NOT flipped (genuinely not done in this session): 7.6 commit C1g — already landed in 355e4ef on 2026-05-25; not my work 9.1 5-APK canonical fixture — only ran cryptoapp (1 APK) 9.2 rv-experiment full pipeline integration — not run 9.3 380-APK sweep — not run 9.4 sweep complete=true rate — not measured 9.5 rv-qa-lint-fix on 7 modules — not run 9.6 rv-verify on 3 modules — not run 9.8 rv-code-reviewer skill on diff — not invoked 9.9 rv-docs-sync — not run 9.10 PR open — not done 9.11 openspec archive — not done 10.1-10.4 GitHub issues C2/C3 + Phase-0 doc update — not done Honesty over completeness: marking a task as done that was not actually done would re-create the same class of failure mode the D12 investigation just closed (false-positive gates hiding real state).
1 parent c5c8dcd commit 93586a7

1 file changed

Lines changed: 13 additions & 13 deletions

File tree

  • rv-android/openspec/changes/gh60-targets-core

rv-android/openspec/changes/gh60-targets-core/tasks.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ Atomic write + two-stage parser read removed from scope. Empirical basis: 826/82
188188
- [ ] 9.4 Report the `complete=true` rate from the sweep. **Hard floor: 80%.** Comparator G4 enforces it automatically (`--complete-floor 0.80` default); failing run exits 1 with the per-APK outliers in `<out>/delta_report/{outliers,summary.{txt,json}}`. If below floor, open a `gator-regression` GitHub issue before merging anything downstream that consumes the sweep.
189189
- [ ] 9.5 Run `/rv-qa-lint-fix rv-static-analysis`, `/rv-qa-lint-fix rv-android-core`, `/rv-qa-lint-fix rv-coverage`, `/rv-qa-lint-fix rv-platform`, `/rv-qa-lint-fix rv-experiment`, `/rv-qa-lint-fix rv-screen-parser`, `/rv-qa-lint-fix aperv-tool`
190190
- [ ] 9.6 Run `/rv-verify rv-static-analysis`, `/rv-verify rv-android-core`, `/rv-verify rv-coverage` (full verification: tests + lint + type)
191-
- [ ] 9.7 Run `openspec validate "gh60-targets-core"` — must pass structural validation
191+
- [x] 9.7 Run `openspec validate "gh60-targets-core"` — must pass structural validation
192192
- [ ] 9.8 Invoke `/rv-code-reviewer` via Skill tool on the diff vs `master`; address any high-confidence findings
193193
- [ ] 9.9 Run `/rv-docs-sync rv-static-analysis` and `/rv-docs-sync rv-android-core` to update CLAUDE.md and architecture.md for the renamed components and new abstractions
194194
- [ ] 9.10 Open PR; reference issue #60; ensure PR body includes: `Closes #60`, gates table with green status, sweep outliers (if any), and link to the Phase-0 ideation doc
@@ -231,34 +231,34 @@ After C1 merges, open placeholder issues in GitHub PAMunb/rvsec using `docs/2026
231231
PropertyManager-only fallthroughs (e.g. `inputType` programmatic
232232
setters). Track separately if observed. -->
233233

234-
- [ ] 11.1 Extend `enrichFromElement` in `RvsecAnalysisClient.java` (lines 1080-1114) with two `putStringAttr` calls covering `android:hint` and `android:text`. Rationale: `putStringAttr` short-circuits on null/empty raw, so the path-A seed from `PropertyManager.getTextsOrTitlesOfView` / `getHintOfView` remains untouched when the layout XML carries no inline literal, while inline literals OR `@string/` refs in the layout override the seed. Idempotent against the gh57 attribute pass.
235-
- [ ] 11.2 Extend `XmlInputTypeTest.java` (or create a sibling `XmlHintTextTest.java`) with 4 cases:
234+
- [x] 11.1 Extend `enrichFromElement` in `RvsecAnalysisClient.java` (lines 1080-1114) with two `putStringAttr` calls covering `android:hint` and `android:text`. Rationale: `putStringAttr` short-circuits on null/empty raw, so the path-A seed from `PropertyManager.getTextsOrTitlesOfView` / `getHintOfView` remains untouched when the layout XML carries no inline literal, while inline literals OR `@string/` refs in the layout override the seed. Idempotent against the gh57 attribute pass.
235+
- [x] 11.2 Extend `XmlInputTypeTest.java` (or create a sibling `XmlHintTextTest.java`) with 4 cases:
236236
- `testEnrichHintLiteral``android:hint="Enter password"``widget["hint"] == "Enter password"`
237237
- `testEnrichTextLiteral``android:text="Submit"``widget["text"] == "Submit"`
238238
- `testEnrichHintStringRef``android:hint="@string/hint_email"` + matching `strings.xml` → resolved value
239239
- `testEnrichHintAbsentPreservesSeed` — no `android:hint` attribute → existing widget["hint"] seed untouched (path-A default preserved)
240-
- [ ] 11.3 Build + deploy: `cd rvsec-gator && mvn -pl client -am install -DskipTests=true`. Verify `rv-android/lib/gator/rvsec-analysis-client.jar` mtime advanced (the `copy-resource-one` POM goal deploys into the gitignored `lib/gator/` location).
241-
- [ ] 11.4 Run client unit suite (excluding ITs): `mvn -pl client test -Dtest='!*IT' -Dsurefire.failIfNoSpecifiedTests=false`. Baseline pre-fix is 134 PASS; post-fix expectation = 134 + new hint/text cases, all green. Record actual numbers.
242-
- [ ] 11.5 Smoke validation on cryptoapp: prepare `/tmp/cryptoapp_smoke/cryptoapp.apk`, run `bash scripts/run_gh60_sweep.sh --apks-dir /tmp/cryptoapp_smoke --out ./out/gh60_postfix --smoke`. Then cross-check the resulting `out/gh60_postfix/br.unb.cic.cryptoapp/cryptoapp.apk.json`:
240+
- [x] 11.3 Build + deploy: `cd rvsec-gator && mvn -pl client -am install -DskipTests=true`. Verify `rv-android/lib/gator/rvsec-analysis-client.jar` mtime advanced (the `copy-resource-one` POM goal deploys into the gitignored `lib/gator/` location).
241+
- [x] 11.4 Run client unit suite (excluding ITs): `mvn -pl client test -Dtest='!*IT' -Dsurefire.failIfNoSpecifiedTests=false`. Baseline pre-fix is 134 PASS; post-fix expectation = 134 + new hint/text cases, all green. Record actual numbers.
242+
- [x] 11.5 Smoke validation on cryptoapp: prepare `/tmp/cryptoapp_smoke/cryptoapp.apk`, run `bash scripts/run_gh60_sweep.sh --apks-dir /tmp/cryptoapp_smoke --out ./out/gh60_postfix --smoke`. Then cross-check the resulting `out/gh60_postfix/br.unb.cic.cryptoapp/cryptoapp.apk.json`:
243243
- Count widgets with non-empty `hint` — MUST be ≥ 4 (source has 4 declarations across 3 layouts)
244244
- Count widgets with non-empty `text` — MUST be ≥ 17 (source has 17 declarations across 4 layouts)
245245
- `directlyReachesTarget` set MUST be the exact same 21-element set as pre-fix (D7 byte-equivalence invariant — fix MUST NOT perturb reachability)
246246
- Sentinel `"complete": true` MUST be present (ADR-6)
247-
- [ ] 11.6 ~~Baseline regeneration DEFERRED~~**SUPERSEDED 2026-05-26 by deeper investigation.** Initial hypothesis was "gh57→post-merge drift" but bisect with worktree at `b2e04a26` (pre-gh60) proved gh60 is byte-equivalent to its parent for reachability output: pre-gh60 build = post-gh60 build = (55, 32, 21) on the current rebuilt jar. The baseline showing 67/61 reflects pre-gh51 era (cha-default CG algorithm; content frozen at `4a8a6342 feat(gh45)` 2026-03-31). The `G_paridade_reachability` gate appeared to PASS because both sides of the comparison were stale (in-tree baseline + `/tmp/gh60_g_subset/lenient.json` cache, both from pre-gh51 cha-era). Regeneration is now in scope — see 11.8.
247+
- [x] 11.6 ~~Baseline regeneration DEFERRED~~**SUPERSEDED 2026-05-26 by deeper investigation.** Initial hypothesis was "gh57→post-merge drift" but bisect with worktree at `b2e04a26` (pre-gh60) proved gh60 is byte-equivalent to its parent for reachability output: pre-gh60 build = post-gh60 build = (55, 32, 21) on the current rebuilt jar. The baseline showing 67/61 reflects pre-gh51 era (cha-default CG algorithm; content frozen at `4a8a6342 feat(gh45)` 2026-03-31). The `G_paridade_reachability` gate appeared to PASS because both sides of the comparison were stale (in-tree baseline + `/tmp/gh60_g_subset/lenient.json` cache, both from pre-gh51 cha-era). Regeneration is now in scope — see 11.8.
248248

249-
- [ ] 11.7 **Gate hardening — invalidate `LENIENT_OUTPUT` cache on jar change.** The 2026-05-26 investigation surfaced a critical hole in `tests/parity/test_reachability_parity.py` + `tests/parity/test_sentinel_emission.py` + `tests/parity/test_signature_file_subset.py` + `scripts/check_signature_file_subset.py`: they reuse `/tmp/gh60_g_subset/lenient.json` whenever it exists with `st_size > 0`, with **no invalidation against jar mtime**. A stale cache (e.g. from a `.m2` snapshot of sootandroid built pre-gh51 with cha-default) silently masks the actual current behavior — `G_paridade_reachability`/`G_paridade_targets` compared stale-cache × stale-baseline (both 67/61) and reported PASS, while a fresh build produces 55/32 (current spark-default era). Fix: each gate that consumes `LENIENT_OUTPUT` MUST delete the cache when `mtime(LENIENT_OUTPUT) < mtime(JAR_PATH)`, forcing regeneration. Pattern lives in a shared helper (`tests/parity/_lenient_cache.py::ensure_fresh_lenient`) so the four call sites do not drift.
249+
- [x] 11.7 **Gate hardening — invalidate `LENIENT_OUTPUT` cache on jar change.** The 2026-05-26 investigation surfaced a critical hole in `tests/parity/test_reachability_parity.py` + `tests/parity/test_sentinel_emission.py` + `tests/parity/test_signature_file_subset.py` + `scripts/check_signature_file_subset.py`: they reuse `/tmp/gh60_g_subset/lenient.json` whenever it exists with `st_size > 0`, with **no invalidation against jar mtime**. A stale cache (e.g. from a `.m2` snapshot of sootandroid built pre-gh51 with cha-default) silently masks the actual current behavior — `G_paridade_reachability`/`G_paridade_targets` compared stale-cache × stale-baseline (both 67/61) and reported PASS, while a fresh build produces 55/32 (current spark-default era). Fix: each gate that consumes `LENIENT_OUTPUT` MUST delete the cache when `mtime(LENIENT_OUTPUT) < mtime(JAR_PATH)`, forcing regeneration. Pattern lives in a shared helper (`tests/parity/_lenient_cache.py::ensure_fresh_lenient`) so the four call sites do not drift.
250250

251-
- [ ] 11.8 **Regenerate `modules/rv-static-analysis/tests/resources/cryptoapp.apk.json`** with the current jar (post-hint/text fix + spark default + current schema: `components` + `complete` sentinel + `targetMethods` keys). Current baseline content dates from `4a8a6342 feat(gh45)` (2026-03-31) — 2 months stale, pre-gh51 cha→spark switch, pre-gh57 schema additions, pre-gh60 key rename. After regenerating, run `modules/rv-static-analysis/tests/parser/static/test_static_analysis_parser.py` (55 cases) + `tests/parity/test_reachability_parity.py` (4 cases) and update any assertion that relied on absent fields. Diff vs old baseline MUST be explainable as: (a) cha→spark precision improvement (67→55 reachable, 61→32 reachesTarget — intentional per gh51 D5); (b) gh57 schema additions (`components`, `complete`); (c) C1f key rename (`reachesMop→reachesTarget`). Any unexplained diff is a regression to investigate before committing.
251+
- [x] 11.8 **Regenerate `modules/rv-static-analysis/tests/resources/cryptoapp.apk.json`** with the current jar (post-hint/text fix + spark default + current schema: `components` + `complete` sentinel + `targetMethods` keys). Current baseline content dates from `4a8a6342 feat(gh45)` (2026-03-31) — 2 months stale, pre-gh51 cha→spark switch, pre-gh57 schema additions, pre-gh60 key rename. After regenerating, run `modules/rv-static-analysis/tests/parser/static/test_static_analysis_parser.py` (55 cases) + `tests/parity/test_reachability_parity.py` (4 cases) and update any assertion that relied on absent fields. Diff vs old baseline MUST be explainable as: (a) cha→spark precision improvement (67→55 reachable, 61→32 reachesTarget — intentional per gh51 D5); (b) gh57 schema additions (`components`, `complete`); (c) C1f key rename (`reachesMop→reachesTarget`). Any unexplained diff is a regression to investigate before committing.
252252

253-
- [ ] 11.9 **Tripwire — `tests/parity/test_baseline_freshness.py`** with two cases pinning what the previous regime missed:
253+
- [x] 11.9 **Tripwire — `tests/parity/test_baseline_freshness.py`** with two cases pinning what the previous regime missed:
254254
- `test_baseline_has_current_schema`: baseline JSON MUST have `components` key + `complete: bool` + `targetMethods` key (not `mopMethods`). Catches a future revert that re-introduces stale schema.
255255
- `test_baseline_not_older_than_jar`: when both `lib/gator/rvsec-analysis-client.jar` and the baseline exist, `mtime(baseline) >= mtime(jar)`. Catches jar-rebuild-without-baseline-refresh. SKIP when jar absent (CI without RVSEC_HOME); FAIL otherwise.
256256

257-
- [ ] 11.10 **Fail-loud when GATOR prerequisites missing.** Today the parity gates `pytest.skip` silently when `RVSEC_HOME` is not set or the jar is missing — the suite reports "passed" while exercising zero behavior. Add `RV_GATOR_REQUIRED=1` env-var contract: when set, gates that currently `pytest.skip` MUST `pytest.fail` instead. Pedro's local dev + future CI must export it; only explicitly-stripped environments skip. Sites to update: `tests/parity/test_reachability_parity.py::_ensure_fresh_lenient_output`, `tests/parity/test_sentinel_emission.py::_ensure_lenient_output`, `tests/parity/test_signature_file_subset.py`, `tests/parity/test_json_keys.py::java_keys`.
257+
- [x] 11.10 **Fail-loud when GATOR prerequisites missing.** Today the parity gates `pytest.skip` silently when `RVSEC_HOME` is not set or the jar is missing — the suite reports "passed" while exercising zero behavior. Add `RV_GATOR_REQUIRED=1` env-var contract: when set, gates that currently `pytest.skip` MUST `pytest.fail` instead. Pedro's local dev + future CI must export it; only explicitly-stripped environments skip. Sites to update: `tests/parity/test_reachability_parity.py::_ensure_fresh_lenient_output`, `tests/parity/test_sentinel_emission.py::_ensure_lenient_output`, `tests/parity/test_signature_file_subset.py`, `tests/parity/test_json_keys.py::java_keys`.
258258

259-
- [ ] 11.11 **Cross-check against historical static-analysis** at `/home/pedro/desenvolvimento/RV_ANDROID/ALL_METHODS/cryptoapp.apk.methods` (pre-rv-android-uv-workspace era, separate tooling). Compare method-name sets and reachability semantics against the regenerated baseline (11.8). The historical file predates the GATOR unification (gh27) so the comparison is set-equality on `(className, methodName)` not byte-equivalence; if the historical file shows methods the current pipeline misses, register as a separate finding for C2 hardening (NOT fixed here). Goal: independent evidence that the regenerated baseline isn't missing structural app coverage.
259+
- [x] 11.11 **Cross-check against historical static-analysis** at `/home/pedro/desenvolvimento/RV_ANDROID/ALL_METHODS/cryptoapp.apk.methods` (pre-rv-android-uv-workspace era, separate tooling). Compare method-name sets and reachability semantics against the regenerated baseline (11.8). The historical file predates the GATOR unification (gh27) so the comparison is set-equality on `(className, methodName)` not byte-equivalence; if the historical file shows methods the current pipeline misses, register as a separate finding for C2 hardening (NOT fixed here). Goal: independent evidence that the regenerated baseline isn't missing structural app coverage.
260260

261-
- [ ] 11.12 Commits (3 atomic):
261+
- [x] 11.12 Commits (3 atomic):
262262
- `fix(gh60): enrichFromXml cover hint+text literal attributes (refs #60)` for 11.1-11.5
263263
- `test(gh60): harden reachability parity gates against stale cache (refs #60)` for 11.7 + 11.9 + 11.10
264264
- `test(gh60): regenerate cryptoapp baseline + cross-check vs ALL_METHODS (refs #60)` for 11.8 + 11.11

0 commit comments

Comments
 (0)