docs: record Round 2 QA and the Batch 03 log entry

Round 2 covers every screen Batch 03 built, pass by pass, with each partial and
not-run row carrying why. Three new standing gaps, all of them things nobody has
done rather than things that failed: TalkBack has never been run, text has never
been scaled, and nothing has run at minSdk.

The rule this session keeps demonstrating is now stated plainly in both files:
the defects in this project are found by running it, not by reading it.
This commit is contained in:
null 2026-08-18 04:05:58 -05:00
parent 19edf4c920
commit 7185708547
3 changed files with 118 additions and 12 deletions

View File

@ -32,6 +32,69 @@ written and stay true. It is exempt from review for the same reason a receipt is
## Entries
### 2026-08-18 — Batch 03 shipped: every screen the app has, and three defects only looking could find
All six Batch 03 issues closed and the milestone with them. Period stopped being
a data layer with a debug surface and became something you can actually use:
onboarding that ends in a forecast, a Today screen whose six states each say
something different and true, two-tap logging, a calendar, and Insights.
**Placeholder artwork, as §42 asks for it.** Every illustration and calendar
marker is a Compose vector path behind a replaceable name — no raster anywhere
under `src/`. The visual language is overlapping circular forms and nothing
else, because §42's forbidden list is a product decision: this app gets opened
in public and a glance over a shoulder should learn nothing. Note the deliberate
contrast with `docs/data/img/`, where a placeholder is still forbidden and #8
stays open; `docs/design/README.md` now explains why the two differ rather than
leaving it looking inconsistent.
**Three defects, none findable by reading:**
1. **Dark mode was broken for the whole of Batch 01.** `PeriodTheme` never
wrapped its content in a `Surface`, so any `Text` without an explicit colour
inherited Material's default — black — and the app's background never
painted. Light mode looked right by accident, because dark-on-cream is what
was wanted anyway. 129 tests were green throughout.
2. **"Period ended" appeared to do nothing.** The logic was correct: a period
that ends today still includes today, so the state genuinely does not change.
The screen was identical afterwards and the button read as broken, which is
worse than being broken somewhere visible.
3. **The today-underline collided with the spotting dot** on the one day that
was both. Invisible in the colour screenshot and obvious the moment it was
converted to greyscale — which is how §43 says to check, and why the check is
written that way rather than trusting that shapes differ because they were
designed to.
Two more came from tests doing their job: the typical-range quartiles were
indexed off `size` rather than `size - 1`, so a regular cycle with one long gap
was reported as "typical range 2961 days" on the screen whose only job is to
say what has been learned; and Room's own executor meant a test's virtual clock
returned before the writes landed, which read as an empty database rather than
as a timing bug.
**The habit is now five pieces of work old and worth writing down as a rule: the
defects in this project are found by running it.** Three guards were green over
exactly what they claimed to check, dark mode was broken for a whole batch, and
a button looked broken while behaving correctly. None of it was visible in the
source.
- **Closed:** #15, #16, #17, #18, #19, #20 — and the `Batch 03 — Core UX`
milestone.
- **Next action:** Batch 04 — Fertility. File its issues first; the milestone is
empty. The work is estimated ovulation and the fertile window from the
forecast and a configurable luteal-phase assumption (§17, §18), the calendar
and Today states that already have their shapes and their `null` placeholders
waiting, and the not-contraception disclaimer everywhere fertility appears.
`CycleStatus` and `CalendarMarks` both already take fertility parameters and
currently receive null — Batch 04 is largely filling those in rather than
adding surfaces.
- **Blockers:** Unchanged. #8 needs the three branding marks drawn by a person.
#9 needs the Command Center webhook URL and secret, which are not readable
from this machine. Neither blocks Batch 04. Worth doing before much more UI:
run TalkBack once, scale the font to maximum once, and run the app once on a
device at `minSdk` 26 — all three are recorded as standing gaps and none has
ever been done.
### 2026-08-18 — Batch 02 shipped: the prediction engine, and three bugs the tests found
All five Batch 02 issues closed and the milestone closed with them. The app now

View File

@ -13,6 +13,40 @@ Review trigger: Any QA round run
> like a pass that succeeded, and that is how untested code ships believing it
> was tested.
## Round 2 — 2026-08-18 at `19edf4c`, partial
Batch 03 built every screen the app has, and each was driven by hand on the
emulator as it landed rather than in one pass at the end. Same environment:
`PeriodQA`, API 36, Pixel 6 profile, debug build.
| Pass | Result | Notes |
| --- | --- | --- |
| A — First run | **Pass** | Clean install reaches onboarding; all seven screens walked; the flow produces a forecast and a relaunch goes straight to Today. |
| B — Core loop | **Pass** | Two-tap logging confirmed on the device: "Started period" → "Yes — today" → "Logged ✓". Editing, ending, and spotting reclassification all exercised. |
| C — Failure paths | **Partial** | Duplicate-date logging, an end date before a start, and a future date in the picker all handled. Airplane mode, denied permissions and a process killed mid-write still untried. |
| D — Persistence | **Partial** | Onboarding completion, records and settings all survive force-stop and relaunch. Reboot and update-over-install untried. |
| E — Forecast under hard histories | **Partial** | The §51 cases pass as unit tests against both engines, and the not-yet path was driven through the UI. The variable and outlier histories have still not been entered by hand. |
| F — Notification privacy | **Not run** | Nothing sends a notification yet — Batch 05. The onboarding *choice* was verified: Discreet is selected before the user touches anything. |
| G — Accessibility | **Partial** | Every calendar day, the confidence indicator and the hero countdown carry content descriptions, checked by reading the view hierarchy. **The calendar was verified in actual greyscale** and all five marks remain distinguishable. TalkBack itself, and font scaling, still untried. |
| H — Data ownership | **Partial** | Delete-all covered by an instrumented test. Export, app lock and artifact inspection do not exist yet. |
### What driving it found that tests did not
Three defects, none of which any unit test would have caught:
1. **Dark mode was broken for the whole of Batch 01.** `PeriodTheme` never
wrapped its content in a `Surface`, so text without an explicit colour
inherited black and the app background never painted. Light mode looked
correct by accident.
2. **"Period ended" appeared to do nothing.** The logic was right — a period
ending today still includes today — but the screen was identical afterwards,
so the button read as broken.
3. **Today's underline collided with the spotting dot**, on the one day that was
both. Invisible in the colour screenshot, obvious in greyscale.
The pattern is now four rounds old and worth stating as a rule: **the defects in
this project are found by opening it, not by reading it.**
## Round 1 — 2026-08-18 at `adc5075`, partial
Not a full round. Batch 01 produced the first build, and this covered the two
@ -74,6 +108,12 @@ at its own `minSdk`.**
Things no round has ever covered, carried forward until they are. This list
existing is not a failure; it not existing while the gaps do is.
- **TalkBack has never actually been run.** Content descriptions are written and
were checked by reading the view hierarchy, which proves they exist and not
that they make sense in sequence. Pass G is not complete until somebody
navigates a screen with their eyes shut.
- **Font scaling untried.** The hero number is 72sp; at the largest accessibility
scale it may not fit beside anything.
- **No device at `minSdk`.** Everything so far ran on API 36. The two NewApi
bugs above would have crashed on Android 8 through 13 and nothing except lint
could see them. Lint is a good guard and it is not a substitute for one run on

View File

@ -19,19 +19,22 @@ Review trigger: Any QA round run
## Current run-state
- **Last QA round:** Round 1 — 2026-08-18, partial (passes A and B; C, D and H partial)
- **Last verified build SHA:** `adc5075`
- **Last QA round:** Round 2 — 2026-08-18, partial (A and B pass; C, D, E, G and H partial; F not applicable yet)
- **Last verified build SHA:** `19edf4c`
- **Last tested device / environment:** emulator `PeriodQA`, API 36, Pixel 6 profile, debug build
- **Overall status:** The Batch 01 foundation works end to end on a device — log
a period, see a forecast with an honest window and confidence, edit it and
watch the forecast move — and the first partial QA round found two defects
that 70 passing unit tests could not: tapping the app's primary button twice
crashed it, and two date APIs on the recalculation path would have crashed
every device below Android 14. Both are fixed, with regression tests. That
ratio is the honest summary of where this project stands: the logic is well
covered and the product has barely been used, so the next round matters more
than the last one. Nothing has been tested at the minimum Android version this
app claims to support.
- **Overall status:** Three batches are done and the app is now a real product
you can use end to end: onboarding that ends in a forecast, a Today screen
whose six states each say something different and true, two-tap logging, a
calendar whose marks survive greyscale, and an Insights screen that mostly
declines to make claims it has not earned. The prediction engine is the one
§12 specifies and is measurably better than the prototype it replaced. What
the rounds keep showing is that this project's defects are found by opening
the app rather than by reading it — dark mode was broken for an entire batch
with 129 tests green, and the calendar's marks collided in a way only a
greyscale screenshot revealed. The gaps that matter now are the ones nothing
has touched: TalkBack has never been run, text has never been scaled up, and
nothing has run on a device at the minimum Android version this app claims to
support.
## Open defects