docs: accept wave 5; record HAZARD #8 (guard can die without its sentinel)

The wave-guard was killed after its 11:13 renewal and never wrote
logs/WAVE5-DONE, despite the worker succeeding at 11:21. That makes this
file's own first-command heuristic actively misleading — "no sentinel +
no processes -> workers were KILLED" would have thrown away a completed,
verified wave. Recorded the reliable signals instead: the size of
logs/<name>.json and the tail of logs/<name>.state.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Sprite
2026-09-09 12:46:49 +00:00
co-authored by claude
parent 93f972b7d1
commit dd3a61fc33
2 changed files with 60 additions and 0 deletions
+38
View File
@@ -373,3 +373,41 @@ that.
worth doing on its own merits but no longer the leading theory), R8 still off so 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), 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`. 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/<name>.json` — 0 bytes means killed; non-zero means it finished.
2. `tail logs/<name>.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/<name>.state` is.
+22
View File
@@ -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/<name>.json (5695 bytes here — a killed worker leaves 0) plus the
tail of logs/<name>.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.