From a03786c9c9ae423b1403b38e789b028c909ac222 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Thu, 6 Aug 2026 23:02:40 +0200 Subject: [PATCH] docs: the classifier belongs where the frontends cannot disagree Section 5d.6 answered as (b): ScrollPosition and the pure classify go in pmacs-protocol, string rendering stays in each frontend. The reading that settles it is sharper than "shared vocabulary". Each frontend computes its own local layout facts --- which rows are on screen is a question only it can answer --- while the shared crate owns the common semantic decision those facts feed. That is not presentation leaking into the protocol crate; it is the DECISION placed where both frontends are structurally unable to disagree, with rendering left where it belongs. Two properties bound the change: no wire message and no protocol version bump, since classify is a pure function over values each side already holds; and the one-copy-fixed defect from 5d.3 becomes unrepresentable rather than reviewer-guarded, because there is only one classifier to fix. Q#LL8 approved. All eight questions answered. Implementation begins. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai --- docs/active-work.md | 13 ++++++----- docs/long-lines-framing.md | 45 ++++++++++++++++++++++++++++---------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 2aba8c7..c20bb28 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -296,7 +296,7 @@ change to *when* `needs_full_grid` is set — the producer's triggers were verified correct, along with per-frame geometry sync and `view_top` reconciliation on shrink. -## Long lines (QoL Stage 3) — BRANCHED, no PR yet +## Long lines (QoL Stage 3) — APPROVED, implementing; no PR yet **Branch `long-lines`**, base `githubsucks/main` @ `218d2e7` (the #219 merge). `githubsucks/long-lines` is the authoritative tip — the ref, @@ -306,7 +306,7 @@ records. Recover: `git fetch githubsucks && git checkout long-lines`. **This block was written with the lane's first commit, before any PR exists** — the standing correction from #171, #215 and #220. -- **Framing `docs/long-lines-framing.md` revision 18.** Q#LL1-LL7 +- **Framing `docs/long-lines-framing.md` revision 19, APPROVED.** Q#LL1-LL7 settled; **Q#LL8 not yet approved** --- implementation is blocked on it, because it changes what gets built rather than how. - **Independent of #220.** Stage 2 (GUI zoom) and Stage 3 share no @@ -386,9 +386,12 @@ for the user to express a preference in either. keeping the existing formatter **untouched for `truncate`** — output identical by construction — and adding a `classify(first_visible, last_visible, byte_pos, byte_len)` for `wrap` that never sees a row - count. **Open: where the classifier lives.** `pmacs-gpu` depends on - `pmacs-protocol` only, so the duplication is structural; sharing it - is a §16 layering call. + count. **Resolved: the classifier lives in `pmacs-protocol`** — + `ScrollPosition` plus a pure `classify`, with string rendering left + in each frontend. Per §16: each frontend computes its own local + layout facts, the shared crate owns the semantic decision they feed. + **No wire message, no version bump**, and the one-copy-fixed defect + becomes unrepresentable rather than reviewer-guarded. ### The two decisions most likely to be questioned later diff --git a/docs/long-lines-framing.md b/docs/long-lines-framing.md index d62f5d5..22aabb5 100644 --- a/docs/long-lines-framing.md +++ b/docs/long-lines-framing.md @@ -1,8 +1,7 @@ # Long lines — QoL Stage 3 -**Status: revision 18 — branched as `long-lines`; Q#LL1–LL7 settled; -Q#LL8 awaiting approval, and §5d.6 (where the classifier lives) needs a -decision. Not yet implemented.** +**Status: revision 19 — APPROVED (2026-08-06). All eight questions +answered; §5d.6 resolved. Implementation begun.** **Revision 2** corrected a load-bearing error in revision 1: it claimed both frontends render from the same `CellGrid`. They do not — the GPU @@ -276,7 +275,7 @@ deleted, so a later reader can tell "the key was fixed" from "there is no key". §5d.7 adds the **large-file guard witnesses**, because "no whole-document work happens" must be enforced, not merely intended. -**Revision 18 — the current one.** Review of `d6b5285` found the +**Revision 18** — review of `d6b5285` found the interface contradiction the byte fallback left behind. Revision 16 had claimed the formatter could keep its signature and change only its arguments; it cannot. **Every branch of `format_scroll_indicator` @@ -303,6 +302,14 @@ condition that produced §5d.3's defect; sharing it via `pmacs-protocol` makes agreement structural but widens that crate toward presentation — a §16 layering call I am not taking alone. +**Revision 19 — the current one.** §5d.6 answered as **(b)**: +`ScrollPosition` and `classify` go in `pmacs-protocol`, string +rendering stays per-frontend. The §16 reading that decides it — each +frontend computes its own local layout facts, the shared crate owns the +semantic decision they feed — is a sharper split than "shared +vocabulary", and it adds **no wire message and no version bump**. +Q#LL8 is approved. **The framing is approved; implementation begins.** + Drafted while GitHub Actions was in a major outage and #220 could not merge. Nothing here depends on #220 landing; the two lanes touch no common code. @@ -1410,7 +1417,7 @@ contracts genuinely differ, and a shared four-count signature can only serve them by making units implicit --- which is how this contradiction arose. -### 5d.6 Where the classifier lives --- **OPEN, needs a decision** +### 5d.6 Where the classifier lives --- **ANSWERED: `pmacs-protocol`** `pmacs-gpu` depends on **`pmacs-protocol` only**, never on the `pmacs` lib (`pmacs-gpu/Cargo.toml:65`). So `format_scroll_indicator` is @@ -1425,13 +1432,27 @@ faces the same fork: maintained** --- the principle that chose byte-anchoring, additive `sub_row`, and a content-derived cache key. -**I lean (b) and will not take it unilaterally**, because it widens -`pmacs-protocol` from wire vocabulary toward presentation, which is a -`COHERENCE.md` §16 layering question and not this lane's to settle -alone. The narrow version --- share the `ScrollPosition` enum and -`classify`, leave the string rendering per-frontend --- keeps the -protocol crate holding a *decision type* rather than presentation, and -`panel.rs` is arguably precedent for that. +**Answered 2026-08-06: (b), in the narrow form.** `ScrollPosition` and +the pure `classify(first_visible, last_visible, byte_pos, byte_len)` +live in `pmacs-protocol`; **string rendering stays in each frontend.** + +The §16 reading that settles it, and it is a better statement of the +split than "shared vocabulary": **each frontend computes its own local +layout facts --- which rows are on screen is a question only it can +answer --- while the shared crate owns the common semantic decision +those facts feed.** That is not presentation moving into the protocol +crate; it is the *decision* being placed where both frontends are +structurally unable to disagree about it, with the rendering left where +it belongs. + +Two properties worth recording because they bound the change: + +- **No wire message and no protocol-version bump.** `classify` is a + pure function over values each side already has. Q#LL7's v22 variant + is unrelated and unaffected. +- **The §5d.3 defect becomes unrepresentable**, rather than guarded by + a reviewer noticing the second copy. A frontend cannot classify + differently, because there is only one classifier. ### 5d.7 The large-file guard