Runbook: check the running binary first; drop the unproven heal-cycle law - #153
Merged
Merged
Conversation
… heal-cycle law A verified-Fable calibration audit of the self-heal incident record flagged the "Expected steady-state" paragraph as the one materially over-claimed artifact: it generalized a single out-of-band probe measurement (n=1, a replayed session COPY) into a causal law about Google, then predicted a "~15 min heal cycle with sub-minute dips" that the project's own subsequent watch data does not show. Two live outages (2026-07-22, and 2026-07-25 for ~10.5h) had the same actual cause, which the runbook did not mention at all: a PRE-FIX .app bundle was running. Many bundles on a dev machine share CFBundleIdentifier com.openmessage.app (stale worktree builds, dated backups, the R8 rollback copy), so LaunchServices can resolve Spotlight/Dock/`open -a`/notification launches to a build without the OSID self-heal fix, which then latches needs_repair exactly like the original bug. Quitting the GUI is also not enough: BackendManager reuses an already-running backend on the port. - Lead the section with the binary check (one command, highest diagnostic yield) plus the bundle-id resolution check and explicit-path launch. - Replace the "~14 min => ~15 min heal cycle" law with what was actually observed, scoped as observation, and state plainly that the cause of varying lifetimes is not established. - "Absent/0 is the healthy ~15-minute heal cycle" -> absent/0 is the norm. - "wait ~15-60s" -> "wait ~2-3 min" (the one observed heal took 2m20s; under-waiting pushes operators into the re-pair this section warns against). Docs only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…audit A second (sol) calibration audit of the same incident record flagged two remaining assertions in this file that are not supported by the code or the retained data: - "Cookies rotate roughly every 30 minutes" is unsourced folklore. Observed hashes changed at irregular intervals on the order of tens of minutes; the cadence is not established. Reworded as observation. - "If it hasn't recovered, the cookies are genuinely gone from Chrome ... or the device link was revoked" presents two causes as exhaustive. Repair can also fail on Chrome/keychain/profile access, undecryptable cookies, a session-file write failure, or network/server rejection. Operators should read the actual repair and reconnect errors before choosing to re-pair — the re-pair this section warns against is exactly what a wrong guess here triggers. Docs only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…oped claims) A cross-family GO/NO-GO review of this PR's own diff returned NO-GO with five findings, all verified against the raw watch data and code before applying: - "two multi-hour outages ... the latter ~10.5h" was wrong twice over: the 7/22 latch was ~11 minutes, and 7/25 ran 06:54->13:21 local (~6h26m) — the 10.5h figure mixed UTC transcript timestamps with local watch timestamps. - "one cookie expiry on 7/21 and none attributable to the fixed build since" was false: fixed builds had auth_expired episodes on 7/21, 7/22 16:12, 7/23 09:56, and 7/28 21:58 — each self-healing in <=~2.5 min (three within a 60s sample). That's stronger evidence for the fix, now stated with its n. - "Cookies go stale on the order of tens of minutes" converted hash-change observations into an invalidation cadence; replaced with the instruction plus the observed failure, no cadence claim. "~3-4 min" fresh-pair deaths scoped (4x, one account, one day). - repairs_paced: a climbing count proves only that repair requests arrived faster than the floor — it does not identify why. Also documented that the supervisor currently discards the repair error detail (handleRepairResult sets Blocked without logging it), so the runbook now points at the two ways to actually see the failure reason (log stream during an attempt, or run the refresh script manually). Observability gap chipped separately. - "BackendManager reuses an already-running backend, so quitting is not enough" over-generalized code I had not fully read (it has adopt/stop logic); rescoped to the observed stale-listener hazard plus a verify-the-PID step. Docs only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…rvable except by manual reproduction Round-2 review blockers: "Absent/0 is healthy" implied the counter can clear the session (a single failed repair parks the supervisor Blocked with the counter at 0), and the suggested log-stream capture cannot reveal the repair error because the native refresh path returns errors without ever logging them. Retitle the section to what the counter is, state its exact semantics, and leave manual script execution as the only currently-actionable way to see a refresh failure (logging fix chipped). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mwhobrey
pushed a commit
to mwhobrey/om-tui
that referenced
this pull request
Aug 24, 2026
…o observed data (MaxGhenis#153) * Runbook: check the running binary first, and stop stating an unproven heal-cycle law A verified-Fable calibration audit of the self-heal incident record flagged the "Expected steady-state" paragraph as the one materially over-claimed artifact: it generalized a single out-of-band probe measurement (n=1, a replayed session COPY) into a causal law about Google, then predicted a "~15 min heal cycle with sub-minute dips" that the project's own subsequent watch data does not show. Two live outages (2026-07-22, and 2026-07-25 for ~10.5h) had the same actual cause, which the runbook did not mention at all: a PRE-FIX .app bundle was running. Many bundles on a dev machine share CFBundleIdentifier com.openmessage.app (stale worktree builds, dated backups, the R8 rollback copy), so LaunchServices can resolve Spotlight/Dock/`open -a`/notification launches to a build without the OSID self-heal fix, which then latches needs_repair exactly like the original bug. Quitting the GUI is also not enough: BackendManager reuses an already-running backend on the port. - Lead the section with the binary check (one command, highest diagnostic yield) plus the bundle-id resolution check and explicit-path launch. - Replace the "~14 min => ~15 min heal cycle" law with what was actually observed, scoped as observation, and state plainly that the cause of varying lifetimes is not established. - "Absent/0 is the healthy ~15-minute heal cycle" -> absent/0 is the norm. - "wait ~15-60s" -> "wait ~2-3 min" (the one observed heal took 2m20s; under-waiting pushes operators into the re-pair this section warns against). Docs only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Runbook: scope two more unsourced claims flagged by the cross-family audit A second (sol) calibration audit of the same incident record flagged two remaining assertions in this file that are not supported by the code or the retained data: - "Cookies rotate roughly every 30 minutes" is unsourced folklore. Observed hashes changed at irregular intervals on the order of tens of minutes; the cadence is not established. Reworded as observation. - "If it hasn't recovered, the cookies are genuinely gone from Chrome ... or the device link was revoked" presents two causes as exhaustive. Repair can also fail on Chrome/keychain/profile access, undecryptable cookies, a session-file write failure, or network/server rejection. Operators should read the actual repair and reconnect errors before choosing to re-pair — the re-pair this section warns against is exactly what a wrong guess here triggers. Docs only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Runbook: apply sol's NO-GO corrections (durations, episode record, scoped claims) A cross-family GO/NO-GO review of this PR's own diff returned NO-GO with five findings, all verified against the raw watch data and code before applying: - "two multi-hour outages ... the latter ~10.5h" was wrong twice over: the 7/22 latch was ~11 minutes, and 7/25 ran 06:54->13:21 local (~6h26m) — the 10.5h figure mixed UTC transcript timestamps with local watch timestamps. - "one cookie expiry on 7/21 and none attributable to the fixed build since" was false: fixed builds had auth_expired episodes on 7/21, 7/22 16:12, 7/23 09:56, and 7/28 21:58 — each self-healing in <=~2.5 min (three within a 60s sample). That's stronger evidence for the fix, now stated with its n. - "Cookies go stale on the order of tens of minutes" converted hash-change observations into an invalidation cadence; replaced with the instruction plus the observed failure, no cadence claim. "~3-4 min" fresh-pair deaths scoped (4x, one account, one day). - repairs_paced: a climbing count proves only that repair requests arrived faster than the floor — it does not identify why. Also documented that the supervisor currently discards the repair error detail (handleRepairResult sets Blocked without logging it), so the runbook now points at the two ways to actually see the failure reason (log stream during an attempt, or run the refresh script manually). Observability gap chipped separately. - "BackendManager reuses an already-running backend, so quitting is not enough" over-generalized code I had not fully read (it has adopt/stop logic); rescoped to the observed stale-listener hazard plus a verify-the-PID step. Docs only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Runbook: pacing counter records delays only; repair errors are unobservable except by manual reproduction Round-2 review blockers: "Absent/0 is healthy" implied the counter can clear the session (a single failed repair parks the supervisor Blocked with the counter at 0), and the suggested log-stream capture cannot reveal the repair error because the native refresh path returns errors without ever logging them. Retitle the section to what the counter is, state its exact semantics, and leave manual script execution as the only currently-actionable way to see a refresh failure (logging fix chipped). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 3567f92)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A verified-Fable calibration audit of the Google self-heal incident record (PRs #148/#151) found one materially over-claimed artifact, and two live outages exposed a diagnostic step the runbook was missing entirely.
1. The missing check that cost ~10.5 hours
Twice now the live install latched
needs_repairand it was not the self-heal failing — a pre-fix.appbundle was running. On 2026-07-25 the legacy R8 rollback bundle was launched at 06:45; Google latched at 06:54 and stayed dead ~6h26m (06:54→13:21 local; an earlier ~10.5h figure mixed UTC and local timestamps), with Chrome up and all five account cookies available the whole time (the fixed binary heals that in seconds).Cause: many bundles on a dev machine declare the same
CFBundleIdentifier com.openmessage.app(stale worktree builds, dated app-backups, the R8 rollback copy — 18 of them on this machine), so LaunchServices can resolve Spotlight/Dock/open -a OpenMessage/notification clicks to a build without the OSID fix.lsregister -dumpconfirmed the legacy path was the registered resolution. Compounding it,BackendManagerreuses an already-running backend on the port, so quitting the GUI and relaunching silently adopts the stale backend.So the section now leads with the one-command binary check, the bundle-id resolution check, and explicit-path launch.
2. The over-claim
The old text stated as fact:
That generalized one out-of-band probe measurement (n=1, replaying a session copy, forcing refreshes) into a causal law about Google's behavior, then into a steady-state prediction the project's own watch data does not support — the live app showed one cookie expiry in a 15h watch, not a 15-minute cycle. "Sub-minute dips" was wrong even for the single observed heal (2m20s).
Replaced with what was actually observed, scoped as observation, plus an explicit "why lifetimes differ is not established." Also:
Absent/0 is the healthy ~15-minute heal cycle→ absent/0 is simply the norm; andwait ~15-60s→wait ~2-3 min, since under-waiting funnels operators into the re-pair the same section warns against.Docs only, no behavior change.