docs: log Batch 06 closing, four new guards, and an emulator that was not mine
Step 6 of WORK_CYCLE. Next action is filing Batch 07's issues: Monetization is an open milestone with zero issues, so the largest remaining body of code is described nowhere and is missing from the denominator the project screen reports. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6591951c8d
commit
25102269d9
|
|
@ -32,6 +32,95 @@ written and stay true. It is exempt from review for the same reason a receipt is
|
||||||
|
|
||||||
## Entries
|
## Entries
|
||||||
|
|
||||||
|
### 2026-08-19 (later) — Batch 06 closed, and four guards that can now fail
|
||||||
|
|
||||||
|
Export, the privacy promise, the themed-drawable guard and the notification icon
|
||||||
|
all landed, and **Batch 06 is closed** with seven issues in it. The tracker has
|
||||||
|
three issues left and none of them is code: two need artwork, and the third
|
||||||
|
(#31, the incognito launcher) says in its own body that the alias must land with
|
||||||
|
§32's toggle rather than ahead of it.
|
||||||
|
|
||||||
|
**#35, export.** One pretty-printed JSON file, plaintext, written straight into
|
||||||
|
a document the user picked through the Storage Access Framework. No copy in
|
||||||
|
`cacheDir`, no `FileProvider`, no path handed to another app — and a test walks
|
||||||
|
`cacheDir` afterwards and requires it empty, which fails the moment anybody
|
||||||
|
reintroduces write-then-share.
|
||||||
|
|
||||||
|
The format is pinned **byte-for-byte** against a committed golden file, because
|
||||||
|
the issue is right that it outlives the batch: whatever ships first is what
|
||||||
|
people's archives are in. It also renders identically in UTC, +14 and −12,
|
||||||
|
because `Converters.kt` stores a `LocalDate` as its epoch day precisely so it
|
||||||
|
"cannot carry a timezone by accident" and a zone-aware formatter here would be
|
||||||
|
off by one day for everybody east or west of whoever wrote it.
|
||||||
|
|
||||||
|
**Plaintext was the decision, and it reverses an earlier note in this file.**
|
||||||
|
The entry above records the next action as "export with the file encrypted".
|
||||||
|
That is wrong, and `SECURITY.md` now says why: the export is the copy that makes
|
||||||
|
a lost Keystore key survivable rather than final — the exact condition written
|
||||||
|
down for ever revisiting database encryption. A passphrase would reproduce the
|
||||||
|
failure that decision avoided, and nothing, including this app, could open the
|
||||||
|
result.
|
||||||
|
|
||||||
|
"Only the user's own data" is enforced structurally rather than by review:
|
||||||
|
`:core:export` is pure JVM and depends on `:domain:cycle` alone, so `Prediction`,
|
||||||
|
`FertilityEstimate` and `android.os.Build` are not on its classpath. Adding a
|
||||||
|
forecast does not compile.
|
||||||
|
|
||||||
|
**Four guards exist now that did not, and each was watched failing.**
|
||||||
|
|
||||||
|
- `checkThemedDrawables` (#42) — every drawable has a night twin, both
|
||||||
|
directions. `prove-guard.sh` cannot drive it, because it replaces a string
|
||||||
|
in a file and this guard's failure mode is a file that is *not there*, in a
|
||||||
|
set that is all `.webp`. GUARDS.md §9 records that class.
|
||||||
|
- `checkNoSharedStorageWrites` — §45's shared-storage ban was enforced by
|
||||||
|
nobody having typed it. `checkPermissions` structurally cannot see it: it
|
||||||
|
matches `<uses-permission>`, and a `<provider>` declaring `FileProvider`
|
||||||
|
merges green.
|
||||||
|
- `checkNoHealthLogging` completeness — a module missing from
|
||||||
|
`modulesSeeingHealthData` was silently exempt with a green build. Both
|
||||||
|
`:core:security` and `:core:export` would have gone through that hole.
|
||||||
|
- `checkPermissions` narrowed — it was reading `merged_manifest/debugUnitTest`
|
||||||
|
and failed on `REORDER_TASKS`, a test-runner permission that does not ship.
|
||||||
|
The tempting fix was to allowlist it, which would have permitted it in the
|
||||||
|
real manifest too and quietly undone the guard.
|
||||||
|
|
||||||
|
**Three defects found that nobody was looking for.**
|
||||||
|
|
||||||
|
1. `NotificationPrivacyTest` could never run on `PeriodMinSdk26`.
|
||||||
|
`GrantPermissionRule` asked for `POST_NOTIFICATIONS` unconditionally, and
|
||||||
|
that permission arrived in API 33 — so every test in the class errored
|
||||||
|
before its first assertion, on the one emulator where it mattered. The class
|
||||||
|
guards what a locked screen shows.
|
||||||
|
2. No Robolectric test in `:app` could read a string resource.
|
||||||
|
`unitTests.isIncludeAndroidResources` was never set there, so the module
|
||||||
|
owning nearly all the user-facing copy was the one whose copy could not be
|
||||||
|
tested.
|
||||||
|
3. `prove-guard.sh`, a third time: a `PROVE_GUARD_FAIL_PATTERN` matching
|
||||||
|
**nothing** gives the same "caught it, and only it" verdict as one matching
|
||||||
|
once. The empty `--- what failed ---` block is the tell, and GUARDS.md §8
|
||||||
|
now says to read it.
|
||||||
|
|
||||||
|
**A mistake worth recording.** Looking for a device to verify the export on, I
|
||||||
|
installed the debug APK onto whatever `adb` reported and drove it — and it was
|
||||||
|
the **FruitFall** emulator, running another project's app. My package is
|
||||||
|
uninstalled and their app was left running, but the lesson is that a device on
|
||||||
|
`adb devices` is not evidence of a device that is mine. The export's on-device
|
||||||
|
checks are three new rows in `SECURITY_CHECKLIST.md` rather than a claim.
|
||||||
|
|
||||||
|
**What this proved:** 261 JVM tests, none skipped. Five guards green, four of
|
||||||
|
them proved able to fail today.
|
||||||
|
|
||||||
|
**Next action:** file Batch 07's issues. Monetization is an open milestone with
|
||||||
|
**zero issues**, closed or open, so the largest remaining body of code in this
|
||||||
|
project is described nowhere — which also means the 84% figure on the project
|
||||||
|
screen is measured against a denominator that excludes it. Ads and billing need
|
||||||
|
scoping before they need writing, and §34's advertising boundary is the part
|
||||||
|
that most needs stating before anybody starts.
|
||||||
|
|
||||||
|
**Blockers:** none for code. #31 waits on §32's toggle by its own instruction,
|
||||||
|
#32 and #44 need artwork, and the public privacy page — which #37's Privacy
|
||||||
|
Policy row waits on — is site-side work no agent here can do.
|
||||||
|
|
||||||
### 2026-08-19 — The app lock, and three defects only testing found
|
### 2026-08-19 — The app lock, and three defects only testing found
|
||||||
|
|
||||||
#34 is closed. The app asks for a PIN before it opens, and a forgotten PIN
|
#34 is closed. The app asks for a PIN before it opens, and a forgotten PIN
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue