From 932b3ab179daeb55d4eb698c6b7cd65263a21a7d Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Wed, 5 Aug 2026 13:34:22 +0200 Subject: [PATCH] =?UTF-8?q?docs(tree):=20revision=203=20=E2=80=94=20an=20e?= =?UTF-8?q?xample=20is=20not=20a=20consumer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three review findings, all verified in source before applying, plus one found while verifying them. `*references*` HAS NO `g` AND NO `on_refresh`. Revision 2 asserted it twice. Its header is "RET visit n/p move q quit" and it supplies only `on_visit` (lsp.lua:2442). The consumer with refresh is `*lsp*` (lsp.status, lsp.lua:3004). The error is worth naming precisely because it will recur otherwise: I read `listview.lua`'s MODULE-DOCSTRING EXAMPLE, which illustrates the API using `name = "*references*"` and a header containing `g refresh`, and treated it as the real consumer. An example written to show the shape of an API is not evidence about any caller of it. The refresh-scoping conclusion is unaffected — it rested on the OUTLINE lacking refresh, which holds. THE BRANCH PLAN STILL NAMED buffer-list. Acceptance 5 had already been corrected for exactly that error in the previous round; the same claim survived one section further down. Fixing a mistake where it was reported is not the same as fixing it where it occurs. "BYTE-IDENTICALLY, PINNED BY THEIR EXISTING SUITES" WAS UNSUPPORTED. `listview_acceptance` says in its own header that the references panel needs a live LSP and is validated manually or via the m4 harness — it does not exercise `*references*` at all — and the m4 hover test asserts content PRESENCE, not byte-exact output. So the criterion claimed coverage that does not exist. It is now posed as a decision rather than patched: either byte-identity becomes a new test this stage writes (needing the fake-LSP harness for references), or the claim weakens to the substrate behaviours actually pinned. Leaning recorded toward writing the test, because a flat consumer silently gaining an indent column is precisely what this criterion exists to catch and content-presence would not see it. FOUND WHILE VERIFYING: §14's "exactly three `pmacs.listview.open` call sites" is STALE. There are four. `*lsp*` arrived with Journey Stage 1b-2 (#204), after §14's audit at ad41cf1, and it is the ONLY listview consumer with refresh — which is why §1.5a's conclusion holds rather than being luck. §14's line numbers have drifted too. Recorded in a new §1.3a so the next reader does not inherit "three". Framing only, still unapproved. Co-Authored-By: Claude Opus 5 (1M context) --- docs/tree-primitive-framing.md | 101 +++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 11 deletions(-) diff --git a/docs/tree-primitive-framing.md b/docs/tree-primitive-framing.md index 1640191..785c646 100644 --- a/docs/tree-primitive-framing.md +++ b/docs/tree-primitive-framing.md @@ -1,8 +1,32 @@ # Framing — the tree primitive -**Revision 2.** Status: framing only, **not yet approved**. No +**Revision 3.** Status: framing only, **not yet approved**. No implementation. Scouted against `githubsucks/main` @ `12f2970`. +**Revision 2 → 3**, three further review findings, all verified in +source: + +- **`*references*` has no `g` and no `on_refresh`** — revision 2 claimed + it twice. The consumer with refresh is **`*lsp*`** (§1.5a). The error + came from reading `listview.lua`'s **module-docstring example**, which + illustrates the API using `*references*` with `g refresh` in the + header. An example is not a consumer. *The refresh-scoping conclusion + is unaffected — it depended on the OUTLINE lacking refresh, which + holds.* +- **The branch plan still said "references or buffer-list"** — the same + `*buffer-list*` error acceptance 5 had already been corrected for, + surviving one section further down. +- **"Byte-identically, pinned by their existing suites" was + unsupported.** `listview_acceptance` states in its own header that + `*references*` needs a live LSP and is not exercised there, and the m4 + hover test asserts content *presence*, not byte-exact output. + Acceptance 5 now poses that as a decision — write the byte-identity + test, or weaken the claim — with a leaning and its cost. + +**Found while verifying those: §14's "exactly three call sites" is +stale — there are FOUR** (§1.3a), and the fourth (`*lsp*`, added by +#204) is the only one with refresh. + **Revision 1 → 2**, all from review, all verified against source before applying: @@ -135,6 +159,28 @@ current one. 3. It is harmless while `*workers*` is not a panel, and inherits the hazard the moment it becomes one.)* +### 1.3a There are FOUR listview consumers now, not three + +§14 measured "exactly **three** `pmacs.listview.open` call sites, all +three in `builtin/runtime/lsp.lua`" at `ad41cf1`. **There are four**, and +the fourth matters here: + +| call site | panel | `on_visit` | `on_refresh` / `g` | +|---|---|---|---| +| `lsp.lua:2442` | `*references*` | yes | **no** | +| `lsp.lua:2488` | `*outline*` | yes | **no** | +| `lsp.lua:2924` | `*lsp-help*` | no | **no** | +| `lsp.lua:3004` | `*lsp*` (`lsp.status`) | no | **yes** | + +`*lsp*` arrived with Journey Stage 1b-2 (#204), after §14's audit. It is +**the only listview consumer with refresh at all**, which is why §1.5a's +scoping conclusion holds: refresh is a feature exactly one panel has, and +it is not the anchor. + +§14's line numbers have also drifted (`:2056`/`:2102`/`:2513` against +today's `:2442`/`:2488`/`:2924`). The count is the part that matters; +this is recorded so the next reader does not inherit "three". + ### 1.4 What listview's model would have to gain listview's contract today: @@ -212,9 +258,17 @@ an async LSP round-trip with its own await, failure and staleness handling — and it raises who owns the resulting state when the response arrives against a buffer the user may have edited or left. -That is a real feature (`*references*` has `g` and an `on_refresh`; the -outline never gained one), and it is **not** a tree concern. Bundling it -here would make the tree lane responsible for LSP request lifecycle. +That is a real feature — **`*lsp*` (`lsp.status`) has `g refresh` and an +`on_refresh`** (`lsp.lua:3004`); the outline never gained one — and it is +**not** a tree concern. Bundling it here would make the tree lane +responsible for LSP request lifecycle. + +*(Revision 2 attributed refresh to `*references*` twice. It has neither: +its header is `RET visit n/p move q quit` and it supplies only +`on_visit` (`lsp.lua:2442`). The error came from reading +`listview.lua`'s **module-docstring example**, which illustrates the API +using `name = "*references*"` and a header containing `g refresh` — an +example, not a consumer.)* **Consequence for acceptance:** the criteria are re-scoped to what the anchor consumer can actually exercise — collapse and selection surviving @@ -330,10 +384,32 @@ fixed until Q#TR1–TR3 are decided. The shapes they will take: 4. **No new interaction island**: every tree key is a buffer-local binding, and the dispatch-shadow count is unchanged. Asserted, not assumed. -5. **listview's OTHER consumers are unaffected** — `*references*` and - `*lsp-help*`, which with `*outline*` are the **only three - `pmacs.listview.open` call sites, all in `lsp.lua`**. They render - byte-identically, pinned by their existing suites. +5. **listview's OTHER consumers are unaffected** — `*references*`, + `*lsp-help*` and `*lsp*` (§1.3a: four call sites, all in `lsp.lua`). + + **What existing suites actually pin, stated honestly.** + `listview_acceptance` drives the substrate hermetically and says so + in its own header: *"The references panel itself needs a live LSP and + is validated manually / via the m4 harness"* — so **it does not + exercise `*references*` at all**. The m4 hover test asserts content + *presence*, not byte-exact output. **"Byte-identical, pinned by + existing suites" was therefore unsupported** for both panels named. + + So this criterion needs a decision, not a wording tweak: + - **either** byte-identity becomes a **new test requirement** this + stage writes — capturing each panel's rendered buffer before and + after and diffing it, which needs the m4 fake-LSP harness for + `*references*`; + - **or** the claim weakens to what is genuinely pinned today: + the substrate behaviours `listview_acceptance` covers (open, + navigate, visit, `q` restore, the read-only intercept, the + round-trip gate, refresh) plus content-presence for hover. + + **Leaning: write the byte-identity test**, because a flat consumer + silently gaining an indent column is exactly the regression this + criterion exists to catch, and content-presence would not see it. + Recorded as a leaning rather than a decision because it costs harness + work the stage has not scoped. **Revision 1 named `*buffer-list*` and project search here and was wrong** — §14 measured that they do **not** use listview and calls @@ -363,8 +439,8 @@ fixed until Q#TR1–TR3 are decided. The shapes they will take: raw-switch hazard noted there. - **Tree rendering in the GPU frontend** beyond whatever the shared generated-buffer path already gives. -- **Giving the outline a refresh** (§1.5a). `*references*` has `g` and - an `on_refresh`; the outline never gained one. Adding it means +- **Giving the outline a refresh** (§1.5a). **`*lsp*` has `g` and an + `on_refresh`**; the outline never gained one. Adding it means re-requesting `textDocument/documentSymbol` with its own await, failure and staleness handling, and deciding who owns the result when it arrives against a buffer the user may have edited. **That is LSP @@ -393,7 +469,10 @@ Not settled, because it depends on Q#TR1. Two shapes: - **If listview is extended:** one branch, with the flat-consumer no-change proof (acceptance 5) landing *before* the outline adopts, so - a regression in references or buffer-list is attributable. + a regression in `*references*`, `*lsp-help*` or `*lsp*` is + attributable. *(Revision 2 said "references or buffer-list" here — + the same `*buffer-list*` error acceptance 5 had already been corrected + for. `*buffer-list*` does not use listview.)* - **If a separate `treeview`:** the primitive and its first consumer are separable, and the outline's adoption can be its own PR.