diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 8816221..ecec457 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -373,3 +373,41 @@ that. worth doing on its own merits but no longer the leading theory), R8 still off so the release APK is 41.8MB and too large to send over the file channel (30MB cap), where the server will live, and the two account emails for `create-user.sh`. + +## Wave 5 — G-diagnostics: COMPLETE, verified by the orchestrator 2026-09-09 +Commit `93f972b`. The app now distinguishes barcode-didn't-decode from +lookup-request-failed from genuinely-not-found; see the commit message and +`docs/METADATA-SOURCES.md`. + +| Check | Result | +|---|---| +| `assembleDebug` | exit 0 | +| `testDebugUnitTest` | exit 0 — **138 tests**, 1 skipped, 0 failures (was 107) | +| `verifyPaparazziDebug` | exit 0 | +| `assembleRelease` | exit 0 — 41,793,760 bytes, V2 signer `CN=Bookshelf` | +| boundary check | clean — no build files, no forbidden packages | +| `grep "always 'false'"` | 0 hits on touched files | + +The worker was honest this time: everything it claimed checked out. Cost $0.28, +6 turns, one quota wait that `run-task.sh` resumed correctly. + +**The orchestrator added one thing the worker's brief didn't cover:** the +manual-ISBN dialog silently discarded an unparseable entry — the same silent +failure this wave existed to eliminate, sitting just outside the prompt's scope. +It now marks the field in error and disables "Look up" until the checksum passes. +Lesson for future prompts: scope a wave by *failure class*, not by file list, or +the instances of the class that live outside the listed files survive. + +### HAZARD #8 — the wave-guard can die without writing its sentinel +`logs/WAVE5-DONE` was written BY HAND. The guard renewed at 11:13, the worker +succeeded at 11:21, and the guard neither wrote the sentinel nor logged its +"guard exiting" trap line — it was killed outright. The lease expired on its own +an hour later. + +**This breaks the first-command heuristic at the top of this file.** "no sentinel ++ pgrep count 0 -> workers were KILLED" was WRONG here: the worker had finished +successfully. Use these instead, in this order: + 1. `ls -l logs/.json` — 0 bytes means killed; non-zero means it finished. + 2. `tail logs/.state` — says SUCCESS / GIVING UP / WALL CLOCK explicitly. + 3. `git status --porcelain` — is there actually work in the tree? +The sentinel is a convenience, not the record of truth. `logs/.state` is. diff --git a/logs/WAVE5-DONE b/logs/WAVE5-DONE new file mode 100644 index 0000000..ab0d427 --- /dev/null +++ b/logs/WAVE5-DONE @@ -0,0 +1,22 @@ +=== WAVE5-DONE written BY HAND by the orchestrator, 2026-09-09 === +NOT written by tasks/wave-guard.sh. The guard renewed its lease at 11:13, the +worker reported SUCCESS at 11:21, and the guard should have noticed within 30s +and written this file. It never did, and it left no "guard exiting" line either, +so it was killed outright rather than exiting through its TERM/INT trap. The +lease then expired on its own at ~12:13. + +READ THIS BEFORE TRUSTING THE FIRST-COMMAND HEURISTIC AT THE TOP OF HANDOFF.md: +"no sentinel + pgrep 0 -> workers were KILLED" would have been WRONG here. The +worker finished successfully; only the guard died. The reliable signal is the +size of logs/.json (5695 bytes here — a killed worker leaves 0) plus the +tail of logs/.state (which says SUCCESS). + +G-diagnostics: SUCCESS after 2 attempts, 1 quota wait. cost=$0.28, turns=6. +Independently re-verified by the orchestrator: + ./tasks/gw assembleDebug exit 0 + ./tasks/gw testDebugUnitTest exit 0 - 138 tests, 1 skipped, 0 failures (was 107) + ./tasks/gw verifyPaparazziDebug exit 0 + ./tasks/gw assembleRelease exit 0 - 41,793,760 bytes, V2 signer CN=Bookshelf + boundary check clean - no build files, no forbidden packages + grep "always 'false'" 0 hits on touched files +Accepted and committed as 93f972b.