docs: record landed modeline detection

Advance the durable baseline to PR #132, remove the completed volatile lane,
and record the shared language pin, bounded modeline contract, Vterm Stage 2
landing, remaining deferrals, and current roadmap state.
This commit is contained in:
Levi Neuwirth 2026-07-22 11:30:45 -04:00
parent 1dd47fcad1
commit 9b8b312848
5 changed files with 54 additions and 76 deletions

View File

@ -14,7 +14,7 @@ backlog.
machine-local: `origin` may name this canonical URL, a release mirror, machine-local: `origin` may name this canonical URL, a release mirror,
or something else, and therefore has no authority by name alone. or something else, and therefore has no authority by name alone.
- Canonical base at this snapshot: - Canonical base at this snapshot:
`githubsucks/main` @ `86fc1bc` (Vterm Stage 2 #130 merged; protocol v18). `githubsucks/main` @ `1dd47fc` (modeline detection #132 merged; protocol v18).
- On the transfer source, `origin/main` named a release mirror at - On the transfer source, `origin/main` named a release mirror at
`d3fa632` and lagged badly. On the current destination, `origin` names `d3fa632` and lagged badly. On the current destination, `origin` names
the canonical URL. This difference is why all recovery begins by the canonical URL. This difference is why all recovery begins by
@ -48,46 +48,9 @@ git worktree list
git status --short --branch git status --short --branch
``` ```
The first command must expose `86fc1bc` or a newer intentional main. The first command must expose `1dd47fc` or a newer intentional main.
If it does not, stop and repair the remote/fetch configuration. If it does not, stop and repair the remote/fetch configuration.
## Modeline detection implementation lane
- Portable branch: `githubsucks/modeline-detection`
- Approved framing head: `6b4f3c3`
- Implementation head: `f8d05d2`
- Base: originally canonical `main` @ `d5d9b9c`; current canonical `main`
@ `86fc1bc` (Vterm Stage 2 #130) is integrated before merge.
- PR: #132, <https://github.com/levineuwirth/pmacs/pull/132>, open against
canonical `main` and explicitly authorized for merge.
- State: Revision 2's bounded Emacs/Vim parser, explicit-over-inferred
precedence, alias normalization, shared fresh-load language pin, LSP path
guard, and all thirteen acceptance criteria are implemented. Protocol
remains v18.
- Verification:
- focused modeline + shebang-pin acceptance before integration: 7 passed on
default LuaJIT and 7 passed on non-default Lua 5.4;
- post-integration `cargo fmt --check`;
- post-integration `cargo clippy --workspace --all-targets -- -D warnings`;
- post-integration `cargo test --lib`: 1,753 passed;
- post-integration `cargo test --lib --features crdt`: 1,929 passed;
- post-integration `cargo test --test m4_acceptance -- --skip basedpyright`:
120 passed, 3 ignored, 1 filtered;
- post-integration `PMACS_REQUIRE_GPU=1 cargo test -p pmacs-gpu`: 109 passed;
- post-integration `cargo test --workspace -- --skip basedpyright`: 2,888
passed across 82 suites, 19 ignored, 1 filtered;
- `git diff --check`.
- Next: push the current-main integration and merge PR #132 as authorized.
Recovery worktree on a machine that does not already own the branch:
```sh
git worktree add --track \
-b modeline-detection \
../pmacs-modeline-detection \
githubsucks/modeline-detection
```
## Parked lane: kill-ring browser + persistence ## Parked lane: kill-ring browser + persistence
- Portable branch: `githubsucks/kill-ring-browser` - Portable branch: `githubsucks/kill-ring-browser`

View File

@ -1,10 +1,9 @@
# Agent handoff — cross-machine continuity # Agent handoff — cross-machine continuity
**Last updated: 2026-07-22, after Vterm Stage 2 PR #130 review round 2 **Last updated: 2026-07-22, after modeline language detection (#132) and
was addressed and approved for merge; mode system wiring (#129) and its Vterm Stage 2 (#130) landed on `main`, atop mode system wiring (#129/#131),
handoff (#131), config registry (#127), Vterm Stage 1 terminal core (#126), config registry (#127), Vterm Stage 1 terminal core (#126), and completed
and completed Themes Arc 4 (#120/#124/#125) are landed on `main`. Vterm Themes Arc 4 (#120/#124/#125). Vterm Stage 3 is not implemented.**
Stage 3 is not implemented.**
This file is the This file is the
bridge between development machines. If you are an agent reading bridge between development machines. If you are an agent reading
this on a fresh clone: this document plus the `docs/*-framing.md` this on a fresh clone: this document plus the `docs/*-framing.md`
@ -18,7 +17,7 @@ commands, read `docs/active-work.md` immediately after this file.
## 1. Where the project stands (2026-07-22) ## 1. Where the project stands (2026-07-22)
- `main` @ `d5d9b9c` (mode system handoff #131), protocol **v18** - `main` @ `1dd47fc` (modeline detection #132), protocol **v18**
(`SUPPORTED=[6..18]`; v16 = `ThemeFacts`, v17 = `FontFacts`, v18 = (`SUPPORTED=[6..18]`; v16 = `ThemeFacts`, v17 = `FontFacts`, v18 =
`StatuslineSegments`). `StatuslineSegments`).
- **Config registry LANDED — #127** (`docs/config-registry-framing.md` - **Config registry LANDED — #127** (`docs/config-registry-framing.md`
@ -81,6 +80,21 @@ commands, read `docs/active-work.md` immediately after this file.
- The built-in `mode` statusline provider reads `ctx.buffer`, so passive - The built-in `mode` statusline provider reads `ctx.buffer`, so passive
splits render their own mode. Real-daemon acceptance covers all ten framing splits render their own mode. Real-daemon acceptance covers all ten framing
criteria across both Lua backends and Linux/macOS CI. criteria across both Lua backends and Linux/macOS CI.
- **Modeline language detection LANDED — #132**
(`docs/modeline-detection-framing.md` rev 2; merge `1dd47fc`). Fresh loads
scan bounded Emacs `-*- mode: ... -*-` and Vim/Vi `ft=` / `filetype=`
modelines without evaluating file content, normalize common editor aliases,
and give explicit modelines precedence over inferred language.
- `builtin/runtime/syntax.lua` owns one per-buffer fresh-load decision:
modeline → bundled grammar extension → LSP filetype extension → exact
filename → shebang. Syntax, initial major mode, pairing, comments, and LSP
all reuse that pin; LSP retains its independent backing-path guard.
- Editing a modeline or shebang does not switch an attached parser or make
language-aware consumers diverge. Close/reopen re-evaluates changed file
metadata. Explicit post-load major-mode overrides remain independent.
- Bounded valid unknown names remain passive major modes without starting an
unavailable parser or server. All thirteen framing criteria are covered on
LuaJIT and Lua 5.4. No Rust or protocol surface changed; protocol stays v18.
- **Syntax-highlight / language-detection side-quest (#114#118) - **Syntax-highlight / language-detection side-quest (#114#118)
LANDED** — a one-shot arc built in sibling worktrees off main while LANDED** — a one-shot arc built in sibling worktrees off main while
the user's themes lane (`theme-faces`) ran concurrently in the shared the user's themes lane (`theme-faces`) ran concurrently in the shared
@ -90,15 +104,15 @@ commands, read `docs/active-work.md` immediately after this file.
the ABI-current `tree-sitter-containerfile`, NOT the dead the ABI-current `tree-sitter-containerfile`, NOT the dead
`tree-sitter-dockerfile` which pins `tree-sitter ^0.20`), make, `tree-sitter-dockerfile` which pins `tree-sitter ^0.20`), make,
cmake, python, go, javascript (+jsx), typescript (+tsx), toml, zig. cmake, python, go, javascript (+jsx), typescript (+tsx), toml, zig.
- **Detection chain** (`resolve_active_language` in syntax.lua / - **Detection chain and pin** (`builtin/runtime/syntax.lua`): modeline →
`buffer_language` in lsp.lua): extension → LSP filetype map → grammar extension → LSP filetype map → filename → shebang. User-extensible
filename → shebang. New user-extensible Lua surfaces Lua surfaces include `pmacs.parse.modeline_aliases`, `.shebangs`,
`pmacs.parse.shebangs` / `.filenames` and `.filenames`, `language_from_modeline`, `language_from_shebang`,
`pmacs.parse.language_from_shebang` / `language_from_filename`. `language_from_filename`, and the pinned `buffer_language`.
Grammar name MUST equal the `pmacs.lsp.config.<name>` key (grammar `builtin/runtime/lsp.lua` delegates to that shared decision after enforcing
detection wins over the filetype map, so it fixes the LSP id too). its backing-path requirement. Grammar name MUST equal the
A buffer keeps its first-attached grammar across edits/switches (no `pmacs.lsp.config.<name>` key. A buffer keeps its pinned language across
re-sniff of a since-edited shebang). edits/switches; close/reopen performs a fresh bounded inference.
- **LSP configs added**: dockerfile (`docker-langserver --stdio`), - **LSP configs added**: dockerfile (`docker-langserver --stdio`),
cmake (`cmake-language-server`, config via cmake (`cmake-language-server`, config via
`init_options.buildDirectory="build"` — it does NOT pull `init_options.buildDirectory="build"` — it does NOT pull
@ -249,9 +263,10 @@ commands, read `docs/active-work.md` immediately after this file.
protocol-owned wire types/limits, and a deliberate complete-frame limit protocol-owned wire types/limits, and a deliberate complete-frame limit
decision: 16 MiB is insufficient; use a measured legal-worst cap or decision: 16 MiB is insufficient; use a measured legal-worst cap or
aggregate bound, never silent chunking. aggregate bound, never silent chunking.
- **Stage 2 TUI is implemented on `vterm-tui`** (`docs/vterm-framing.md` - **Stage 2 TUI LANDED ON `main` — #130** (merge `86fc1bc`;
Revision 7, criteria 1527). `TerminalViewKey` keys per-frontend/window `docs/vterm-framing.md` Revision 7, criteria 1527). `TerminalViewKey` keys
projection state over one shared process/screen; logical row anchors retain per-frontend/window projection state over one shared process/screen; logical
row anchors retain
scroll/selection through reflow. One authenticated frontend controls at scroll/selection through reflow. One authenticated frontend controls at
most one session, with atomic replacement and release on most one session, with atomic replacement and release on
focus/switch/kill/detach. focus/switch/kill/detach.
@ -312,8 +327,8 @@ commands, read `docs/active-work.md` immediately after this file.
fix (#101). fix (#101).
- **Arc 4 (themes + extensibility) COMPLETE** — named UI faces (#120), - **Arc 4 (themes + extensibility) COMPLETE** — named UI faces (#120),
live GPU font preferences (#124), statusline providers (#125). live GPU font preferences (#124), statusline providers (#125).
- **Arc 5 terminal stage ACTIVE** — compile mode (#113) and Vterm terminal - **Arc 5 terminal stage ACTIVE** — compile mode (#113), Vterm terminal core
core (#126) landed; Vterm TUI is the next formal stage. (#126), and Vterm TUI (#130) landed; protocol/GPU Stage 3 is next.
- **Config registry COMPLETE (#127)** — not a numbered arc; it was the - **Config registry COMPLETE (#127)** — not a numbered arc; it was the
cross-cutting substrate ranked first on cross-cutting substrate ranked first on
`docs/side-quest-backlog.md`'s north star, and it unblocks the `docs/side-quest-backlog.md`'s north star, and it unblocks the
@ -551,8 +566,8 @@ currently accepted for `autosave.interval-ms`, where a per-buffer
value is meaningless. value is meaningless.
**Tab width is NOT a config gap** — see §5. **Tab width is NOT a config gap** — see §5.
Mode system (SHIPPED #129): minor modes, `buffer.after-mode-change`, Mode system (SHIPPED #129): minor modes, `buffer.after-mode-change`,
mode-scoped settings, modeline detection, `describe-mode`, and persistence of mode-scoped settings, `describe-mode`, and persistence of explicit
explicit major-mode overrides/clears across sessions. major-mode overrides/clears across sessions. Modeline detection shipped in #132.
Highlight/detection (from the #114#118 side-quest + injections #122): Highlight/detection (from the #114#118 side-quest + injections #122):
locals-query processing (run each grammar's LOCALS_QUERY so locals-query processing (run each grammar's LOCALS_QUERY so
`#is?`/`#is-not? local` is honored instead of the current fail-closed `#is?`/`#is-not? local` is honored instead of the current fail-closed
@ -564,8 +579,8 @@ comment schemes), child-tree incrementality + range-scoped layer rebuild
runtime/Lua-registered languages (v1 resolves only against runtime/Lua-registered languages (v1 resolves only against
`BUILTIN_LANGUAGES`), and the next injection *consumers* gated on new `BUILTIN_LANGUAGES`), and the next injection *consumers* gated on new
grammars — HTML/CSS/GraphQL/SQL (`<script>`/`<style>`, JS/TS template grammars — HTML/CSS/GraphQL/SQL (`<script>`/`<style>`, JS/TS template
literals, doc-comment code); modeline detection as a 5th layer ~~modeline detection as a 5th layer (`-*- mode: … -*-` /
(`-*- mode: … -*-` / `# vim: ft=…`); `# vim: ft=…`)~~ **SHIPPED #132**;
byte-accurate multibyte cursor placement in `move_active_cursor_to` byte-accurate multibyte cursor placement in `move_active_cursor_to`
(still steps one codepoint per LSP byte column). A full Jupyter `.ipynb` (still steps one codepoint per LSP byte column). A full Jupyter `.ipynb`
setup (reader → editable → kernel execution) now has its JSON grammar setup (reader → editable → kernel execution) now has its JSON grammar

View File

@ -1,7 +1,7 @@
# Modeline language detection — side quest # Modeline language detection — side quest
**Status:** Revision 2, approved for implementation by the user on 2026-07-22. **Status:** Revision 2 implemented and landed as PR #132 on 2026-07-22
No implementation was present at approval. (`1dd47fc`). All thirteen acceptance criteria shipped without a protocol change.
**Base:** `githubsucks/main` at `d5d9b9c`; protocol v18. **Base:** `githubsucks/main` at `d5d9b9c`; protocol v18.
## Problem ## Problem

View File

@ -80,7 +80,7 @@ preference at protocol v17; and composable per-window
`pmacs.statusline` providers transported to semantic/GPU frontends by `pmacs.statusline` providers transported to semantic/GPU frontends by
protocol-v18 `StatuslineSegments`. protocol-v18 `StatuslineSegments`.
### Arc 5 — Terminal, staged — VTERM STAGE 2 ON FEATURE BRANCH ### Arc 5 — Terminal, staged — VTERM STAGES 12 LANDED
- **Compile mode landed in #113**: line-oriented PTY/ANSI output, - **Compile mode landed in #113**: line-oriented PTY/ANSI output,
error-regex navigation, and `M-x compile`. error-regex navigation, and `M-x compile`.
@ -89,10 +89,10 @@ protocol-v18 `StatuslineSegments`.
encoders, internal `TerminalManager`, read-only identity buffers, process encoders, internal `TerminalManager`, read-only identity buffers, process
lifecycle, control-free renderer-boundary cells, and headless real-PTY lifecycle, control-free renderer-boundary cells, and headless real-PTY
acceptance. acceptance.
- **Vterm Stage 2 TUI is implemented on `vterm-tui`**: terminal-window - **Vterm Stage 2 TUI landed in #130**: terminal-window composition,
composition, input/resize, per-context scroll/selection/copy, authenticated input/resize, per-context scroll/selection/copy, authenticated frontend
frontend ownership, BEL/clipboard drainage, and the strict Lua surface. ownership, BEL/clipboard drainage, and the strict Lua surface.
- **Vterm Stage 3 protocol/GPU follows Stage 2**: additive protocol v19 - **Vterm Stage 3 protocol/GPU is next**: additive protocol v19
complete frames, authenticated daemon routing, and native GPU terminal complete frames, authenticated daemon routing, and native GPU terminal
rendering. Its framing must resolve the 16 MiB transport cap's incompatibility rendering. Its framing must resolve the 16 MiB transport cap's incompatibility
with the legal worst complete terminal frame; never silently chunk. with the legal worst complete terminal frame; never silently chunk.

View File

@ -40,8 +40,8 @@ The direct continuation of the #114#118 grammar/detection stack.
languages (v1 resolves only against `BUILTIN_LANGUAGES`), and new languages (v1 resolves only against `BUILTIN_LANGUAGES`), and new
injection *consumers* gated on grammars — HTML/CSS/GraphQL/SQL injection *consumers* gated on grammars — HTML/CSS/GraphQL/SQL
(`<script>`/`<style>`, template literals, doc-comment code). (`<script>`/`<style>`, template literals, doc-comment code).
- **Modeline detection** — a 5th detection layer (`-*- mode: … -*-`, - ~~**Modeline detection**~~**SHIPPED as #132.** Bounded Emacs/Vim
`# vim: ft=…`) after extension → filetype → filename → shebang. metadata now precedes extension → filetype → filename → shebang inference.
- **JSON + YAML — PR #123 open.** Grammars and LSP configs exist on the - **JSON + YAML — PR #123 open.** Grammars and LSP configs exist on the
feature line; review fixes are preserved on feature line; review fixes are preserved on
`json-yaml-handoff-2026-07-20`. A real YAML-through-pmacs smoke, `json-yaml-handoff-2026-07-20`. A real YAML-through-pmacs smoke,
@ -248,7 +248,7 @@ multi-language injections (#122), the config registry (#127), JSON + YAML
main text path. Explicitly NOT a config-registry task; see the entry main text path. Explicitly NOT a config-registry task; see the entry
under "Cross-cutting substrate". under "Cross-cutting substrate".
Beyond those, the cleanest one-shots in the highlight family are Beyond those, the cleanest remaining one-shots in the highlight family are the
**modeline detection** and the HTML/CSS grammars that light up more HTML/CSS grammars that light up more injection *consumers*; modeline detection
injection *consumers*; the most-missed editing table-stakes remain shipped in #132. The most-missed editing table-stakes remain **word-kills +
**word-kills + `C-SPC` set-mark**. `C-SPC` set-mark**.