From 3d28a315736cbcb31c7f749e3f5bc37367a93f40 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Wed, 22 Jul 2026 15:04:52 -0400 Subject: [PATCH] docs: record tab-width implementation lane Record the proven implementation head, full local gate results, recovery commands, concurrent vterm overlap, and the advanced side-quest backlog. --- docs/active-work.md | 31 +++++++++++++++++++++-- docs/agent-handoff.md | 50 +++++++++++++++++++++++--------------- docs/side-quest-backlog.md | 29 +++++++++------------- 3 files changed, 72 insertions(+), 38 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 8ee476f..0cb0391 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -14,7 +14,8 @@ backlog. machine-local: `origin` may name this canonical URL, a release mirror, or something else, and therefore has no authority by name alone. - Canonical base at this snapshot: - `githubsucks/main` @ `8cbb9f4` (locals-query processing #134; protocol v18). + `githubsucks/main` @ `40111dc` (landed-state docs after locals-query #134; + protocol v18). - On the transfer source, `origin/main` named a release mirror at `d3fa632` and lagged badly. On the current destination, `origin` names the canonical URL. This difference is why all recovery begins by @@ -48,9 +49,35 @@ git worktree list git status --short --branch ``` -The first command must expose `8cbb9f4` or a newer intentional main. +The first command must expose `40111dc` or a newer intentional main. If it does not, stop and repair the remote/fetch configuration. +## Tab-width rendering parity lane + +- Portable branch: `githubsucks/tab-width-parity`. +- Base: canonical `main` @ `40111dc`; protocol v18. +- Approved framing: `docs/tab-width-parity-framing.md` revision 2; framing + branch head `9f2f0d5`. +- Implementation head: `9f7bc77`. +- State: implementation complete; PR pending. One fixed 8-column constant now + drives core/TUI columns, GPU code projection, and minimap width. Source bytes + and protocol ranges remain unchanged. +- Verification: `cargo fmt --check`; strict workspace Clippy; 1,763 default, + 1,939 CRDT, and 1,763 Lua 5.4 library tests; 2 tab-width acceptance tests; + M4 121 passed (3 ignored, 1 filtered); required GPU 119; workspace 2,911 + passed across 83 suites (19 ignored, 1 filtered); `git diff --check`. +- Concurrent PR #135 owns overlapping `Cargo.lock`, `pmacs-protocol/src/lib.rs`, + and `pmacs-gpu/src/main.rs`. This branch deliberately remains based on + canonical `main`; rebase and rerun gates if #135 lands first. +- Recovery: + + ```sh + git worktree add --track \ + -b tab-width-parity \ + ../pmacs-tab-width-parity \ + githubsucks/tab-width-parity + ``` + ## Parked lane: kill-ring browser + persistence - Portable branch: `githubsucks/kill-ring-browser` diff --git a/docs/agent-handoff.md b/docs/agent-handoff.md index 17eae1c..6ca615e 100644 --- a/docs/agent-handoff.md +++ b/docs/agent-handoff.md @@ -1,8 +1,8 @@ # Agent handoff — cross-machine continuity -**Last updated: 2026-07-22, after locals-query processing (#134) landed on -`main`, following modeline language detection (#132), Vterm Stage 2 (#130), -and mode system wiring (#129/#131). Vterm Stage 3 is not implemented.** +**Last updated: 2026-07-22, with tab-width rendering parity implemented on +`tab-width-parity` and awaiting review, after locals-query processing (#134) +landed on `main`. Vterm Stage 3 remains in review as #135.** This file is the bridge between development machines. If you are an agent reading this on a fresh clone: this document plus the `docs/*-framing.md` @@ -16,9 +16,9 @@ commands, read `docs/active-work.md` immediately after this file. ## 1. Where the project stands (2026-07-22) -- `main` @ `8cbb9f4` (locals-query processing #134), protocol **v18** - (`SUPPORTED=[6..18]`; v16 = `ThemeFacts`, v17 = `FontFacts`, v18 = - `StatuslineSegments`). +- `main` @ `40111dc` (landed-state documentation after locals-query processing + #134), protocol **v18** (`SUPPORTED=[6..18]`; v16 = `ThemeFacts`, v17 = + `FontFacts`, v18 = `StatuslineSegments`). - **Config registry LANDED — #127** (`docs/config-registry-framing.md` rev 3; merge `2e37c04`; two review rounds). `pmacs.config` is the typed, introspectable options registry the backlog ranked first, and @@ -315,6 +315,23 @@ commands, read `docs/active-work.md` immediately after this file. 8 CRDT; M4 114 passed (3 ignored, 1 filtered); required GPU 109; workspace 2,882 passed across 82 suites (19 ignored, 1 filtered); `git diff --check` clean. +- **Tab-width rendering parity IMPLEMENTED — review pending** + (`docs/tab-width-parity-framing.md` rev 2; branch `tab-width-parity`; + implementation `9f7bc77`). Source tabs remain one byte while every buffer + renderer follows the shared fixed `pmacs_protocol::TAB_STOP_COLUMNS = 8`. + - `src/display_width.rs` owns allocation-free Unicode/tab-aware byte-to-column + accounting for plain text, syntax, diagnostics, completion anchors, + buffer-style overlays, and search washes. + - The GPU rich-chunk projection expands source/adornment tabs before + cosmic-text shaping and retains first-class source-tab provenance. + Carets, hits, selections, peer washes, and diagnostic geometry share the + same source/projected boundary rules, including a soft wrap inside one + expanded tab. + - GPU minimap widths use the same tab/Unicode rule and refresh in the accepted + text-edit transaction. No config, wire shape, negotiation, or protocol + version changed. Local gates: 1,763 default + 1,939 CRDT + 1,763 Lua 5.4 + library tests; 2 focused acceptance; M4 121; required GPU 119; workspace + 2,911 across 83 suites; strict Clippy and diff check clean. - **PARKED: kill-ring browser + persistence.** Revision 2 framing is preserved on branch `kill-ring-browser`, but its `0efb5cd` scout is stale and must be repeated before implementation. No PR or implementation is @@ -501,19 +518,14 @@ acceptance. in per-session baselines; and any daemon-side reset needs its frontend mirror audited in the same round (the GPU snapshot arm missed search/menu/status the first time). -- **Tab width is a rendering-parity bug, NOT a config gap** (scouted at - `7bc0c61` while framing #127; still true). There are FIVE tab-width - sites across TWO crates with TWO different values: `TAB_WIDTH = 8` in - `src/text_view.rs`, `src/highlight.rs`, `src/diag.rs` and - `src/completion.rs`, versus `advance_minimap_col` in - `pmacs-gpu/src/main.rs` expanding to **4** — and the GPU's main text - path expands tabs *not at all* (buffer bytes reach the frontend raw, - so a literal `\t` is shaped by the font). `editor.tab-width` is - therefore the obvious-looking first config adopter and is not one: - defining the setting cannot make the GPU honor it. Doing it properly - needs frontend tab expansion plus a wire-or-frontend-local decision. - Deferred from #127 on exactly these grounds; don't re-plan it as a - config task. +- **Tab width is a rendering semantic, NOT a config gap.** The implementation + on `tab-width-parity` fixes the width at the TUI's established 8 columns, + shares that constant through `pmacs-protocol`, and expands tabs only in each + display projection. Defining `editor.tab-width` could not have fixed the GPU: + source text and semantic spans stay byte-addressed while cosmic-text needs + projected spaces plus an inverse hit/caret map. A future configurable width + would require a buffer-effective frontend fact and cache invalidation; do not + re-plan it as a scalar config-only change. - **A test that never runs passes.** Two #127 review-round tests passed vacuously at first: `pmacs.editor.save()` is the RAW save, while `buffer.before-save` fires inside the `buffer.save` COMMAND diff --git a/docs/side-quest-backlog.md b/docs/side-quest-backlog.md index 9e2609a..9f978d9 100644 --- a/docs/side-quest-backlog.md +++ b/docs/side-quest-backlog.md @@ -120,14 +120,12 @@ The direct continuation of the #114–#118 grammar/detection stack. language-aware indent, per-language comment padding, and per-project compile commands — the last three are now ordinary work, expressed as a `buffer.after-load` hook calling `set_local`, not blocked work. -- **Tab-width rendering parity** — was listed above as a config - consequence; it is not. `TAB_WIDTH = 8` appears four times in the - daemon (`text_view`, `highlight`, `diag`, `completion`), the GPU - minimap's `advance_minimap_col` uses **4**, and the GPU main text path - expands tabs *not at all* — raw `\t` reaches glyphon and is shaped by - the font. Defining `editor.tab-width` cannot make the GPU honor it; - this needs frontend tab expansion plus a wire-or-frontend-local - decision. Deferred from #127 on those grounds. +- ~~**Tab-width rendering parity**~~ — **IMPLEMENTED, IN REVIEW.** One fixed + 8-column constant now drives the core/TUI display-column paths, GPU rich-text + projection, and minimap widths. GPU expansion retains source-tab provenance, + so caret, hit, selection, and diagnostic geometry remain byte-correct through + adornments and soft wraps. Source text and protocol ranges remain raw; this + adds no config key or wire change. See `docs/tab-width-parity-framing.md`. - **Real `read_only` buffer flag** on both edit paths — true immutability for panels / REPL / generated buffers. - ~~**Mode system wiring**~~ — **SHIPPED as #129.** Per-buffer major modes @@ -237,15 +235,12 @@ guides (visual, not color). ## North star (highest-leverage first) -**The original north-star items, mode-system wiring, and locals-query -processing have now shipped** — multi-language injections (#122), the config -registry (#127), JSON + YAML (#123), mode-system wiring (#129), and locals -queries (#134). The remaining board: - -1. **Tab-width rendering parity** — five constants across two crates - with two different values, and no tab expansion at all on the GPU - main text path. Explicitly NOT a config-registry task; see the entry - under "Cross-cutting substrate". +**The original north-star items have shipped or reached review** — +multi-language injections (#122), the config registry (#127), JSON + YAML +(#123), mode-system wiring (#129), locals queries (#134), and tab-width +rendering parity (`tab-width-parity`, review pending). The remaining board now +starts with the broader ranked arcs below rather than another unresolved +cross-frontend rendering invariant. Beyond those, the cleanest remaining one-shots in the highlight family are the HTML/CSS grammars that light up more injection *consumers*; modeline detection