104 lines
6.1 KiB
Markdown
104 lines
6.1 KiB
Markdown
# Claude QA Report — Privacy: Period Tracker
|
||
|
||
```
|
||
Status: Current
|
||
Owner: _null
|
||
Last reviewed: 2026-08-21
|
||
Governs: the QA verdict — build SHAs, round summaries, the overall judgment
|
||
Review trigger: Any QA round run
|
||
```
|
||
|
||
> The QA verdict. Companion to [`ClaudeQACoverage.md`](ClaudeQACoverage.md)
|
||
> (what each pass reached) and [`ClaudeQAPlan.md`](ClaudeQAPlan.md) (the
|
||
> playbook).
|
||
>
|
||
> **Defects are issues, not entries here.** A defect found in a round is filed
|
||
> in the tracker with a severity label, where it can be assigned, closed by a
|
||
> commit, and counted. This file keeps the part a tracker is bad at: a judgment
|
||
> about whether the thing is fit to ship.
|
||
|
||
## Current run-state
|
||
|
||
- **Last QA round:** Round 4 — 2026-08-18, partial (A and B pass; C, D, E, F, G and H partial). **No full round has run since**; the checks on the 20th and 21st were targeted at what those batches changed and are recorded below as such.
|
||
- **Last verified build SHA:** `0ae92bd` — targeted device checks. The last SHA a full round covered is `f43e1c2`.
|
||
- **Last tested device / environment:** emulator `PeriodQA`, API 36, debug build, for the targeted checks. The API 26 run (`PeriodMinSdk26`, Pixel 6 profile, font scales 1.0 / 1.3 / 2.0) was Round 4's and **has not been repeated since** — four batches have landed on top of it.
|
||
- **Overall status:** Every batch through 12 has landed and the tracker has no
|
||
open issue. What was found in the last two days is the reason not to read that
|
||
as *finished*: two release-blockers were sitting in shipped code that no test
|
||
and no round had caught — a reminder button that recorded a new period instead
|
||
of ending one, corrupting the history and every forecast built on it, and a
|
||
Change PIN flow that never checked the current PIN. Both are fixed and both
|
||
were driven on a device. The export can now be read back, which was the last
|
||
thing standing between a user and her own history on a new phone; that flow was
|
||
driven end to end on `PeriodQA` today.
|
||
The pattern is now five rounds old and unchanged: **every defect of consequence
|
||
in this project has been found by driving the app, never by a test.** The tests
|
||
are what stop them coming back. So the standing gaps are the verdict: nobody
|
||
has yet looked at an actual locked screen, TalkBack has still never been run,
|
||
and the app has not been launched at its own `minSdk` since four batches were
|
||
written. Those three hours are what stands between "no known defect" and "fit
|
||
to ship", and they are unspent.
|
||
|
||
## Open defects
|
||
|
||
**Do not list them here, and do not read a defect count out of this file.** The
|
||
Command Center's docs report parses this document for open `P0` / `P1` / `P2`
|
||
counts, and under this convention they are always zero — the defects are in the
|
||
tracker, which is the whole point. The zeros here mean *this file does not hold
|
||
them*, never *there are none*.
|
||
|
||
Filed as issues in this repository's tracker, labelled by what they cost:
|
||
|
||
- **P0** — ships broken, or loses data
|
||
- **P1** — materially wrong, but shippable
|
||
- **P2** — cosmetic or low impact
|
||
- **release-blocker** — a release built today would be *wrong*, not merely
|
||
incomplete
|
||
|
||
Severity is what it costs, not how annoying it is to fix. Every defect needs the
|
||
build SHA it was found at — a finding that cannot be re-tested cannot be closed
|
||
— so put it in the issue body.
|
||
|
||
## Round notes
|
||
|
||
One entry per round, the verdict only. What each pass reached, and what it could
|
||
not, lives in [`ClaudeQACoverage.md`](ClaudeQACoverage.md) and is deliberately
|
||
not repeated here.
|
||
|
||
- **Targeted checks — 2026-08-21 at `0ae92bd`.** Not a round: only the restore
|
||
flow was driven, on `PeriodQA` (API 36). An archive pushed to Downloads was
|
||
restored through Settings → Restore from a file → Add to what is here, giving
|
||
*"Restored. 4 periods and 2 spotting days added."*; Insights then showed three
|
||
cycles with accuracy still unscored, which is the property that matters — an
|
||
import must not manufacture accuracy figures. The same file a second time gave
|
||
*"Everything in that file was already recorded here, so nothing changed."* The
|
||
replace confirmation was opened and cancelled. Verdict on this flow only: it
|
||
does what its screen says. Passes A–H are untouched by this and remain at
|
||
Round 4's state.
|
||
- **Targeted checks — 2026-08-20 at `f91ba6e`.** Not a round: Batches 11 and 12's
|
||
own surfaces were driven on `PeriodQA` — the four App-lock options rendering
|
||
with the biometric rows correctly disabled and explained on a device with no
|
||
enrolment, and the settings back arrow returning from every sub-page. Screenshots
|
||
are black once a lock is set (FLAG_SECURE), so the evidence is `uiautomator dump`
|
||
text. Verdict: the reported navigation trap is gone and the lock offers what it
|
||
claims to offer.
|
||
- **Round 4 — 2026-08-18 at `f43e1c2`, partial.** Batch 06 began, and driving
|
||
it found two defects in controls that already looked finished: navigation
|
||
labels wrapping mid-word at font scale 2.0, and a privacy option whose row was
|
||
inert because only its radio button was clickable. Verdict: the privacy
|
||
controls now behave as their own dialog promises — checked by setting a
|
||
preference, deleting all data, and confirming the preference survived.
|
||
- **Round 3 — 2026-08-18 at `0451fbe`, partial.** Fertility and reminders landed
|
||
and pass F became runnable for the first time. Verdict: fit to keep building,
|
||
not fit to ship — the privacy promise is proved against the notification
|
||
object and never against a locked screen. Two defects, both in how Android
|
||
behaves rather than in the app's logic, and both found by running on a device.
|
||
- **Round 2 — 2026-08-18 at `19edf4c`, partial.** Every screen Batch 03 built
|
||
was driven by hand. Verdict: the product became coherent, and three defects
|
||
surfaced that no unit test would have caught — one of them dark mode, broken
|
||
since Batch 01.
|
||
- **Round 1 — 2026-08-18 at `adc5075`, partial.** Two passes were all the first
|
||
build could support. Verdict: sound enough to keep going, and the first thing
|
||
tried by hand crashed the app with 70 unit tests green — which is the argument
|
||
for driving it at all.
|