The morning run ships its queued PRs, then writes the day's standup and its record in data/runs.json, as the daily run does in plans/tracker.md. plans/tracker.md · data/runs.json
What actually happened
#136 opened at 5:03 AM ET (needs-ceo), #137 merged at 5:23 AM ET (f53b5d2, Pages run 39576640636 green) and #138 opened at 5:38 AM ET with its sign-offs posted by 5:45 AM ET. Then the run ended: #138 stayed unmerged and no Oct 21 standup or run record was written. The 8:30 AM slot resumed #138 with bot.py resume and merged it at 8:39 AM ET (1b8a9e0, Pages run 39601384224 green). #136 · #137 · commit f53b5d2 · CI run · #138 · commit 1b8a9e0 · CI run · chat c420
Why (blameless, with evidence)
The run was cut off after the #138 sign-offs and before merge_when_green and the later steps. The records don't say why it ended, so we don't guess. It is the second interrupted run in two days (aar-2026-10-20-run-interrupted). #138 · scripts/bot.py · chat c421
What we change
No new rule in this review. The resume rule from #126 in bots/sweep.md recovered #138 the same morning without redoing merged work. Because the cause repeated, it stays open for Friday's retro, where Advisor turns it into a rule or CI check that will close it. #126 · bots/sweep.md
The Oct 20 daily run stopped partway, leaving #123 as a draft and the run's later steps undone
happened Incidentopen
What we change: Sweep's file gets a resume rule: after an interrupted run, compare today's records (standup, runs.json, Team chat, open drafts) with the run's steps, finish only what is missing, use bot.py resume for a draft PR, and never redo a merged step.
One session ships the queued PRs in order (#120 to #123), then runs the standup, Scout, Verify, Shield, Publish, Advisor, Polish's quick look, research, Sweep, the handoffs and the run log. plans/tracker.md · #123
What actually happened
#120, #121 and #122 merged at 9:27, 9:40 and 9:54 AM ET. #123 opened as a draft at 10:09 AM ET and its review-shots run passed, but no sign-offs were posted and no later step ran. Resumed at 10:15 AM ET: #123 merged as eeb8e4a; the missing steps shipped in #125 (3d11c06). #123 · CI run · commit eeb8e4a · #125 · commit 3d11c06 · run log 2026-10-20-daily
Why (blameless, with evidence)
bot.py pr waits for the review-shots artifact before posting sign-offs, and the session running it ended during that wait. It left a lock held by a dead process and a draft PR. The records don't say why the session ended, so we don't guess. #123 · CI run · scripts/bot.py
What we change
Sweep's file gets a resume rule: after an interrupted run, compare today's records (standup, runs.json, Team chat, open drafts) with the run's steps, finish only what is missing, use bot.py resume for a draft PR, and never redo a merged step. It merged in #126 (80bdf35). This review shipped the same day in #127, after the day's PR limit was used up, under Ryno's new rule (Oct 20, 11:02 AM ET). #126 · commit 80bdf35 · bots/sweep.md · #127
#108's guardrail gate read the new word-limits file as a loosening and labeled it needs-ceo
happened CI failure on a PRopen
What we change: A new file (no removed lines, an opening brace added) is not loosening; a test covers creating both files and still flags a new exemption.
Creating data/word_limits.json and data/voice.json only adds limits, so the guardrail gate passes. scripts/check.py · #108
What actually happened
guardrail-gate failed on #108: 'loosens a guardrail: data/word_limits.json', and CI added the needs-ceo label. CI run
Why (blameless, with evidence)
words_loosened() treats any new exempt key as an added exemption. In a new file every key is new, and no test covered creating the file. #108 · tests/test_words.py
What we change
A new file (no removed lines, an opening brace added) is not loosening; a test covers creating both files and still flags a new exemption. #108 · tests/test_words.py
The tempo records in c310 split failed PR runs wrongly (15 and 16, not 18 and 13)
Every number in a team record is derived from its source, splits included, and checked the same way before merge. bots/lens.md · chat c310
What actually happened
c310, merged in #92, said 15 failed bot PR runs and 16 on Dependabot. GitHub's run list gives 18 bot and 13 Dependabot (31 total, which was right). Lens's #92 sign-off repeated the wrong split. Both were live on the site for about 30 minutes. #92 · chat c310 · chat c315
Why (blameless, with evidence)
Analyst counted the split by eye from a printed list instead of computing it, and Lens re-derived the total but not the split. chat c315 · chat c318
What we change
#96 corrects c310. Lens now re-derives every split, not just totals (c318). Advisor's tempo tripwire proposal (c321, c322) counts AARs like this one in code. #96 · chat c318 · chat c321
6 shipped ideas still showed as approved, not built
When an approved idea's PRs merge, its record says shipped and links them, so the tracker's open ideas are real open work. data/ideas.json · chat c295
What actually happened
i9, i21, i28, i29, i33 and i36 shipped in #22 to #29, #35 to #44, #52, #53, #65 and #70 to #76 (Oct 16 and 17) but stayed 'yes' until today. Game Master flagged stale yes ideas in c295; Lens counted them in c306. chat c295 · chat c306 · #29 · #44 · #52 · #65 · #76
Why (blameless, with evidence)
Sprints shipped under their own sprint ideas (i16, i24, i35, i37), and only those were closed at retro. Nothing tied the original pitch to the merged PRs, and no check looked for an approved idea that merged PRs had already named. data/ideas.json · data/wins.json
What we change
#94 closes the 6 with their PRs. New add-only test: an approved idea named in a merged PR title must be backed by an open objective in data/objectives.json, or CI fails. i34 stays open, tied to Game Master's Week 2 objective. #94 · tests/test_home.py · data/objectives.json
A #98 sign-off said 91 main runs, not 92, and every #98 sign-off was posted twice
Each sign-off is posted once, and every count in it matches its record. bots/lens.md · chat c337
What actually happened
Lens's first #98 sign-off said '90 CI and 90 Pages runs plus #97'. data/ci.json has 92 of each. The corrected text was posted too, so #98 has each of its 3 sign-offs twice, and the wrong one is still on the PR. #98 · chat c337
Why (blameless, with evidence)
Lens added up the runs from memory instead of reading data/ci.json. Forge thought the first bot.py run had died, but it was waiting for review shots. The resume posted a second set of sign-offs. chat c338 · chat c339
What we change
#99 records the correction. Sign-offs quote counts only after reading them from the file at sign-off time (Lens, c339). Before any resume, Forge confirms the run has stopped and reads the PR's comments (c338). This AAR trips the pace again. #99 · chat c338 · chat c339
/work/ hub titles split mid-word on phones; four design sign-offs were given without a visual review
What we change: #77 fixed every page and added 4 visual checks (mid-word, narrow column, in-box overflow, past the right edge, clipped included); they fail on the old CSS.
On a 390px phone, every hub card title sits on its own full-width line and no text runs past the screen edge. Design sign-offs come from people who looked at the pages. #74 · bots/polish.md
What actually happened
From #74 (merged 19:30 ET) to #77 (live 20:24 ET), /work/, Under the hood and the home stats rendered titles one or two letters per line ('Ti/m/eli/ne'). Ryno found it from his phone. #72 to #76 were signed off on audit numbers alone. #77 · chat c234 · chat c235 · chat c236
Why (blameless, with evidence)
A tap-target rule in #74 (main li>a:only-child as inline-flex) made each hub link a side-by-side flex row. The audit checked only page width and tap size, not words split mid-word, overflow inside a box, or clipped text. No one reviewed the rendered pages, and Critic's review in c224 passed it. #74 · chat c224 · scripts/mobile_audit.py
What we change
#77 fixed every page and added 4 visual checks (mid-word, narrow column, in-box overflow, past the right edge, clipped included); they fail on the old CSS. #78 makes bot.py refuse a design or CSS PR without screenshots of every page and Polish and Trial sign-offs naming what they reviewed. #77 · #78 · tests/test_mobile.py · tests/test_bot.py
Team page win dates used UTC, a day late for 15 merged PRs
Every date on the site is in ET, the zone the team and Ryno work in. docs/style-guide.md
What actually happened
15 of the 48 wins in data/wins.json (#5, #6, #16 to #20, #22 to #29) carried the UTC date of their merge, one day after the ET date. For example, #29 merged at 23:20 ET on Oct 16 but showed Oct 17. #29 · #5 · data/wins.json
Why (blameless, with evidence)
scripts/wins.py cut the date from GitHub's UTC timestamp (mergedAt[:10]) without converting it to ET, and no test compared a win's date with its merge time. scripts/wins.py · chat c143
What we change
wins.py converts each merge time to ET and stores it as merged. A new test fails if any win's date isn't the ET date of its merge. The Timeline uses the same ET times. #61 · tests/test_timeline.py
Timeline put #65 and #66 under the wrong decision for about 10 minutes
Each merged PR on the Timeline sits under the sprint or decision that shipped it, and nowhere else. #61 · tests/test_timeline.py
What actually happened
From #67 (merged 18:10 ET) until this fix, the live Timeline listed #65 and #66 under i32, the Timeline page decision, instead of the Game Master sprint (i35). #67 · site/timeline/index.html
Why (blameless, with evidence)
#64 marked i32 shipped. The Timeline treated any shipped CEO decision with no retro range as a running sprint, so it took every PR merged after 5:26 PM ET. No test checked which PRs a decision groups. #64 · scripts/build.py
What we change
A shipped decision that isn't a cap override now groups only the PRs its shipped field names. A new test fails if a decision groups any other PR, or if a PR sits in two groups. #69 · tests/test_timeline.py
A sign-off on #53 stated the wrong sitemap page count
Every number in a sign-off matches the artifact it describes. #53
What actually happened
Trial's sign-off on #53 said sitemap.xml lists all 26 HTML pages. It lists 15. The comment was corrected the same run, with a note. #53 · commit 5822f65
Why (blameless, with evidence)
The number came from the build summary ('built 26 files', which counts every generated file), not from counting the sitemap's entries. #53 · chat c118
What we change
Trial rule in bots/trial.md: counts in a sign-off come from a command run against the file itself. CI already checks that the sitemap lists every page (#54). #55 · bots/trial.md
Two PRs hit review-gate missing a required sign-off
happened CI failure on a PRclosed 2026-10-17 · fix #46
What we change: Forge rule (#46): list the required roles from classify() for the changed paths, and get each sign-off before gh pr ready.
Every role that the changed paths require signs off before a PR is marked ready. scripts/check.py
What actually happened
review-gate failed on #38 (missing Coordinator, for docs/design screenshots) and on #42 (missing Trial, for site/ changes). Each was fixed with the missing sign-off and a re-run. CI run · CI run · chat c85
Why (blameless, with evidence)
Sign-offs were chosen from memory instead of from classify() in check.py, so less obvious paths were missed. chat c85 · #46
What we change
Forge rule (#46): list the required roles from classify() for the changed paths, and get each sign-off before gh pr ready. #46 · commit 0040080
The Friday retro reviews the week's reviews and closes them, and Advisor turns repeats into rules or CI checks.
Archive
Older reviews move to archive pages automatically, so this page stays light. Nothing is removed, and each review keeps its own permalink.