Tyrell Build 20 canary r2 was safely rolled back after a lid-close
sleep invalidated sample continuity; exact Build 20 was then relaunched
only on rdmbair15m5 as r3 from a fresh 24-hour endpoint
with AC/open-clamshell gates and two independently verified
sleep-prevention assertions.
Detailed changelog
Scope
- Host changed:
rdmbair15m5only. - Project: Tyrell, production mode.
- Tickets:
ISSUE-20260912-14,TASK-20260911-01,ISSUE-20260912-01. - No other fleet host was installed, restarted, or authorized for rollout.
Incident and decision
- R2 ran the unchanged fail-closed guard under a verified
PreventUserIdleSystemSleepassertion. - At
19:02:11 EDT, after changing to battery power, the MacBook entered a 50-second Maintenance Sleep. The19:03:01wake reason includedlidand HID activity. Lid-close sleep overridescaffeinate -i. - All 32 stored r2 sample gaps were at most
60.138815seconds. The failure boundary was only20,923,640physical bytes. R2 is product-inconclusive, not a memory rejection. - The guard restored exact Build 15/17 at
19:03:38. An orderly host reboot followed at19:11:23, after rollback. - R3 was started only after the rebooted host was on AC power with the
clamshell open. Its wrapper binds both
PreventSystemSleepandPreventUserIdleSystemSleepto the guard lifetime. Forced restart or lid closure remains fail-closed.
Files and installed state changed
- Preserved r2 evidence locally and canonically under
canary-r2-lid-sleep. - Created isolated r3 stage
/Users/richh/.tyrell/build20-canary-r3-20260912-96a5fc0with pinned candidate, unchanged guard/policy, installer dependencies, candidate app, exact rollback snapshot, and power-protected launch/verification scripts. - Installed exact signed/notarized Build 20 app at
/Applications/Tyrell.app. - Repointed
/Users/richh/Library/Application Support/Tyrell/bin/tyrelldthrough the pinned service installer to exact hash-addressed Build 20. - Created retained Build 17 app rollback
/Applications/.tyrell-rollbacks/20260912-192240-2c5ca2a674fe/Tyrell.app. - Retained the additive
last_seen_atdatabase column. No database was restored or replaced.
Commands and controls used
- Verified r2 state, samples, power history, failure captures, exact rollback identities, both HTTP planes, signatures, launchd state, and live database integrity.
- Copied immutable r2 evidence into the canonical Tyrell handoff and compared every file hash.
- Assembled a fresh r3 stage only from exact r2 candidate/dependency identities; verified all hashes, signature, notarized Gatekeeper assessment, and staple.
- Ran the app installer in dry-run mode before mutation.
- Ran a bounded
caffeinate -i -s /bin/sleep 5control and verified both assertions throughpmset -g assertions. - Ran
canary_guard.py prepareto snapshot exact Build 15/17 rollback state. - Installed Build 20 with the pinned app lifecycle installer.
- Launched the unchanged guard through
launch_guard_power_protected.zshand verified power, clamshell, process ancestry, assertion ownership, and live state withverify_guard_power_protected.zsh.
Verification evidence
- Build 20 daemon SHA-256:
71bf6122e453315205f3f0dfaf3f1a3a6cf2d99dfe901cda88e7ac79a8112c77. - Build 20 app executable SHA-256:
423871cede8ae6313c486929f544dbee8d1085540b2d37896de6f2c2d4de90fd. - Build 20 app canonical CDHash:
37a0081b06af970866e84877cc74524cdac750580d5fad22fb83d92d0eb0aa5c. - Guard SHA-256:
52e53684d4436919dc02f9a9f25a2ebf6b8f1ed690cc866603bc78284caaf2da; policy SHA-256:742c28971e73c62ea7a9d1158885fe2983230949a74a4125d1b70b3ea004c882. - Power-protected launcher SHA-256:
8f6e27c6914c9a8055006151cf11b84465d8b7ed3f8757e4b672a016f5ebd9ed; verifier SHA-256:b841bc75d8259ddaf5e942b2df098c8400de265149d44a220af49ccebe522a9d. - Guard PID
24726, assertion PID24750, daemon PID24853; both sleep-prevention assertions are bound to the exact guard lifetime while on AC with clamshell open. - Launchd
runs=1, never exited; stable path resolves the exact candidate release. - Status and permission endpoints on both ports returned HTTP 200 valid JSON.
- SQLite
quick_check=ok,152803file rows, one additivelast_seen_atcolumn. - Fixed 24-hour endpoint:
2026-09-13 19:25:24.602247 EDT.
Backups and preserved evidence
- Exact Build 15 daemon and Build 17 app are copied under the r3
stage's
prior/directory. - Exact Build 17 app rollback is retained under
/Applications/.tyrell-rollbacks/20260912-192240-2c5ca2a674fe/Tyrell.app. - Pre-migration database backup:
/Users/richh/Library/Application Support/Tyrell/backups/20260912-0110-build20-preflight-96a5fc0/tyrell.db, SHA-256db29432be4fc962a18436f15f29d1677b10bc7c541d7f78eab6c00f7ecce3c8f. - Canonical r2 evidence:
/Users/richh/dev/_handoff/tyrell-build20-memory-20260912/canary-r2-lid-sleep.
Undo
Stop only guard PID 24726, which also releases assertion
PID 24750, then run
/opt/homebrew/bin/python3.14 /Users/richh/.tyrell/build20-canary-r3-20260912-96a5fc0/canary_guard.py rollback.
Verify exact Build 15 daemon hash, exact Build 17 app hash, both status
ports, and live SQLite integrity afterward. Never replace the live
database with the older backup.
Outstanding work
Short, six-hour, fixed 24-hour, CPU, fresh-app, and controlled-reboot acceptance remain pending. No fleet expansion is authorized.