docs: record the minSdk emulator, and the first run at API 26
A second AVD exists — PeriodMinSdk26, API 26, Pixel 6 — and the app was built, installed and driven on it end to end. Everything before today ran on API 36, which the standing gaps list has said since Batch 01. The QA plan now names both emulators, because rounds cite PeriodQA by name and nothing defined it. It also carries the recreate command and three mechanical traps that each cost time today: - a windowed emulator dies with its session's X server (XIO: fatal IO error on X server ":0") and took one run down mid-flow; -no-window has no such dependency and screencap still works - adb regularly has three devices attached on this machine, since other projects keep emulators running, so the serial must be resolved from the AVD name rather than assumed to be emulator-5554 - the debug build's application id carries a .debug suffix, so `monkey -p dev.privacyllc.period` aborts with "No activities found to run" after a successful install The coverage doc's "No device at minSdk" gap is marked partly closed, with what was reached (onboarding to first forecast, the date picker, all four tabs, a relaunch after a cold boot) and what was not (notifications, the instrumented suites, anything needing more than one cycle of history). Also fixes a guard failure I introduced in ad085fb: that commit's log entry named docs/architecture/scripts/forgejo-issue.py in backticks, and doc-claims.sh reads a backticked path as a claim the file exists. I had run the guard before writing the entry and not after. Named bare now, per the convention DOC_TRUST_MAP.md already documents; doc-claims reports 255 paths, all present. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0d280d5415
commit
7f7513e7be
|
|
@ -32,6 +32,65 @@ written and stay true. It is exempt from review for the same reason a receipt is
|
||||||
|
|
||||||
## Entries
|
## Entries
|
||||||
|
|
||||||
|
### 2026-08-18 — The app ran at `minSdk` for the first time
|
||||||
|
|
||||||
|
A second emulator exists — `PeriodMinSdk26`, API 26, Pixel 6 — and the app was
|
||||||
|
built, installed and driven on it start to finish. Everything before today ran on
|
||||||
|
API 36, which the standing gaps list has said since Batch 01.
|
||||||
|
|
||||||
|
**It works.** Onboarding from *Get Started* to a first forecast, the Material 3
|
||||||
|
date picker, Today, Calendar, Insights and Settings, all rendering correctly on
|
||||||
|
Android 8.0. The forecast was right — 4 August plus 28 days is 1 September, an
|
||||||
|
11-day window, confidence honestly **Low** on one cycle of history — and
|
||||||
|
fertility declined to estimate rather than inventing one. No crash, and no
|
||||||
|
`NoSuchMethodError`, `VerifyError` or `NoClassDefFoundError` attributable to the
|
||||||
|
app. The one `NoClassDefFoundError` in logcat is
|
||||||
|
`com.google.android.googlequicksearchbox` failing to resolve `TracingController`,
|
||||||
|
an API 28 class, in its own process.
|
||||||
|
|
||||||
|
That is a genuinely useful negative result: the two `NewApi` bugs found in Batch
|
||||||
|
01 were exactly this shape and would have crashed here.
|
||||||
|
|
||||||
|
**Three mechanical traps, all now in the QA playbook** rather than in somebody's
|
||||||
|
memory:
|
||||||
|
|
||||||
|
1. **A windowed emulator dies with the session's X server.** The first one was
|
||||||
|
killed by `XIO: fatal IO error on X server ":0"` mid-flow. `-no-window` has no
|
||||||
|
such dependency and screenshots still work through `adb exec-out screencap`.
|
||||||
|
2. **`adb` regularly has three devices attached here**, because other projects
|
||||||
|
keep their own emulators running, and a bare `adb shell` then fails with *more
|
||||||
|
than one device/emulator*. The serial has to be resolved from the AVD name;
|
||||||
|
assuming `emulator-5554` targets somebody else's work.
|
||||||
|
3. **The debug build's application id carries a `.debug` suffix**, so
|
||||||
|
`monkey -p dev.privacyllc.period` aborts with *No activities found to run*
|
||||||
|
after a successful install — which reads as a broken app rather than a wrong
|
||||||
|
package name.
|
||||||
|
|
||||||
|
**And a free persistence result.** The emulator was killed and cold-booted with
|
||||||
|
onboarding half finished. The install survived, and the app restarted at the
|
||||||
|
beginning of onboarding with nothing partial committed — which is correct, and is
|
||||||
|
the first reboot evidence pass D has ever had.
|
||||||
|
|
||||||
|
**A guard failure of my own, from the entry above.** That entry named the bad
|
||||||
|
`forgejo-issue.py` path in backticks, and `doc-claims.sh` reads a backticked path
|
||||||
|
as a claim the file exists — so commit `ad085fb` shipped with the guard failing.
|
||||||
|
I had run it before writing the log entry and not after. The path is named bare
|
||||||
|
now, which is the convention `DOC_TRUST_MAP.md` already documents for
|
||||||
|
deliberately-absent files, and the guard reports 251 claimed paths all present.
|
||||||
|
|
||||||
|
- **Closed:** nothing. This closes no issue; it partly closes a standing QA gap,
|
||||||
|
which lives in `docs/qa/ClaudeQACoverage.md` rather than the tracker.
|
||||||
|
- **Next action:** Batch 06 — Privacy and Security, unchanged. File its issues
|
||||||
|
first; the milestone is empty. Biometric and PIN lock, export, irreversible
|
||||||
|
delete, the privacy promise in Settings, and making §45's logging rules true in
|
||||||
|
a release build.
|
||||||
|
- **Blockers:** #9, the Command Center webhook, still needs a person. Three of the
|
||||||
|
four QA gaps are unchanged and remain the cheaper spend: nobody has looked at a
|
||||||
|
real lock screen, TalkBack has never been run, and text has never been scaled.
|
||||||
|
The fourth — nothing has run at `minSdk` — is now partly answered, though
|
||||||
|
notifications, the instrumented suites and any multi-cycle history are still
|
||||||
|
unreached at API 26.
|
||||||
|
|
||||||
### 2026-08-18 — A doc audit against the code: 57 wrong claims in eighteen files
|
### 2026-08-18 — A doc audit against the code: 57 wrong claims in eighteen files
|
||||||
|
|
||||||
No code changed. Every document in the tree was checked against the source, the
|
No code changed. Every document in the tree was checked against the source, the
|
||||||
|
|
@ -73,11 +132,13 @@ emptySet()` is pre-declared in the root build script, stricter than the sentence
|
||||||
it replaced, and matching no module until Batch 07 — which is exactly why the
|
it replaced, and matching no module until Batch 07 — which is exactly why the
|
||||||
guard is proved by injection rather than trusted.
|
guard is proved by injection rather than trusted.
|
||||||
|
|
||||||
**Smaller, and each a real trap.** `WORK_CYCLE.md` told the reader to run
|
**Smaller, and each a real trap.** `WORK_CYCLE.md` told the reader to run a
|
||||||
`docs/architecture/scripts/forgejo-issue.py`, a template path that does not
|
`forgejo-issue.py` under docs/architecture/scripts/ — a template path that does
|
||||||
exist here — missed by `doc-claims.sh` because it only reads backticked prose,
|
not exist here, named bare above because `doc-claims.sh` reads a backticked path
|
||||||
not fenced blocks. `ClaudeReport.md`'s Round notes said "No rounds yet" after
|
as a claim the file is present and this sentence says the opposite. The guard
|
||||||
three rounds, because `ClaudeQAPlan.md`'s after-a-round list never mentioned that
|
missed it in `WORK_CYCLE.md` for the neighbouring reason: it reads backticked
|
||||||
|
prose, not fenced code blocks. `ClaudeReport.md`'s Round notes said "No rounds
|
||||||
|
yet" after three rounds, because `ClaudeQAPlan.md`'s after-a-round list never mentioned that
|
||||||
section; both are fixed, the playbook first. The instrumented-test count was
|
section; both are fixed, the playbook first. The instrumented-test count was
|
||||||
eight in three places and is four. `HISTORY.md` said the repository had no code
|
eight in three places and is four. `HISTORY.md` said the repository had no code
|
||||||
and that nothing had been tried and dropped, when three approaches had. The
|
and that nothing had been tried and dropped, when three approaches had. The
|
||||||
|
|
|
||||||
|
|
@ -155,10 +155,17 @@ existing is not a failure; it not existing while the gaps do is.
|
||||||
navigates a screen with their eyes shut.
|
navigates a screen with their eyes shut.
|
||||||
- **Font scaling untried.** The hero number is 72sp; at the largest accessibility
|
- **Font scaling untried.** The hero number is 72sp; at the largest accessibility
|
||||||
scale it may not fit beside anything.
|
scale it may not fit beside anything.
|
||||||
- **No device at `minSdk`.** Everything so far ran on API 36. The two NewApi
|
- **~~No device at `minSdk`~~ — partly closed on 2026-08-18 at `0d280d5`.** The
|
||||||
bugs above would have crashed on Android 8 through 13 and nothing except lint
|
app has now been built, installed and driven on `PeriodMinSdk26`, an API 26
|
||||||
could see them. Lint is a good guard and it is not a substitute for one run on
|
emulator: onboarding start to first forecast, the Material 3 date picker,
|
||||||
an old API level.
|
Today, Calendar, Insights and Settings, plus a relaunch after the emulator was
|
||||||
|
killed and cold-booted. No crash, and no `NoSuchMethodError`, `VerifyError` or
|
||||||
|
`NoClassDefFoundError` attributable to the app — the only `NoClassDefFoundError`
|
||||||
|
in logcat belongs to `com.google.android.googlequicksearchbox`. What is still
|
||||||
|
unreached at API 26: notifications and their lock-screen rendering, the
|
||||||
|
instrumented suites, and anything needing more than one cycle of history, so
|
||||||
|
fertility never became visible. Passes C, E, F, G and H have never run at this
|
||||||
|
API level.
|
||||||
- **Physical-device coverage is undecided.** Passes F and G need a real device
|
- **Physical-device coverage is undecided.** Passes F and G need a real device
|
||||||
with a lock screen and TalkBack; which device that is has not been chosen, and
|
with a lock screen and TalkBack; which device that is has not been chosen, and
|
||||||
an emulator is not a substitute for either.
|
an emulator is not a substitute for either.
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,44 @@ Review trigger: Any new user-facing surface, or a defect class that got through
|
||||||
- Seed the cycle history deliberately. A round run against three cycles and a
|
- Seed the cycle history deliberately. A round run against three cycles and a
|
||||||
round run against twelve are not comparable, and the forecast is the product.
|
round run against twelve are not comparable, and the forecast is the product.
|
||||||
|
|
||||||
|
### The emulators, by name
|
||||||
|
|
||||||
|
Rounds cite these by name, so they are defined here rather than in the round
|
||||||
|
that happened to use one. Both are Pixel 6 profiles, x86_64, no Play Store.
|
||||||
|
|
||||||
|
| AVD | API | Why it exists |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `PeriodQA` | 36 | The everyday round. Current Android, and what Rounds 1–3 ran on. |
|
||||||
|
| `PeriodMinSdk26` | 26 | **`minSdk`.** The floor the app claims to support, and the level lint's `NewApi` findings are about — two of which were real crashes on every device below Android 14, invisible to the unit tests and to an API 36 emulator. |
|
||||||
|
|
||||||
|
Recreate either with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
SDK=$ANDROID_HOME
|
||||||
|
$SDK/cmdline-tools/latest/bin/sdkmanager --install "system-images;android-26;google_apis;x86_64"
|
||||||
|
$SDK/cmdline-tools/latest/bin/avdmanager create avd \
|
||||||
|
-n PeriodMinSdk26 -k "system-images;android-26;google_apis;x86_64" -d pixel_6
|
||||||
|
```
|
||||||
|
|
||||||
|
**Launch headless, and target it by serial.** Other projects on this machine keep
|
||||||
|
their own emulators running, so `adb` regularly has three devices attached and a
|
||||||
|
bare `adb shell` fails with *more than one device/emulator*. Resolve the serial
|
||||||
|
by AVD name rather than assuming `emulator-5554`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$SDK/emulator/emulator -avd PeriodMinSdk26 -no-window -no-audio -no-boot-anim &
|
||||||
|
D=$(adb devices | awk '/emulator-/{print $1}' \
|
||||||
|
| while read d; do [ "$(adb -s $d emu avd name | head -1 | tr -d '\r')" \
|
||||||
|
= PeriodMinSdk26 ] && echo $d; done)
|
||||||
|
adb -s "$D" install -r app/build/outputs/apk/debug/app-debug.apk
|
||||||
|
```
|
||||||
|
|
||||||
|
`-no-window` is not only for headless convenience: a windowed emulator dies with
|
||||||
|
`XIO: fatal IO error on X server ":0"` if the launching session's display goes
|
||||||
|
away, which killed one mid-round. And the debug build's application id carries a
|
||||||
|
`.debug` suffix, so it is `dev.privacyllc.period.debug` that must be launched —
|
||||||
|
`monkey -p dev.privacyllc.period` aborts with *No activities found to run*.
|
||||||
|
|
||||||
## The passes
|
## The passes
|
||||||
|
|
||||||
Each pass gets a letter, so `ClaudeQACoverage.md` can report per pass and a
|
Each pass gets a letter, so `ClaudeQACoverage.md` can report per pass and a
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue