The queue moved
one step downstream.
Fifty-six merged this week, fourteen of them today. The review backlog this deck was built to complain about got worked during the meeting — twenty PRs are now approved and green. None of them are merged. That is a better problem than the one we started with, and it is a different one.
/internal/decks.merged:>=2026-08-06, plus live milestone and branch state read today. Nothing is from memory. Where a number is a proxy for something it does not really measure, the slide says so.How this half hour runs
1 · What shipped
A week of two repos, and the first thing we have ever published for other people to use.
2 · Notices
Four things that are true right now and that you would not know from any single ticket. One of them is that a safety control could not be run.
3 · Decisions
Four calls, each with a recommendation. Last week there were seven and none of them closed — so this block starts by admitting that.
4 · Release readiness
What is in today’s release, what is genuinely ready per release number, and which open PRs are safe to group in.
5 · Velocity
Output is not the problem. Merge throughput is. What that changes.
∞ · Goblins
Deadlines are still made up.
Aug 6 → Aug 13
themultiverse.school — 39
| 8 | Class pages & track UI |
| 8 | Docs, process & review checklist |
| 7 | Student tools & engagement analytics |
| 6 | Class editor & the classroom link |
| 4 | Error bridge & audit logging |
| 6 | Everything else — forms, GDPR, scholarship, decks, members |
multiversecampus — 12
| 3 | Releases cut — 1.14.2, 1.14.3, 1.14.4 |
| 4 | Docs & specs, incl. the Matrix runtime plan |
| 4 | Agent & RAG repairs |
| 1 | Build — native toolchain out of the image |
What each person shipped
Nobody has to ask “where is class?” again
Every class now has one durable, permanent link that keeps working, and a Google Meet room it generates for itself. The old failure was a student standing outside a door they could not find, five minutes late, in a chat log from three weeks ago. That is just gone now. 3,346 lines, and the follow-up (#847) went back and made the calendar show local time and made the Matrix failure say what actually broke instead of shrugging.
Five merges, and every one of them is about not lying
#849 stopped two bulk senders from mailing students who had asked to be erased — that is a GDPR obligation we were quietly failing. #773 put real stack frames on auto-filed issues, so an error report is now actionable instead of decorative. On campus, #1097 means an agent asked for a tool that does not exist no longer silently discards the entire turn. #842 gave us RFC 8288 / RFC 9727 agent discovery — Megs deciding the API should be legible to machines before anyone asked. And #808 deleted a dead experiment rather than leaving it to rot: −408 lines, which is its own kind of honesty.
The Social Budget, and a privacy guarantee that is enforced, not promised
A Dunbar-number workbench shipped as a real tool. The interesting part is #897: engagement analytics count that a student moved a knob, and the server refuses to record which knob or what value on a confidential tool. The guarantee is enforced server-side rather than documented client-side — which is the difference between a privacy policy and a privacy property.
Every public form was frozen on “Submitting…”
Eight lines. Every public form on the site. This is the week’s best argument for the review queue being the constraint rather than the writing — the fix took minutes and the bug was live.
Also merged: the class editor got a desktop layout and an in-page Matrix room (#838, #840); lizthedotdev closed audit-logging gaps across db_api, sql_agent, jobs and the MCP client (#695); the Front Page Audit and Pricing Bench landed (#753); and #891 stopped the error bridge filing GitHub issues from non-production environments.
We published something for other people
shipping-skills went public on Aug 10. Nine Claude Code skills for the part of software development that agents make harder, not easier.
It is the first thing this team has shipped that is not a class, a platform feature, or an internal doc — it is a tool for other people who have the same problem we have. The framing in the README is the honest one: “You build a great deal, very fast, and take one step forward and two steps back without noticing.”
| Skill | Covers |
|---|---|
| bootstrap-hosting | A box, a PaaS, a CDN, a vault |
| release-process | Branches, previews, who may promote |
| version-and-claim | Semver, cohorts, falsifiable claims |
| wire-telemetry | Errors→issues, SLOs you can measure |
| verify-release | Human-walkable plans, review at volume |
| explain-this-project | Docs for the operator, not the agent |
| agent-personas | 14 worked expert reviewers |
| run-a-campaign | Builder / breaker / reviewer roles |
| detect-drift | Docs and tests that stopped matching |
True right now, and not in any one ticket
Today’s integration branch is missing today’s security fix
release/school-2026-08-13-integration was built through PR #833 and has not moved since Aug 10. Everything from #835 up is absent — including #894, the only open PR carrying the 4.2.304 milestone. #894 closes a Stripe Connect hole: sponsorship donations are identified purely by Stripe metadata, so an onboarded Connect teacher can attach type=scholarship_slot_donation to their own payment link with any class_id, keep the money in their own balance, and still have the reconciler mint funded scholarship seats. Promoting the branch as-is ships the release without the fix.
Worse: the branch damaged itself. Its conflict resolutions took “theirs” on two scripts and silently dropped production’s entries. deploy_job_runner.sh lost google_meet.py and classroom_link.py from PARENT_MODULES — the second has an in-repo comment saying its absence reverts class emails and calendar invites to raw meeting URLs. That is this week’s headline feature quietly undone by a merge. ci-check.sh lost three modules from CORE_MODULES, and that loop only warns, so it fails silently. Both files still pass bash -n.
The unit suite has never run on the PR gate
ci/hetzner-lint is the only gate we have. It calls ci-check.sh, whose test phase is guarded by if command -v docker — and on failure takes the warn branch, not fail. I checked the runner today: ci-runner-webhook has no docker binary and no /var/run/docker.sock. So the test phase has been silently skipping, and every green check on every PR in the queue means lint only.
Downstream of that, the suite it would have run collects tests/python/*_unit.py — 98 of the 185 files in that directory. Two PRs were shaped by the blind spot: #792 ships a test calling _has_available_scholarship_slot, which does not exist on production (verified, zero hits), and #816’s adversarial file is named *_adversarial.py, so it could never be collected either. A check that cannot go red is decoration.
Two credential-hygiene items are open
- School #865 — a credential-in-logs item, tracked privately.
- School #878 — a credential rotation and history-purge item, tracked privately.
Merging these PRs does not remediate either one. Rotation is a separate, manual action and it is yours.
Campus has three different version numbers in play
Production is on 1.14.4. The integration branch is named 1.17.x and is CONFLICTING against main despite 18 clean merges, a green smoke test and a written test plan. The next unstable milestone is 1.15.0 — and there are still two milestones with that exact name, one holding 97 open issues and one holding 19. That duplicate was Decision 2 on the Aug 6 deck.
The constraint moved — twice
This deck was drafted saying the bottleneck had stopped being writing code and become reviewing it. Between the draft and this slide, twenty PRs were approved. The review wall is gone. The merge wall is not.
| State | n | What it means |
|---|---|---|
| Approved + green | 20 | Nothing human is blocking these |
… clean on production | 16 | Mergeable right now |
| … BEHIND or stacked | 4 | #852, #873 stacked; #871, #888 need a rebase |
| Review required | 32 | The remaining backlog |
server.py, so merge one and rebase the other.My instance of the failure mode, again: #907 is on that list. It is my own manual-publishing script, approved and green, and I did not merge it before writing this slide.
The three that did not get approved
#872 (stored XSS from the public intake form), #865 (a credential written to the log stack on every connect) and #878 (an eleven-month credential exposure) are all still REVIEW_REQUIRED.
Not a judgement call — all three are BEHIND or DIRTY, so they need a rebase before anyone can even evaluate them. The mechanism is that stale branches drop out of the review flow silently, and the security fixes are the oldest branches. Rebase those three first and they rejoin the queue.
One down, three live
prod↔main reconcile. Those branches were 171 and 209 commits apart on Aug 6; today they are 1 and 4. It is worth asking why that one landed and the other six did not: it was the only one with a named cutover and a person doing it, rather than a question awaiting an answer. That observation is Decision 4.4.2.304 shipped as a stream, not a branch
The recommendation was “narrowed B” — add #894 alone rather than rebuild the branch. That is what happened: #894 merged straight to production, closing the Connect hole, and fourteen PRs landed today without going through release/school-2026-08-13-integration at all. That branch is now DIRTY with 2 of its 16 PRs landed — it has been overtaken and should be closed rather than fixed. The real question is no longer this release; it is Decision 2.
Rotate now, or wait for the PRs to merge?
Two credential-hygiene items are outstanding. Specifics are deliberately not on this page — see the internal copy. Merging #865 and #878 fixes neither — and both are now stale enough (BEHIND, DIRTY) that they were skipped in today’s approval sweep. A: rotate all three today, independently of the release. B: bundle rotation into the secrets-hot-swap work (#287), which has been open since June.
Recommend A. B is how these became eleven months old. Tier 3 — secrets. This is the one item on the deck I would not let slide past this meeting.
The 38 unmilestoned PRs — sequence or close?
72% of the open school queue carries no release number, so it cannot be planned and no release sweep will pick it up. A: triage all 38 into 4.2.404 / 4.2.504 / 4.3.0. B: make “unmilestoned and older than 14 days” a standing close-candidate rule.
Recommend A now, B as a standing rule from next cycle. Only 4 are older than 14 days, so B costs almost nothing today and stops the recurrence. If we do not decide, the milestone numbers keep describing a minority of the work.
Do decisions get an owner and a date, or stay advisory?
Seven went out; none came back. A: each deck decision becomes a GitHub issue in a Decisions milestone with your name and a due date, so it appears in the same sweep as everything else. B: accept that decisions land in conversation and stop tracking closure.
Recommend A. B is honest, but it makes this block theatre — and this block is why the meeting exists. If we do not decide, next week’s deck opens with “zero of eleven.”
The integration branch lost
Three sources disagreed all week: what the milestone claimed, what was in the integration branch, and what would actually merge. Today the third one won outright — work went to production directly and the branch was left behind.
| Release | Preview branch | Landed | Open, milestoned | State |
|---|---|---|---|---|
| 4.2.204 — Aug 6 | none | — | 2 | Overdue #700, #712 — #712 is approved and clean |
| 4.2.304 — today | …08-13-integration (#834, draft) | 2 / 16 | 0 | Abandoned DIRTY; overtaken by 14 direct merges |
| 4.2.404 — Aug 20 | none | — | 1 | Unstarted |
| 4.2.504 — Aug 27 | none | — | 2 | Unstarted #882 conflicting |
| campus 1.17.x | release/campus-1.17.x-integration (#1171) | 18 | — | Conflicting vs main; name disputed |
What the week actually proved
A long-lived integration branch built at the end of a window loses a race against the work it is trying to contain. #834 spent three days accumulating conflicts and shipped two of its sixteen PRs; the other fourteen things that went live today simply went round it. Close #834 — do not repair it. Its PRs are individually open, reviewed and mergeable.
The fix is the one we already published
Cut the branch at the start of the window and let PRs merge into it continuously; the branch then is the release and cannot go stale. That is release-process in shipping-skills, which we shipped publicly on Aug 10 and have still not adopted. This week is the argument for adopting it.
Fourteen merges, straight to production
This is 4.2.304 as it really happened — not the branch’s contents. Full notes: docs/releases/4.2.304-2026-08-13.md.
The one that mattered
#894 — sponsorship donations were identified purely by Stripe metadata, so an onboarded Connect teacher could attach type=scholarship_slot_donation with any class_id to their own payment link, keep the money in their own balance, and still have the reconciler mint funded scholarship seats. Also fixed a fourth purchase-driven enroller that was enrolling the donor. Merged alone, as its author asked.
Also live
#910 scholarship applications encrypted at rest, reading both shapes during transition. #897 the knob-privacy guarantee enforced server-side. #891 the error bridge no longer files GitHub issues from non-production — the staging-steals-prod noise. #901, #904, #896, #890 engagement analytics and the admin surface for it. #889, #895, #753 the Social Budget workbench, its hosting, and the Front Page Audit. #813, #905 the decks and this deck.
Still not shipped, and still the sharpest items
#872 — stored XSS from the unauthenticated intake form into admin pages, plus an "us" substring match that classified Australia, Austria, Belarus, Cyprus, Mauritius and Russia as domestic, mailing US-only crisis resources abroad.
#865 — a live credential written to the log stack on every connect.
#878 — an eleven-month credential exposure in git history.
All three need a rebase before they can be reviewed at all.
Two risks that did not go away
The gate still tested none of this. Every green check on all fourteen means lint only — see Notice 2.
The PARENT_MODULES regression lives in #834, so abandoning that branch avoids it — but confirm deploy_job_runner.sh on production still lists classroom_link.py and google_meet.py, because that is what keeps class emails from reverting to raw meeting URLs.
Two of fifty-three
Every open non-draft school PR at the time of the sweep (49; there are 53 now) was read as a diff, not a title, by a fan-out of one reviewing agent per PR. Both are still open and still unapproved. “Trivial” means: fixes a real defect, small, self-contained, targets production, no non-additive migration, no secrets, revertible on its own.
#804 — safe to group
/classes had lost the site header and social links. Template-only, +54/−49 across 3 files, no server.py, no migration. Behind production but not conflicted. If #689 also lands, merge #804 first — both touch index_zen.html.
#817 — safe, but ship it alone
/enroll double-click showed a false error; now a target-less ON CONFLICT DO NOTHING. One hunk in enroll_in_class, plus a test. Already in the integration branch. Its author asks that it ship alone with a post-deploy enrollment smoke test, because it is live Path-1 enrollment — honour that even though the change is trivial. Note #822 also edits enroll_in_class.
Near misses, and what disqualified them
| PR | Fixes | Why not groupable |
|---|---|---|
| #872 | Stored XSS from the public intake form into admin pages; "us" substring matched Australia, Austria, Belarus, Cyprus, Mauritius, Russia → US-only crisis packs mailed abroad | Rewrites inline handlers to delegated ones across 4 admin templates — a dead button would fail silently. Needs browser QA. |
| #865 | A credential-in-logs fix, plus require_auth crashing instead of 503 when the DB is down | Bundles the auth decorator, the default visitor theme CSS, and a global cache-bust. |
| #886 | Silent calendar-job and webhook failures | Purely additive logging — zero behaviour change. Ship it, but as observability, not as a bugfix. |
| #885 | Boot fails closed on a half-applied migration | A ;→&& in the Dockerfile changes availability semantics for the whole app: a transient DB blip now crash-loops the container. Deliberate ops choice, not a drive-by. |
| #888 | 150 dead curriculum pages behind Tier 0 | Bundles a fallback that switches up to 1,048 paths from static builds to DB-served content. |
Two merge-order traps
#835 × #880: #835 plants four xfail(strict=True) markers on error_bridge defects that #880 may fix. A strict xfail that passes is a failure — land both and the shared gate goes red. #880 first, then rebase #835 without the markers.
#898 × #900: identical insertion point in server.py. Merge one, rebase the other.
Also: #824 → #852 → (#873, #881) is a fixed stack — none can land without dragging in a 42-file change.
Nobody here is behind
Merged, Aug 6–13, both repos
lizthedotdev and lizTheDeveloper are two GitHub accounts belonging to Liz, counted here as one person — 49 + 1.
The same week, counted honestly
| Person | Merged | Open | What the pair says |
|---|---|---|---|
| Liz | 50 | 36 | Both accounts; also the only reviewer |
| Megs | 6 | 16 | Writing 3× what gets merged |
| Neek | 0 | 4 | Oldest waiting since Jul 28 |
Put the two columns side by side and the merged column stops being a productivity number and starts being a review-capacity number. That is the only reading of it I will defend.
The better metric remains verified merges per person per week — a merge carrying a breadcrumb saying what was verified and how. We still do not measure it. verify-release in the repo we just published describes exactly how; adopting our own skill is the cheapest way to start.
Deadlines are made up. Evidence is not.
The week’s quietly perfect detail: we published a repository of skills about knowing whether your software is getting better — and the very first thing this deck found, one day later, was that our own redaction script could not be run by the command in our own documentation.
It had not leaked anything. The regenerated files came out byte-identical. But it had been a control that nobody could execute, sitting quietly next to a document explaining why executing it matters. That is not embarrassing, it is the exact failure mode detect-drift exists to catch, and we caught it by writing the thing down and then using it.