01
Team Update
/13
Multiverse SchoolEngineering2026-08-13

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.

Public copy. This page is readable by anyone with the link. Infrastructure addresses and the specifics of unresolved credential items have been removed; every number, finding and roadmap item is unchanged. The complete version lives behind the admin gate at /internal/decks.
56
PRs merged this week
44 school · 12 campus
20
Approved, green, unmerged
16 clean on production
148
PRs still open
55 school · 93 campus
38
School PRs with no milestone
of 53 non-draft — 72%
Where the numbers come from. The GitHub API for both repos, windowed 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.
Agendafive blocks

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.

Block 1What shipped

Aug 6 → Aug 13

themultiverse.school — 39

8Class pages & track UI
8Docs, process & review checklist
7Student tools & engagement analytics
6Class editor & the classroom link
4Error bridge & audit logging
6Everything else — forms, GDPR, scholarship, decks, members
Peak day was today: 8 merged before this meeting.

multiversecampus — 12

3Releases cut — 1.14.2, 1.14.3, 1.14.4
4Docs & specs, incl. the Matrix runtime plan
4Agent & RAG repairs
1Build — native toolchain out of the image
Three releases in a week is the highest cadence campus has ever run.
Campus shipped fewer PRs and more releases than school. That is the right direction and it is worth saying out loud — school merged 39 things and cut zero releases.
Block 1The things people will remember

What each person shipped

Liz school #839 · #845 · #847

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.

Megs school #849 · #842 · #773 · campus #1097

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.

Liz school #889 · #890 · #896 · #897

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.

Liz school #844 · 8 lines

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.

Block 1Outward-facing

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.”

Deliberately generic — no company hosts, tokens or container IDs. Vendors are named as one working choice, not a requirement. That constraint is why it is publishable at all.
SkillCovers
bootstrap-hostingA box, a PaaS, a CDN, a vault
release-processBranches, previews, who may promote
version-and-claimSemver, cohorts, falsifiable claims
wire-telemetryErrors→issues, SLOs you can measure
verify-releaseHuman-walkable plans, review at volume
explain-this-projectDocs for the operator, not the agent
agent-personas14 worked expert reviewers
run-a-campaignBuilder / breaker / reviewer roles
detect-driftDocs and tests that stopped matching
Three of these — release-process, version-and-claim, verify-release — are the exact machinery this deck keeps asking for. We wrote them down for strangers before we finished adopting them ourselves.
Block 2Notices

True right now, and not in any one ticket

Notice 1 school PR #834 · #894

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.

Notice 2 ci-runner · verified today

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.

Notice 3 school #865 · #878

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.

Notice 4 campus #1171 · milestones

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.

Block 2The finding, and what happened to it

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.

StatenWhat it means
Approved + green20Nothing human is blocking these
… clean on production16Mergeable right now
… BEHIND or stacked4#852, #873 stacked; #871, #888 need a rebase
Review required32The remaining backlog
The sixteen: 712, 785, 791, 835, 846, 864, 879, 884, 885, 886, 887, 898, 902, 903, 906, 907. Two of those collide — #898 and #900 share an insertion point in 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.

Merged this week56
Merged today14
Approved, unmerged20
Open — school55
Open — campus93

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.

Campus is unchanged at 93 open and 12 merged — all of this week's movement was school.
Block 3Decisions

One down, three live

First, the honest part. The Aug 6 deck put seven decisions in front of you. Checked live today: school #606, #287 and #459 still open; campus #841 and #1053 still open; the duplicate 1.15.0 milestones still duplicated. One of seven got done — Decision 6, the campus 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.
Decision 1 — done #894 merged 20:00

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.

Decision 2 2 credentials

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.

Decision 3 37 school PRs

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.

Decision 4 process

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.”

Block 4Release readiness

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.

ReleasePreview branchLandedOpen, milestonedState
4.2.204 — Aug 6none—2Overdue #700, #712 — #712 is approved and clean
4.2.304 — today…08-13-integration (#834, draft)2 / 160Abandoned DIRTY; overtaken by 14 direct merges
4.2.404 — Aug 20none—1Unstarted
4.2.504 — Aug 27none—2Unstarted #882 conflicting
campus 1.17.xrelease/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.

Block 4What actually shipped

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.

Block 4Groupable now

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.

53
Open non-draft PRs
49 read one-agent-per-PR, full diff
2
Trivial bugfixes
#804 and #817 — the whole list

#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.

Two in forty-nine is the finding. The queue is not full of small safe fixes waiting for a batch. It is full of bundles — a real bugfix shipped alongside a new job, a new template system, or three unrelated repairs. That is what makes review expensive, and it is why the queue is three weeks deep.

Near misses, and what disqualified them

PRFixesWhy not groupable
#872Stored XSS from the public intake form into admin pages; "us" substring matched Australia, Austria, Belarus, Cyprus, Mauritius, Russia → US-only crisis packs mailed abroadRewrites inline handlers to delegated ones across 4 admin templates — a dead button would fail silently. Needs browser QA.
#865A credential-in-logs fix, plus require_auth crashing instead of 503 when the DB is downBundles the auth decorator, the default visitor theme CSS, and a global cache-bust.
#886Silent calendar-job and webhook failuresPurely additive logging — zero behaviour change. Ship it, but as observability, not as a bugfix.
#885Boot fails closed on a half-applied migrationA ;→&& 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.
#888150 dead curriculum pages behind Tier 0Bundles 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.

Block 5Velocity

Nobody here is behind

Read this before the chart. Nobody on this team is behind. These are counts of merged pull requests, which measure how much work got through the queue — and this week’s whole finding is that the queue, not the people, is the constraint. A low bar here mostly means “waiting on review” — and as of this afternoon, twenty of those waits ended, so next week’s bars will look different for reasons that have nothing to do with anyone working harder. Most of this code is agent-written, so the number is not a measure of a faster person; it is a measure of a different machine, and it discriminates between people far less than it looks like it does.

Merged, Aug 6–13, both repos

Liz50
Megs6
Neek0
Small numbers, deliberately not enlarged. lizthedotdev and lizTheDeveloper are two GitHub accounts belonging to Liz, counted here as one person — 49 + 1.

The same week, counted honestly

PersonMergedOpenWhat the pair says
Liz5036Both accounts; also the only reviewer
Megs616Writing 3× what gets merged
Neek04Oldest 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.

Standing instruction, restated: do not treat this number as a target. It will get Goodharted — by agents at least as readily as by people.
∞Goblins

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.

So: go be goblins about the calendar. Miss a date, move the date. But when the check says green, go look at the artifact — and when the runbook says run this, run it once to see whether it runs at all.