docs(vterm): record Stage 1 review round 1
Record the IND, NEL, RI, TERM, portable-liveness, and tab-stop fixes; make the line-oriented EOF contract explicit; and list the accepted fidelity, performance, and lifecycle deferrals. Update final from-start gates and the clean behavioral bite proof.
This commit is contained in:
parent
bf972a76fa
commit
5d5055871f
|
|
@ -1,8 +1,8 @@
|
|||
# Agent handoff — cross-machine continuity
|
||||
|
||||
**Last updated: 2026-07-21, with Vterm Stage 1 implemented and fully gated on
|
||||
the `vterm-core` feature branch (awaiting review; not merged). Vterm Stages 2
|
||||
and 3 are not implemented.** This file is the bridge between development
|
||||
**Last updated: 2026-07-21, after Vterm Stage 1 review round 1 was addressed
|
||||
and fully gated on `vterm-core` (awaiting follow-up; not merged). Vterm Stages
|
||||
2 and 3 are not implemented.** This file is the bridge between development
|
||||
machines. If you are an agent reading on a fresh clone: this document
|
||||
plus the `docs/*-framing.md` files ARE your memory. Read this fully
|
||||
before taking on work, seed persistent memory from it, and **update this
|
||||
|
|
@ -121,11 +121,11 @@ next machine reads it the way you just did.
|
|||
`basedpyright` filtered); `git diff --check` clean. Stage 3 landed
|
||||
as #125 and completed Arc 4 on `main`.
|
||||
- **Vterm Stage 1 terminal core IMPLEMENTED ON `vterm-core`, FULLY GATED,
|
||||
AWAITING REVIEW, NOT MERGED** (`docs/vterm-framing.md` rev 3).
|
||||
- Implementation commits: `bbc1f33` (Stage 1) and `962944b` (Darwin PTY
|
||||
signal normalization); pull request: #126,
|
||||
<https://github.com/levineuwirth/pmacs/pull/126> (open, non-draft,
|
||||
targeting `main`).
|
||||
AWAITING REVIEW FOLLOW-UP, NOT MERGED** (`docs/vterm-framing.md` rev 4).
|
||||
- Implementation commits: `bbc1f33` (Stage 1), `962944b` (Darwin signal
|
||||
normalization), and review fixes `f0a235f`, `28f2e6c`, `bf972a7`; pull
|
||||
request: #126, <https://github.com/levineuwirth/pmacs/pull/126> (open,
|
||||
non-draft, targeting `main`).
|
||||
- `AnsiParserProfile::{LineOriented, FullScreen}` preserves compile/REPL
|
||||
behavior while terminal PTYs emit the full cursor/mode/device operation
|
||||
set. `src/terminal/{screen,input,session}.rs` owns the state machine,
|
||||
|
|
@ -147,15 +147,23 @@ next machine reads it the way you just did.
|
|||
output before exact PID/outcome annotation. One-row annotation visibility,
|
||||
TERM-ignoring shutdown, spawn rollback, buffer-kill prune, and immutable
|
||||
empty CRDT bootstrap are pinned.
|
||||
- Final from-start rerun after the portability fix: Clippy clean; 1,658
|
||||
default + 1,834 CRDT library tests (3 ignored each); 8 default + 9 CRDT
|
||||
vterm acceptance; M4 114 passed (3 ignored, 1 filtered); required GPU 109;
|
||||
workspace 2,765 passed across 79 suites (19 ignored, 1 filtered); diff
|
||||
check clean. The first gate pass found only missing crate docs in the new
|
||||
acceptance; PR CI then exposed Darwin's numeric `strsignal` suffix. Both
|
||||
fixes were followed by a complete restart from gate 1.
|
||||
`scripts/bite main src/lib.rs --test vterm_stage1_acceptance` is green only
|
||||
as the helper's explicitly weaker compile-time API bite.
|
||||
- Review round 1 added typed IND/NEL/RI with margin-correct screen behavior,
|
||||
defaults absent `TERM` to `xterm-256color`, makes shutdown liveness
|
||||
acceptance portable with `kill(pid, 0)`, and preserves custom tab stops on
|
||||
resize. Stage 2 must uniquify default terminal buffer names. Exact CUU/CUD
|
||||
margin clamping, combining across controls, xterm alternate-screen details,
|
||||
legacy non-SGR mouse, and the printable ASCII allocation fast path are
|
||||
explicit post-arc deferrals in the framing.
|
||||
- Final from-start rerun after review round 1: Clippy clean; 1,660 default +
|
||||
1,836 CRDT library tests (3 ignored each); 8 default + 9 CRDT vterm
|
||||
acceptance; M4 114 passed (3 ignored, 1 filtered); required GPU 109;
|
||||
workspace 2,767 passed across 79 suites (19 ignored, 1 filtered); diff
|
||||
check clean. The first review Clippy pass found only identical LF/IND match
|
||||
arms; after consolidation the complete sequence restarted at gate 1.
|
||||
`scripts/bite HEAD^ src/ansi.rs --lib
|
||||
parser_split_points_produce_identical_screen` is a clean behavioral bite;
|
||||
the original `main`/crate-root bite remains explicitly weaker compile-time
|
||||
API evidence.
|
||||
- Stage 2 reviews require a durable focus/input resize owner, owning
|
||||
`FrontendId` for the global `C-c` continuation, and local clipboard/BEL
|
||||
signal drainage. Stage 3 additionally owns `pmacs-gpu/src/attach.rs`,
|
||||
|
|
|
|||
|
|
@ -92,12 +92,13 @@ faces, and semantic/GPU transport through protocol v18.
|
|||
|
||||
- **Compile-mode landed** in #113: line-oriented PTY/ANSI output,
|
||||
error-regex navigation, and `M-x compile`.
|
||||
- **Vterm Stage 1 terminal core** is implemented and fully gated on
|
||||
`vterm-core`, awaiting review and **not merged**. It adds the compatibility
|
||||
parser profiles, bounded VT screen/scrollback/reflow state machine, input
|
||||
encoders, internal `TerminalManager`, read-only identity-buffer invariant,
|
||||
process lifecycle/final annotations, and headless real-PTY acceptance. It
|
||||
intentionally adds no interactive Lua command or frontend rendering.
|
||||
- **Vterm Stage 1 terminal core** is implemented, review round 1 is addressed,
|
||||
and the branch is fully gated on `vterm-core`; PR #126 awaits review
|
||||
follow-up and is **not merged**. It adds compatibility parser profiles,
|
||||
bounded VT screen/scrollback/reflow state, IND/NEL/RI, input encoders,
|
||||
internal `TerminalManager`, read-only identity buffers, process lifecycle,
|
||||
and headless real-PTY acceptance. It intentionally adds no interactive Lua
|
||||
command or frontend rendering.
|
||||
- **Vterm Stage 2 TUI** starts only after Stage 1 merges: terminal-window
|
||||
composition, input/resize, per-context scroll/selection/copy, and the Lua
|
||||
surface.
|
||||
|
|
|
|||
|
|
@ -1,16 +1,19 @@
|
|||
# Vterm — framing (Arc 5 stage 2, three-PR delivery)
|
||||
|
||||
**Revision 3 — 2026-07-21. Status: Stage 1 terminal core implemented and fully
|
||||
gated on `vterm-core`, awaiting review; not merged. Stages 2 and 3 are not
|
||||
implemented.**
|
||||
**Revision 4 — 2026-07-21. Status: Stage 1 review round 1 fixes implemented
|
||||
and fully gated on `vterm-core`; awaiting review follow-up, not merged. Stages
|
||||
2 and 3 are not implemented.**
|
||||
|
||||
Revision 3 records the Stage 1 implementation and downstream consumer reviews.
|
||||
The architecture remains unchanged: `C-c` is the terminal editor escape
|
||||
(`C-c C-c` sends interrupt); main-screen resize reflows while alternate screen
|
||||
clips/pads; exited buffers remain with an Emacs-style process message; protocol
|
||||
v19 is additive with complete frames; shared `Style` stays unchanged; and one
|
||||
`BufferId` owns one shared process/screen whose most recently active frontend
|
||||
controls size.
|
||||
Revision 4 closes the first Stage 1 review: full-screen parsing now implements
|
||||
IND/NEL/RI and terminal children default to `TERM=xterm-256color`; shutdown
|
||||
acceptance probes process liveness portably; resize preserves application tab
|
||||
stops; the line-oriented EOF flush is explicit; and remaining VT-fidelity,
|
||||
performance, and lifecycle nits are recorded below. The architecture remains
|
||||
unchanged: `C-c` is the terminal editor escape (`C-c C-c` sends interrupt);
|
||||
main-screen resize reflows while alternate screen clips/pads; exited buffers
|
||||
remain with an Emacs-style process message; protocol v19 is additive with
|
||||
complete frames; shared `Style` stays unchanged; and one `BufferId` owns one
|
||||
shared process/screen whose most recently active frontend controls size.
|
||||
|
||||
This framing follows the compile-mode terminal substrate that landed in PR
|
||||
#113. `src/process.rs` already owns PTY creation, process groups, bounded
|
||||
|
|
@ -32,11 +35,12 @@ Arc 5 stage 2 ships as three separately reviewed PRs:
|
|||
There is no single mega-PR. Each stage is useful and testable by itself, and a
|
||||
later stage starts only after the preceding stage lands on `main`.
|
||||
|
||||
## 0. Revision 3 — Stage 1 implementation record
|
||||
## 0. Revision 4 — Stage 1 implementation and review record
|
||||
|
||||
The first of the three vterm PRs is implemented on `vterm-core`, fully gated,
|
||||
and awaiting review. Feature commit `bbc1f33` is published as open, non-draft
|
||||
PR #126, <https://github.com/levineuwirth/pmacs/pull/126>, targeting `main`.
|
||||
The first of the three vterm PRs is implemented and fully gated on
|
||||
`vterm-core`, awaiting review follow-up. Initial feature commit `bbc1f33` and
|
||||
review fixes through `bf972a7` are published as open, non-draft PR #126,
|
||||
<https://github.com/levineuwirth/pmacs/pull/126>, targeting `main`.
|
||||
It is deliberately headless: there is no `pmacs.terminal` Lua module,
|
||||
interactive terminal command, TUI paint branch, or GPU/protocol surface yet.
|
||||
|
||||
|
|
@ -110,20 +114,19 @@ All fourteen Stage 1 criteria are implemented:
|
|||
|
||||
### 0.3 Final gates and bite
|
||||
|
||||
The initial gate run found and fixed missing module documentation in the new
|
||||
acceptance crate, then restarted from gate 1. After PR #126 opened, its macOS
|
||||
Lua 5.4 job exposed Darwin's numeric `strsignal` suffix (`"Terminated: 15"`);
|
||||
commit `962944b` normalizes both Darwin and glibc descriptions to the same
|
||||
symbolic signal. The complete sequence restarted from gate 1 again:
|
||||
The initial delivery gate run fixed missing acceptance-crate documentation;
|
||||
PR CI then exposed Darwin's numeric `strsignal` suffix, fixed in `962944b`.
|
||||
Review round 1's first Clippy pass found only identical LF/IND match arms,
|
||||
consolidated in `bf972a7`; the complete sequence restarted from gate 1:
|
||||
|
||||
- `cargo fmt --check`: clean;
|
||||
- `cargo clippy --workspace --all-targets -- -D warnings`: clean;
|
||||
- default library: 1,658 passed, 3 ignored;
|
||||
- CRDT library: 1,834 passed, 3 ignored;
|
||||
- default library: 1,660 passed, 3 ignored;
|
||||
- CRDT library: 1,836 passed, 3 ignored;
|
||||
- Stage 1 acceptance: 8 default + 9 CRDT passed;
|
||||
- M4 acceptance: 114 passed, 3 ignored, 1 `basedpyright` filtered;
|
||||
- required GPU: 109 passed;
|
||||
- workspace: 2,765 passed across 79 suites, 19 ignored, 1 filtered;
|
||||
- workspace: 2,767 passed across 79 suites, 19 ignored, 1 filtered;
|
||||
- `git diff --check`: clean.
|
||||
|
||||
`scripts/bite main src/lib.rs --test vterm_stage1_acceptance` returned
|
||||
|
|
@ -131,6 +134,12 @@ symbolic signal. The complete sequence restarted from gate 1 again:
|
|||
API. This is explicitly the helper's weaker compile-time API bite, not a clean
|
||||
behavioral assertion failure.
|
||||
|
||||
`scripts/bite HEAD^ src/ansi.rs --lib
|
||||
parser_split_points_produce_identical_screen` returned `bite: OK` with a clean
|
||||
behavioral assertion failure: the pre-dispatch parser left the cursor at row
|
||||
zero/column four instead of applying NEL/RI/IND and landing at row one/column
|
||||
zero.
|
||||
|
||||
### 0.4 Downstream review findings (not implemented)
|
||||
|
||||
Stage 2 must derive PTY resize ownership from a durable accepted-input/focus
|
||||
|
|
@ -152,6 +161,32 @@ as large as the legal worst case (review estimate at least 80 MiB), or add a
|
|||
shared aggregate payload bound. It must never silently chunk the locked
|
||||
complete-frame protocol.
|
||||
|
||||
### 0.5 Stage 1 review round 1
|
||||
|
||||
The first external review found no ownership, mutation-guard, parser-cap, or
|
||||
security regressions. This round resolves its three merge-adjacent findings:
|
||||
|
||||
- `ESC D` (IND), `ESC E` (NEL), and `ESC M` (RI) are typed full-screen
|
||||
operations. RI scrolls down only at the top margin; IND/NEL scroll up at the
|
||||
bottom margin, with NEL additionally returning to column zero. The parser's
|
||||
every-byte-split matrix and focused screen-margin test pin the complete path.
|
||||
- Terminal children no longer inherit an arbitrary host `TERM`; absent a
|
||||
caller override, their process environment gets `TERM=xterm-256color`.
|
||||
- The TERM-ignoring shutdown acceptance uses `kill(pid, 0)` through `nix`
|
||||
instead of Linux-only `/proc`, so macOS now exercises the assertion.
|
||||
- Resize retains every surviving application tab stop and installs default
|
||||
stops only in newly added columns.
|
||||
|
||||
`spawn_ansi_parser` intentionally calls `AnsiParser::finish()` on channel
|
||||
disconnect for both profiles. For existing line-oriented compile/REPL
|
||||
consumers, EOF therefore delivers trailing partial text and required synthetic
|
||||
style/alternate-screen balancing that older code dropped. This is an
|
||||
intentional latent-bug fix and an observable compatibility contract.
|
||||
|
||||
The Stage 2 Lua `open` surface must uniquify colliding default buffer names
|
||||
(`*terminal:sh*`, `*terminal:sh*<2>`, and so on) before terminal creation
|
||||
becomes user-visible.
|
||||
|
||||
## 1. Problem and ownership boundary
|
||||
|
||||
Pmacs can supervise a PTY and can parse enough ANSI to turn command output into
|
||||
|
|
@ -774,10 +809,10 @@ Per-stage utilization:
|
|||
|
||||
## 8. Branch and PR plan
|
||||
|
||||
Stage 1 is implemented and fully gated on `vterm-core` at `bbc1f33`, published
|
||||
as open, non-draft PR #126 (<https://github.com/levineuwirth/pmacs/pull/126>),
|
||||
targeting `main` and not merged. Continue the approved plan only after the
|
||||
preceding PR lands:
|
||||
Stage 1 is implemented and fully gated on `vterm-core`; review fixes through
|
||||
`bf972a7` are published in open, non-draft PR #126
|
||||
(<https://github.com/levineuwirth/pmacs/pull/126>), targeting `main` and not
|
||||
merged. Continue the approved plan only after the preceding PR lands:
|
||||
|
||||
1. review PR #126; merge only when the user says;
|
||||
2. after stage 1 merges, create `pmacs-vterm-tui`, branch `vterm-tui`, from the
|
||||
|
|
@ -794,8 +829,9 @@ base-branch deletion/auto-close risk and makes each PR's gate evidence honest.
|
|||
|
||||
### Stage 1 — terminal core
|
||||
|
||||
1. Feed every supported CSI/OSC/DEC sequence at every byte split; whole-feed
|
||||
and split-feed screens are identical.
|
||||
1. Feed every supported CSI/OSC/DEC sequence, including IND/NEL/RI, at every
|
||||
byte split; whole-feed and split-feed screens are identical. RI and
|
||||
forward-index operations additionally pin exact scrolling-margin behavior.
|
||||
2. Split UTF-8, malformed UTF-8, truncated escape, over-cap control string,
|
||||
and unknown private sequences recover without panic, unbounded growth, or
|
||||
visible escape leakage.
|
||||
|
|
@ -811,8 +847,9 @@ base-branch deletion/auto-close risk and makes each PR's gate evidence honest.
|
|||
glyphs across split feeds.
|
||||
7. SGR indexed/truecolor/underline/reverse survives screen operations; ignored
|
||||
attributes leave supported fields unchanged.
|
||||
8. Main-screen resize reflows only soft wraps and preserves cursor/logical-line
|
||||
identity; alternate-screen resize clips/pads without reflow.
|
||||
8. Main-screen resize reflows only soft wraps, preserves cursor/logical-line
|
||||
identity and application tab stops, and adds defaults only in new columns;
|
||||
alternate-screen resize clips/pads without reflow.
|
||||
9. Scrollback obeys both row and cell budgets, evicts oldest rows, and keeps
|
||||
the visible grid exact.
|
||||
10. DA/DSR/CPR query events produce bounded exact response bytes; unsupported
|
||||
|
|
@ -899,6 +936,21 @@ Not part of these three PRs:
|
|||
- kitty keyboard protocol, key release events, media keys, and IME preedit;
|
||||
- cursor-shape/blink rendering and numeric-keypad distinction absent from the
|
||||
current normalized input/cursor protocol;
|
||||
- RIS (`ESC c`), DECALN (`ESC # 8`), and DEC cursor save/restore mode `?1048`;
|
||||
- CUU/CUD region clamping when the cursor starts inside scroll margins while
|
||||
origin mode is disabled;
|
||||
- combining a character into the preceding cell across intervening SGR or
|
||||
cursor-control events;
|
||||
- exact xterm `?1047` clear-on-exit and scroll-margin preservation across
|
||||
alternate-screen switches;
|
||||
- legacy X10 mouse byte encoding when a child enables mouse tracking without
|
||||
SGR mode; Stage 2 sends no report for that unsupported combination;
|
||||
- nonstandard `CSI 3 K` ignore semantics (the current core clears the line);
|
||||
- the ASCII fast path that avoids grapheme-candidate allocation and
|
||||
segmentation for every printable character after another ASCII character;
|
||||
- cleanup of the defensive impossible-state path where a terminal spawn
|
||||
returns a process without a running PID, and borrow-tolerant `EditorState`
|
||||
drop; normal spawn/rollback/prune/shutdown paths remain covered;
|
||||
- shell integration, prompt marks, command semantic zones, and cwd reporting;
|
||||
- ordinary document search over terminal history;
|
||||
- terminal session persistence/reconnect across editor restart;
|
||||
|
|
|
|||
Loading…
Reference in New Issue