Rev 4 §9 scoped Stage 2B as a single PR: v21 protocol, daemon panel
projection, GPU band, and the negotiated `panel_capable` flip.
Implementation showed that to be roughly four thousand lines across
three crates with three different failure modes. Rev 5 splits it into
2B-1 (the wire layer), 2B-2 (the daemon projection and epoch machine),
and 2B-3 (the GPU band and the flip), on the rule that a slice ends
where the next thing to build has a different authority.
No decision changes. What changes is the allocation:
- §7.2 becomes three subsections, and criteria that span a boundary are
named in every slice they touch with their half stated, rather than
assigned wholesale to one. Parent 39 is the clearest case: its
shared-validation and transport-budget halves are wire properties
provable in 2B-1, while "the previous valid frame is retained" and "a
duplicate does no work" need the epoch machine and are 2B-2. A2B-1
splits the same way — grid exhaustion in 2B-2, the frontend latch in
2B-3.
- §9 lists four serial PRs instead of two, each cut from `main`, and
states that every slice runs the full gate set rather than the subset
its own crate suggests.
- §6 records which slice pays the coherence debt. The journey claim
belongs to 2B-3 alone: with `panel_capable = false`, a GPU user still
gets the Stage 1 non-side fallback after 2A, 2B-1 and 2B-2 have all
landed. Three quarters of this stage is preparation.
Two things recorded because they are easy to inherit silently:
- This revision is retroactive for slice 1. `bottom-panel-stage2b`
already carried the v21 protocol layer, written before the revision
existed, which inverts framing -> approval -> branch -> implement. The
slicing was sound; taking it in code rather than in the document is
how a stage's scope drifts without anyone deciding that it should.
- 2B-1 and 2B-2 ship dark. The bump advertises a capability whose only
distinguishing feature is unreachable until 2B-3, so the arc must not
stall between them. Safe for compatibility — appended variants,
extended ladder, a v20 peer still negotiates 20 — but a stall should
be visible as a decision, not inherited as a default.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011LFvC4FQtux4y32KuevZ7B