docs(bottom-panel): record Stage 2B-3 and close Stage 2
Handoff section 1 gains the 2B-3 bullet and the protocol anchor moves to v21 with the rule that matters stated once: advertise the baseline, negotiate up from the frontend's AttachRequest, and reserve moving the advertised version for a change that cannot be expressed additively at all. 2B-1's forward-looking constraint is marked discharged rather than deleted, because its acceptance still passes unchanged and that is the evidence. COHERENCE section 14 grades the bottom/side panel primitive as complete on BOTH frontends rather than 'Stage 2 pending its own framing', section 20 P5 follows it, and the section-19 protocol bullet records that the v21 family is live in production without an incompatible handshake change. The active-work lane is rewritten to the shipped slice, including the rejected activation alternatives and why the server-first shape forces each one out, and the one-way compatibility window it leaves open. The 2B-2 acceptance suite's header said production keeps panel_capable false for every semantic session. That is no longer true, and its assertions did not change — which is the point, so the header now says so rather than being quietly left stale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lv428Fth9LRtffwJSsqH7T
This commit is contained in:
parent
71cc31bfbb
commit
8ee08d93e5
36
COHERENCE.md
36
COHERENCE.md
|
|
@ -107,7 +107,7 @@ remain open to them.
|
|||
| 11 | Config layering + provenance | **Partial (foundation only)** | Typed registry is right; 5 settings live in it; no value provenance |
|
||||
| 12 | Profiles | **Missing** | One hardcoded default keymap; not a named concept |
|
||||
| 13 | Package lifecycle UX | **Resolution without lifecycle** | Mature resolver/lockfile; init-only install; no uninstall/disable/search |
|
||||
| 14 | Workbench primitives | **Partial (best trajectory)** | Listview is a real primitive but only 3 call sites, all LSP panels; buffer-list and search re-implement it; bottom panel landed (#155) |
|
||||
| 14 | Workbench primitives | **Partial (best trajectory)** | Listview is a real primitive but only 3 call sites, all LSP panels; buffer-list and search re-implement it; bottom panel complete on BOTH frontends (#155 + Stage 2) |
|
||||
| 15 | Contextual affordances | **Weak** | Right-click menu only; code actions apply first-blindly; no git integration at all |
|
||||
| 16 | Semantic frontend | **Strong** | v6..=v21 schema support; production attach remains v20 during the dark panel slice; degradation practiced |
|
||||
| 17 | Distribution | **Missing** | CI is test-only; no binaries, channels, checksums, or update path |
|
||||
|
|
@ -1280,10 +1280,17 @@ Primitive-by-primitive against the list above:
|
|||
vocabulary is fixed Rust-side).
|
||||
- **Contextual popup** ✓ — completion popup, context menu (each a
|
||||
shadow, §6).
|
||||
- **Bottom/side panel** ✓ — landed as bottom-panel Stage 1 (#155):
|
||||
- **Bottom/side panel** ✓ — Stage 1 (#155) gave the substrate:
|
||||
`WindowParams` side/fixed_rows/dedicated, `display = "current" |
|
||||
"panel"` adopted by listview/compile/terminal, quit-action, divider
|
||||
drag. Stage 2 (GPU band) pending its own framing.
|
||||
drag. **Stage 2 completed it on the second frontend** (2A #177, 2B-1
|
||||
#184, 2B-2 #187, 2B-3): the GPU frontend now renders a real panel
|
||||
band with its own divider, pointer routing, and resize drag, and a
|
||||
semantic session that negotiates the panel wire is panel-capable.
|
||||
Both frontends therefore share one placement primitive rather than
|
||||
the GPU silently taking the Stage 1 non-side fallback. Stage 3 — the
|
||||
adopter default flip, so omitting `display` resolves to the panel
|
||||
policy — is the remaining step.
|
||||
- **Task/progress view** △ — `*workers*` exists but joins nothing
|
||||
(§9).
|
||||
- **Help view** △ — exists twice (§5); needs unification, not
|
||||
|
|
@ -1366,10 +1373,15 @@ its asks are already practiced.**
|
|||
- Versioned protocol schema `SUPPORTED=[6..=21]` with deliberate
|
||||
encoding-breaking bumps, both-frontends support required per bump,
|
||||
and byte-pin discipline for appended variants (handoff §4). The v21
|
||||
bottom-panel family landed with Stage 2B-1 (#184) and is reserved but
|
||||
dark: because `Hello` is server-first, the production daemon still
|
||||
advertises v20 so shipped v20 clients remain attachable; compatible
|
||||
v21 activation belongs to Stage 2B-3.
|
||||
bottom-panel family landed with Stage 2B-1 (#184) and is **live in
|
||||
production since Stage 2B-3** — activated without an incompatible
|
||||
handshake change. Because `Hello` is server-first, the daemon's
|
||||
advertised version is now a permanent compatibility **baseline**
|
||||
(still 20) and the session's real version is settled one message
|
||||
later by the frontend's `AttachRequest` counter-offer. That split —
|
||||
advertise the floor, negotiate up — is the reusable pattern for every
|
||||
future additive family, and it means bumping the advertised version is
|
||||
reserved for a change that cannot be expressed additively at all.
|
||||
- Two genuine frontends share the conceptual model; CRDT concurrent
|
||||
editing with presence across them; remote attach + reconnect.
|
||||
- **Graceful per-frontend degradation is practiced, not aspirational**:
|
||||
|
|
@ -1569,10 +1581,12 @@ and §18's floor ride on this.
|
|||
|
||||
### Priority 5: Finish the workbench convergence
|
||||
|
||||
**State: partial and moving (§14) — bottom panel Stage 1 landed, GPU
|
||||
band pending; listview proven.** Remaining: the tree primitive (build
|
||||
it before dired and the worker tree invent two), table/inspector/diff,
|
||||
help unification. Wiring plus one modest model piece (the tree model).
|
||||
**State: partial and moving (§14) — the bottom panel is now complete on
|
||||
both frontends (Stage 1 #155 through Stage 2B-3), and listview is
|
||||
proven.** Only the adopter default flip (Stage 3) remains on the panel
|
||||
itself. Remaining elsewhere: the tree primitive (build it before dired
|
||||
and the worker tree invent two), table/inspector/diff, help unification.
|
||||
Wiring plus one modest model piece (the tree model).
|
||||
|
||||
### Priority 6: Productize configuration
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Active work — cross-machine resume ledger
|
||||
|
||||
**Snapshot: 2026-07-28.** This file records volatile work that has not
|
||||
**Snapshot: 2026-07-29.** This file records volatile work that has not
|
||||
landed on `main`. Read it after `docs/agent-handoff.md`. Remove completed
|
||||
entries when their PR merges; do not let this become a second permanent
|
||||
backlog.
|
||||
|
|
@ -245,24 +245,84 @@ If it does not, stop and repair the remote/fetch configuration.
|
|||
never been enforced. Any CI job that compiles the `crdt` targets has to
|
||||
fix them first or it will be red on arrival.
|
||||
|
||||
## Bottom-panel lane (Arc 7) — 2B-2 MERGED; 2B-3 IS NEXT
|
||||
## Bottom-panel lane (Arc 7) — 2B-3 OPEN; Stage 2 is COMPLETE with it
|
||||
|
||||
Stage 1, the Stage 2 framing, Stage 2A, Stage 2B-1, and **Stage 2B-2 are
|
||||
all on `main`**. Framing revision 5's three-way split of 2B was
|
||||
explicitly approved on 2026-07-27; revision 6 records PR #184's review
|
||||
correction. **2B-2 — the daemon panel projection and epoch machine —
|
||||
landed as [PR #187](https://github.com/levineuwirth/pmacs/pull/187)**,
|
||||
one review round of five findings on top of the implementation, 12/12
|
||||
green, 22/22 mutations biting. Its durable lessons are in
|
||||
`docs/agent-handoff.md` §1; what remains below is the 2B-3 plan.
|
||||
Stage 1, the Stage 2 framing, Stage 2A, Stage 2B-1, and Stage 2B-2 are
|
||||
all on `main`. **Stage 2B-3 — the GPU panel band, compatible protocol-v21
|
||||
activation, and the negotiated `panel_capable` flip — is this lane's open
|
||||
work**, and it completes Stage 2. Framing revision 5's three-way split of
|
||||
2B was explicitly approved on 2026-07-27; revision 6 records PR #184's
|
||||
review correction.
|
||||
|
||||
**2B-2's boundaries, restated because they are easy to overrun:** the
|
||||
production `Hello` stays at v20 and `panel_capable` stays `false`. The
|
||||
slice is dark/test-only capability exactly as 2B-1 was. Compatible v21
|
||||
activation, the GPU band, and the negotiated capability flip are all
|
||||
2B-3's, and 2B-3 may **not** simply change the unsolicited `Hello` to
|
||||
21.
|
||||
- **Branch `bottom-panel-stage2b3`, worktree `../pmacs-bp-2b3`, cut fresh
|
||||
from landed `main` @ `e003b81`** (`Merge pull request #190 from
|
||||
levineuwirth/resource-op-delete-guard-impl`) — measured with
|
||||
`git log --oneline -1 githubsucks/main`, not carried over from a
|
||||
briefing. Not stacked on `../pmacs-bp-stage2b2`: each slice starts from
|
||||
landed main, which is the house pattern and what 2B-2 did.
|
||||
- **The activation mechanism, and why the alternatives fail.** The
|
||||
constraint inherited from 2B-1's review is that the unsolicited `Hello`
|
||||
may not become 21: it is server-first, so a shipped v20 frontend rejects
|
||||
an unknown version *before* it can send `AttachRequest`. What 2B-3 ships
|
||||
instead is a **frontend counter-offer**:
|
||||
`ADVERTISED_PROTOCOL_VERSION` becomes a permanent compatibility
|
||||
*baseline* (20), the frontend answers
|
||||
`requested_protocol_version(baseline)` — its own `PROTOCOL_VERSION` when
|
||||
the baseline is current, a verbatim echo of anything older — and the
|
||||
daemon records `negotiated_session_version(offer)`. The daemon needed
|
||||
**no change** to accept it; it already recorded `req.protocol_version`.
|
||||
Rejected alternatives, each for a reason the server-first shape forces:
|
||||
growing `Hello`/`InstanceCapabilities` (postcard structs are positional,
|
||||
so it breaks the *other* direction symmetrically and cannot be verified
|
||||
against shipped binaries); a client-first hint (an old client writes
|
||||
nothing until it has read `Hello`, so any probe is a timeout);
|
||||
sniffing `instance_identity.pmacs_version` (version-string branching on
|
||||
a field documented as display-only); and a second post-`Hello` daemon
|
||||
message (an old client reads it as an `InstanceMessage` and dies on the
|
||||
unknown discriminant).
|
||||
- **The window this leaves open is named, not hidden.** A daemon whose own
|
||||
`PROTOCOL_VERSION` equals the baseline rejects an offer above its
|
||||
supported range. A single `AttachRequest` cannot mean both "I want 21"
|
||||
and "≤ 20", so compatibility is preserved for old *frontends* — the
|
||||
direction that matters, since the daemon is what a user leaves running —
|
||||
and the window closes on the next daemon restart. It surfaces as an
|
||||
explicit `GoodbyeReason::VersionMismatch` naming both versions, pinned by
|
||||
`an_unsupported_offer_is_refused_by_name`.
|
||||
- **Five commits:** the activation mechanism, the three-boundary split plus
|
||||
the band's machinery, the paint/input wiring, the acceptance suites, and
|
||||
the bite fixes plus these docs.
|
||||
- **Verification on the reviewed head** (all redirected to files and
|
||||
checked by their own exit codes, never through a pipe): recorded in the
|
||||
PR body and reproduced by the commands in `CLAUDE.md`.
|
||||
- **23 falsifying mutations, all executed, all biting**, using an in-place
|
||||
mutation runner rather than `scripts/bite` because several claims live in
|
||||
the *same file* as their test and a whole-file swap would not compile.
|
||||
**Three assertions were VACUOUS on the first pass and the mutation runs
|
||||
are what found them** — a fixed-point contrast check, a pixel test that
|
||||
passed with the band painting nothing, and a monospace fixture that could
|
||||
not tell two glyph-advance derivations apart. A fourth finding was about
|
||||
the code, not the tests: "no panel frame reaches a v20 session" is
|
||||
defence in depth, not the placement gate, and passes with the capability
|
||||
gate removed entirely.
|
||||
- **Two real defects the new tests caught in the implementation**, both
|
||||
recorded in `docs/agent-handoff.md` §1: `edge_scroll_direction` has no
|
||||
upper bound, so reclassifying its boundary was necessary but not
|
||||
sufficient; and `apply_panel_payload` ignored the exhaustion latch.
|
||||
- **Cross-machine recovery (fresh clone):**
|
||||
|
||||
```sh
|
||||
git fetch githubsucks --prune
|
||||
git switch --track -c bottom-panel-stage2b3 githubsucks/bottom-panel-stage2b3
|
||||
git rev-parse HEAD
|
||||
```
|
||||
|
||||
- **Stage 3 (the adopter default flip) is the arc's last step** and is not
|
||||
started. This lane is not removed at 2B-3's merge: Stage 3 remains ahead
|
||||
of it.
|
||||
|
||||
- **Stage 2B-2 MERGED as #187.** One review round of five findings on top
|
||||
of the implementation, 12/12 green, 22/22 mutations biting. Its durable
|
||||
lessons are in `docs/agent-handoff.md` §1.
|
||||
- **What PR #187 shipped, dark by construction:** the semantic daemon's
|
||||
`FrontendCellGeometry` epoch machine; one reconciled panel grid
|
||||
derivation; `PanelFrame::{Present, Absent}` projection on both document
|
||||
|
|
@ -308,7 +368,7 @@ activation, the GPU band, and the negotiated capability flip are all
|
|||
```
|
||||
|
||||
#187 has landed, so `githubsucks/main` already contains this work and
|
||||
the branch is retained only for provenance. Start 2B-3 from `main`.
|
||||
the branch is retained only for provenance. 2B-3 was cut from `main`.
|
||||
- **Stage 2B-1 MERGED as #184** (`main` @ `6bee09d`, 2026-07-28; all
|
||||
twelve checks green on the reviewed head `5539b6e`; two review rounds
|
||||
plus a gate-found follow-up). Branch
|
||||
|
|
@ -322,11 +382,11 @@ activation, the GPU band, and the negotiated capability flip are all
|
|||
`panel_capable` is still `false` for every semantic session, so the
|
||||
journey grade is unchanged and every shipped v20 client remains
|
||||
attachable.
|
||||
- **2B-3 inherits a hard constraint from 2B-1's review**: it owns a
|
||||
*compatibility-preserving* v21 activation mechanism and may **not**
|
||||
simply change the unsolicited `Hello` to 21. The handshake is
|
||||
server-first, so that one-line change locks out every shipped v20
|
||||
frontend before it can even send an `AttachRequest`.
|
||||
- **2B-3 discharged the hard constraint 2B-1's review set**: the
|
||||
*compatibility-preserving* activation is the frontend counter-offer
|
||||
described at the top of this lane, and the unsolicited `Hello` is
|
||||
unchanged. 2B-1's real-daemon acceptance for the v20 rejection point
|
||||
still passes untouched.
|
||||
- **Two review rounds, and what each cost.** Round 1: `PanelFrame`
|
||||
needed an explicit `buffer_id`, the transport ratchet had to drive the
|
||||
real attach path rather than a detached codec assertion, and shared
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
# Agent handoff — cross-machine continuity
|
||||
|
||||
**Last updated: 2026-07-28, as bottom-panel Stage 2B-2 (#187) — the
|
||||
**Last updated: 2026-07-29, as bottom-panel Stage 2B-3 — the GPU panel
|
||||
band, compatible protocol-v21 activation, and the negotiated
|
||||
`panel_capable` flip, completing Arc 7 Stage 2 — opens atop `e003b81`.
|
||||
Beneath it, bottom-panel Stage 2B-2 (#187) — the
|
||||
daemon panel projection and the epoch machine — lands on `6c9e765`,
|
||||
which is the dired Stage 2 framing (#171) atop the resource-op delete
|
||||
guard framing (#186). Those two are framing-only: both are approved
|
||||
|
|
@ -77,14 +80,13 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
#165, the GPU terminal input fix #166, Lean 4 Stage 2 #161, the dired
|
||||
framing #164, COHERENCE.md #163, find-file #162, Lean 4 Stage 1 #160,
|
||||
minimap blank-slab #159, bottom-panel Stage 1 #155).
|
||||
**Protocol schema support is now `v6..=v21`, while the production
|
||||
server-first `Hello` still advertises v20.** Those are two different
|
||||
facts and #184 landed only the first: the v21 bottom-panel wire family
|
||||
exists, is gated in both directions, and has no producer, no consumer,
|
||||
and no capability behind it. Compatible v21 activation and the
|
||||
production advertisement move belong to Stage 2B-3. The bullets below
|
||||
describe the arcs in their own terms; this line is the head-of-`main`
|
||||
anchor.
|
||||
**Protocol schema support is `v6..=v21`, the production server-first
|
||||
`Hello` advertises v20, and a current session nevertheless negotiates
|
||||
v21.** All three are true at once, and Stage 2B-3 is what made them
|
||||
compatible: the advertised version is a permanent **baseline** and the
|
||||
session's real version is settled one message later by the frontend's
|
||||
`AttachRequest` counter-offer. The bullets below describe the arcs in
|
||||
their own terms; this line is the head-of-`main` anchor.
|
||||
- **`COHERENCE.md` is now required reading and a required framing input
|
||||
— #163.** It carries the product-coherence thesis, an audited
|
||||
scorecard, per-concern gaps, and §20's priority order, and it is the
|
||||
|
|
@ -457,14 +459,17 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
unchanged, which is the additivity gate for the `read_dir` change; M4
|
||||
121; required GPU 155; isolated-`XDG_CONFIG_HOME` workspace sweep
|
||||
3,205 across 93 suites. 15 claims bite-verified.
|
||||
- Canonical `main` is protocol **v20** (`SUPPORTED=[6..=20]`; v16 =
|
||||
- Canonical `main` is protocol **v21** (`SUPPORTED=[6..=21]`; v16 =
|
||||
`ThemeFacts`, v17 = `FontFacts`, v18 = `StatuslineSegments`, v19 =
|
||||
terminal frames/events, v20 = the GPU initial-target semantic
|
||||
bootstrap family). Bottom-panel Stage 2B-1's in-review schema is v21
|
||||
(`SUPPORTED=[6..=21]`), but its production daemon deliberately
|
||||
advertises v20: the handshake is server-first, so advertising 21
|
||||
would make shipped v20 GPU/TUI clients reject before
|
||||
`AttachRequest`. Stage 2B-3 owns compatible production activation.
|
||||
bootstrap family, v21 = the bottom-panel band family).
|
||||
**`ADVERTISED_PROTOCOL_VERSION` stays 20, permanently, and that is the
|
||||
activation mechanism rather than a hedge** — see the Stage 2B-3 bullet.
|
||||
The rule for every future additive family: advertise the baseline,
|
||||
negotiate up from the frontend's `AttachRequest`. Moving the advertised
|
||||
version is reserved for a change that cannot be expressed additively at
|
||||
all, because a server-first `Hello` reaches a shipped frontend before it
|
||||
can identify itself.
|
||||
- **Bottom panel Stage 1 (window placement + TUI side windows) LANDED —
|
||||
#155** (`docs/bottom-panel-framing.md` rev 4; merge `e745068`; two review
|
||||
rounds). **No protocol change (still v20).** Arc 7's substrate: pmacs now
|
||||
|
|
@ -529,23 +534,21 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
`bottom_panel_stage1_acceptance` 46; kill ring 30; compile 67; M4 121;
|
||||
required GPU 152; initial-target 14 CRDT; all three vterm suites; folding
|
||||
Stage 2 48. All 12 CI checks green at merge.
|
||||
- **Stage 2 (the GPU panel band) is FRAMED; its first two slices have
|
||||
LANDED and its third is open as PR #187** —
|
||||
- **Stage 2 (the GPU panel band) is COMPLETE: 2A #177, 2B-1 #184,
|
||||
2B-2 #187, and 2B-3 (this lane)** —
|
||||
`docs/bottom-panel-stage2-framing.md` rev 6, four
|
||||
framing review rounds, no open framing items; the rev-5
|
||||
implementation split was explicitly approved 2026-07-27 and rev 6
|
||||
records PR #184's server-first compatibility and gate correction.
|
||||
It reserves protocol **v21** and ships as four serial
|
||||
It reserved protocol **v21** and shipped as four serial
|
||||
implementation slices: **2A** classified census routing +
|
||||
per-window painter extraction (no wire change, #177), **2B-1** the
|
||||
wire (#184), **2B-2** the daemon projection and epoch machine
|
||||
(implemented but not landed in PR #187), then **2B-3** the GPU band,
|
||||
compatible v21 activation, and the
|
||||
negotiated `panel_capable` flip. Production attachment remains v20
|
||||
through 2B-2. Parent acceptance 37–55 remains authoritative.
|
||||
Stage 3 is the adopter default flip. **Do not start 2B-3 until PR
|
||||
#187 lands.** Its branch, checkpoints, two review rounds, verification,
|
||||
and exact recovery commands live in `docs/active-work.md`.
|
||||
(#187), then **2B-3** the GPU band, compatible v21 activation, and
|
||||
the negotiated `panel_capable` flip. Production attachment stayed
|
||||
v20 through 2B-2 and negotiates v21 from 2B-3 on. Parent acceptance
|
||||
37–55 remains authoritative. **Stage 3, the adopter default flip, is
|
||||
the arc's remaining step.**
|
||||
- **The §1.3 census is CLASSIFIED, not uniformly redirected.** Only the
|
||||
Projection class (#1–#12, #21–#22) routes through
|
||||
`primary_document_window`; focus/input (#13–#15, #23), focus chrome
|
||||
|
|
@ -567,9 +570,10 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
version is therefore an incompatible act on its own, independent of
|
||||
whether any new message is ever sent. A real-daemon acceptance
|
||||
emulates that exact rejection point and then requires the
|
||||
attachment to reach its initial grid. **2B-3 must ship a
|
||||
compatibility-preserving activation mechanism; it may not simply
|
||||
change the unsolicited `Hello` to 21.**
|
||||
attachment to reach its initial grid. **Stage 2B-3 discharged this
|
||||
without touching the unsolicited `Hello`** — the advertisement is a
|
||||
permanent baseline and the frontend counter-offers; see its bullet
|
||||
below. That acceptance still passes unchanged, which is the point.
|
||||
- **One shared grid validator, split along a stated boundary**
|
||||
(`pmacs-protocol/src/wire_grid.rs`). Shared: checked area, the
|
||||
visible-cell bound (262,144), cell count, cursor bounds, glyph
|
||||
|
|
@ -650,7 +654,91 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
stays a per-frame `Absent`, flagged rather than hidden, because
|
||||
making it durable needs a new "presentation permanently
|
||||
unavailable" reason in `FrontendView` for a state requiring 2^64
|
||||
presentations in one session.
|
||||
presentations in one session. **Stage 2B-3 did not make it cheap** —
|
||||
the frontend half latches instead, which is a different remedy, so
|
||||
the daemon-side hole stays open as recorded.
|
||||
- **Bottom panel Stage 2B-3 (the GPU band, compatible v21 activation,
|
||||
and the negotiated capability flip) — the arc's Stage 2 is COMPLETE.**
|
||||
This is the slice a user can see: a semantic GPU session now renders a
|
||||
real panel band instead of taking the Stage 1 non-side fallback, which
|
||||
is what closes the journey-steps-7–10 divergence §6 of the Stage 2
|
||||
framing names. Durable facts:
|
||||
- **A server-first handshake is negotiated from the CLIENT side, not by
|
||||
moving the advertisement.** `ADVERTISED_PROTOCOL_VERSION` is now a
|
||||
permanent compatibility *baseline*; the frontend answers
|
||||
`requested_protocol_version(baseline)` — its own `PROTOCOL_VERSION`
|
||||
when the baseline is the current one, a verbatim echo of anything
|
||||
older — and the daemon records
|
||||
`negotiated_session_version(offer)`. A shipped baseline frontend
|
||||
echoes and gets a baseline session, byte-for-byte as before; a
|
||||
current frontend offers up and gets the current wire. The `Hello`
|
||||
encoding and value never change, which is why the old frontend never
|
||||
sees a version it must reject. **The daemon needed no change to
|
||||
accept the offer** — it already recorded `req.protocol_version` as
|
||||
the negotiated version, so the whole mechanism is one value the
|
||||
frontend chooses plus a documented clamp.
|
||||
- **The window this leaves open, named rather than hidden:** a daemon
|
||||
whose own `PROTOCOL_VERSION` equals the baseline rejects an offer
|
||||
above its supported range. Compatibility can be preserved for old
|
||||
*frontends* or old *daemons* — a single `AttachRequest` cannot mean
|
||||
both "I want 21" and "≤ 20" — and the frontend direction is the one
|
||||
that matters, because the daemon is what a user leaves running. It
|
||||
closes on the next daemon restart and surfaces as an explicit
|
||||
`GoodbyeReason::VersionMismatch` naming both versions.
|
||||
- **`server_protocol_version` split into two facts on the GPU client**:
|
||||
`session_protocol_version` (what the session speaks — every wire gate
|
||||
keys on this) and `baseline_protocol_version` (what `Hello` said).
|
||||
They now DIFFER in the normal case, and that difference *is* the
|
||||
compatibility property, so both headless probe reports emit both and
|
||||
the two ratchets that read them assert both directions. Asserting
|
||||
only the session version would pass if the baseline had been bumped
|
||||
too, which is the exact incompatible change the mechanism avoids.
|
||||
- **The GPU document bottom is three boundaries and each call site was
|
||||
classified individually** — 20 production sites (8 status-owned, 12
|
||||
document-owned), 1 definition, 8 test sites, 29 matches, arithmetic
|
||||
stated. `geometry_capacity_bottom` reserves the divider *while the
|
||||
panel is absent* (that asymmetry is what breaks the first-open cycle)
|
||||
while `document_text_bottom` costs the document nothing until a
|
||||
`Present` frame paints.
|
||||
- **Moving a boundary is not always sufficient.** `edge_scroll_direction`
|
||||
has no upper bound, so a pixel *inside* the band still read as
|
||||
"further down the document" and armed the document's auto-scroll —
|
||||
the exact named symptom, surviving a correct reclassification. Any
|
||||
consumer that treats "past the bottom" as unbounded needs the band as
|
||||
an explicit exclusion, not just a moved boundary.
|
||||
- **Three of the first-pass assertions were VACUOUS, and the mutation
|
||||
runs are what found them.** (a) The contrast assertion compared
|
||||
`status_band_top` before and after — a *fixed point* — so the blanket
|
||||
rewrite it exists to prevent moved both readings together and passed;
|
||||
it is now anchored to an independent formula. (b) The criterion-46
|
||||
pixel test passed with the band painting *nothing*, because
|
||||
installing a panel reshapes the document and that produced the whole
|
||||
diff; it now counts differing pixels in the divider and cell rows.
|
||||
(c) The probe-versus-document-advance fixture compared two ASCII
|
||||
documents, which in a monospace family have identical advances.
|
||||
- **"No panel frame reaches a v20 session" is defence in depth, not the
|
||||
placement gate.** The producer's peer flag and the write-loop filter
|
||||
both suppress `PanelFrame` below the panel version independently of
|
||||
`panel_capable`, so that assertion passes with the capability gate
|
||||
removed entirely. The load-bearing claim is *placement*: the adopter's
|
||||
buffer must land in the pre-panel session's own document window,
|
||||
because a side window it cannot render is simply invisible.
|
||||
- `PanelBand::presented()` is the ONE frontend-side derivation of "is a
|
||||
band on screen" — retained valid frame, matching `geometry_epoch`,
|
||||
latch clear — behind the band inset, the painter, the hit-tester, and
|
||||
the drag. A latched frontend also stops absorbing payloads, so
|
||||
`presented()` is not the only thing between a disowned declaration and
|
||||
a painted band.
|
||||
- Panel columns come from the **stable normal-face probe**, never
|
||||
`mono_advance`'s document-glyph fallback, and `panel_cell_capacity`
|
||||
carries the daemon's **virtual status row** (`frontend_area_rows` is
|
||||
`total.rows - 1`) with **no per-axis cap**, because a panel may
|
||||
legitimately be wider than a PTY.
|
||||
- `PANEL_MIN_VERSION` moved into `pmacs-protocol` so the GPU frontend
|
||||
aliases one definition instead of restating 21.
|
||||
- **Stage 3 (the adopter default flip) is the arc's last step**, and it
|
||||
is the only thing between today's state and omitting `display`
|
||||
resolving to the panel policy.
|
||||
- **dired Stage 2 framing LANDED (document only) — #171**
|
||||
(`docs/dired-stage2-framing.md`, revision 9; seven review rounds).
|
||||
**Approved as a framing; no runtime code and no implementation
|
||||
|
|
|
|||
|
|
@ -4,10 +4,16 @@
|
|||
|
||||
//! The daemon panel projection and the epoch machine.
|
||||
//!
|
||||
//! Everything here runs through a **test-only** panel-capable semantic
|
||||
//! view: production negotiation still sets `panel_capable = false` for
|
||||
//! every semantic session, and the compatibility-preserving v21
|
||||
//! activation is Stage 2B-3's. Nothing in this slice is user-reachable.
|
||||
//! Everything here runs through an explicitly panel-capable semantic
|
||||
//! view constructed by the fixture. When this suite was written that was
|
||||
//! a *test-only* configuration — production negotiation set
|
||||
//! `panel_capable = false` for every semantic session. **Stage 2B-3 made
|
||||
//! it production-reachable**: a semantic session that negotiates
|
||||
//! `PANEL_MIN_VERSION` is panel-capable, activated by the frontend's
|
||||
//! `AttachRequest` counter-offer rather than by moving the advertised
|
||||
//! `Hello` version. These assertions did not change, and that is the
|
||||
//! point — the projection they pin is the one production now drives.
|
||||
//! `bottom_panel_stage2b_gpu_acceptance` covers the negotiation itself.
|
||||
//!
|
||||
//! Two disciplines the framing is explicit about:
|
||||
//!
|
||||
|
|
|
|||
Loading…
Reference in New Issue