The 2026-04-17 freeze
This post documents the meeting that froze RAPP v1. It is written on 2026-04-19, two days after the fact, while memory is still fresh. If anyone later asks “why did we draw the line there?” — this is the record.
The timeline
- 2025-12-14 — First public RAPP brainstem runs against GitHub Copilot device-code flow. No registry, no cards, no eggs. Just
*_agent.pyfiles in a directory. - 2026-01-09 — RAR (RAPP Agent Registry) reaches 50 registered agents. The
__manifest__decision is debated; snake_case is locked in. - 2026-02-20 — The swarm server ships. GUID routing,
423 Lockedconvention, sentinel GUID. The wire contract stabilizes. - 2026-03-11 — The
.eggformat first successfully round-trips (see112-the-egg-forge-origin.md). - 2026-04-02 — Tether v0 (agent-decides-to-delegate) ships. The three-tier story becomes four-tier-feeling and we have to decide whether to include tether in v1.
- 2026-04-17 — Freeze. SPEC.md is marked “Status: Frozen.”
- 2026-04-19 — BookFactory ships as the first rapplication. This blog post is drafted.
What almost made it in and didn’t
Three things were under active discussion on the day of the freeze. Two of them were cut. One of them was deferred to v1.1.
1. LearnNew as a required agent (cut)
Proposal: every RAPP brainstem MUST ship a LearnNew meta-agent that generates new agents from natural language. Counter-argument: §0 says a single weather_agent.py is a valid RAPP system. Requiring LearnNew would force every minimal install to carry the meta-agent as a dep. This violates “drop anywhere and it works.”
Decision: LearnNew is sanctioned (§11) but not required. A brainstem without it is still compliant.
The person who argued for required: was outvoted. The person who argued against required: was correct.
2. Tether as a tier (cut)
Proposal: tether is a fourth tier. Rename “three tiers” to “four tiers” in §4. Counter-argument: tether is a decision an agent makes, not a runtime. An agent that tethers is still running on Tier 1/2/3; tether is just a specific outgoing call pattern.
Decision: tether stays a capability (per 85-tether-agent-decides.md), not a tier. §4 stays at three.
This one was close. The counter-argument won because adding a tier would have required a Tier 4 runtime to exist separately, and there isn’t one — tether rides the same wire.
3. Soul mutation mid-conversation (deferred)
Proposal: allow soul.md to be modified per-conversation (e.g., a “become more formal” directive from the user). Counter-argument: this breaks §10 Tenancy — “one tenant = one soul + one agents directory.” If the soul mutates, the tenant definition becomes probabilistic.
Decision: deferred to v1.1 with a working name of “soul layers.” The current freeze text says “No per-conversation soul mutation in v1.”
This is the single feature most likely to be controversial in v2. We marked it explicitly.
What made it in because someone insisted
A few things survived the freeze because one person on the team refused to let them be cut. Noting them for posterity:
data_slushas a first-class return field. Could have been an optional convention. Is required (§5.4) because the person arguing for it pointed out that without it, chain composition is undefined at the spec level. We agreed.- The 7-word incantation. Could have been just a seed. The incantation adds weeks of work and a Web Speech API dependency. It’s in v1 because the person arguing for it said “if a kid can’t summon an agent by speaking, we failed.” We agreed.
- Three explicit tiers in the SPEC, not two. Tier 3 (Copilot Studio) seemed like it could be a §12-style extension. The person arguing it belonged in §4 pointed out that enterprise adoption requires it be first-class. We agreed.
What the freeze actually means
Freezing v1 doesn’t mean we stop committing. It means:
- The SPEC file is immutable. Typo fixes and clarifications only. No semantic changes.
- The agent contract (§5) is immutable. Any agent written against v1 will load in any future RAPP runtime, forever, unchanged.
- New features go in v1.1, v1.2, …, via sanctioned extensions (§12.4). The extensions must be optional and v1-compatible.
- Breaking changes require v2. v2 does not yet exist. The freeze timestamp is the “what v2 must remain compatible with” anchor.
Why 2026-04-17 specifically
We froze when the spec stopped changing on its own. For two weeks before the freeze, no PR had touched a load-bearing definition. The spec had stabilized organically. We formalized the stability by marking it.
This is the right test for a freeze — not “do we like it?” but “has it stopped wanting to change?” The SPEC wanted to change every day in January. It wanted to change twice a week in March. It wanted to change zero times in early April. We froze.
The freeze as a commitment to users
The third-party agents registered in RAR are the reason the freeze matters. If a developer submitted @jenna/hacker_news_digest in February, that agent must still load in 2036. The freeze is our promise to Jenna.
Freezing a spec is not hard. Honoring the freeze for ten years is hard. The freeze post is the contract. The agent is the witness.
If you’re reading this in 2036
The spec you’re reading is the one we froze on 2026-04-17. If something about the runtime has changed, it was through a sanctioned extension, not a breaking change to §5. If §5 has a breaking change, you’re reading v2 and v1 is still valid as an archive.
The v1 sacred tenet holds: the single-file *_agent.py is sacred. The file is the agent is the documentation is the contract. Ten years is a long time, but that sentence does not rot.
The freeze holds.