Merge pull request #156 from levineuwirth/docs-bottom-panel-landed
docs: record bottom-panel Stage 1 (#155) landing
This commit is contained in:
commit
d152120ff8
|
|
@ -517,153 +517,31 @@ If it does not, stop and repair the remote/fetch configuration.
|
|||
**isolated-config workspace sweep 3,177 across 92 suites, zero failures**;
|
||||
`git diff --check` clean. Gates were run against the committed tree.
|
||||
|
||||
## Bottom-panel lane (window placement + side windows) — Stage 1 IN REVIEW
|
||||
## Bottom-panel lane (Arc 7) — Stage 1 MERGED; Stage 2 (GPU band) is next
|
||||
|
||||
- Portable branch: `githubsucks/bottom-panel`, worktree
|
||||
`../pmacs-bottom-panel`, based on `githubsucks/main` @ `ddaa80d`.
|
||||
- Approved framing: `docs/bottom-panel-framing.md` revision 4, committed
|
||||
as the branch's first commit (`c27f75a`).
|
||||
- **Stage 1 implemented; no wire change (protocol stays v20).** What
|
||||
landed on the branch:
|
||||
- `src/window.rs`: `WindowParams` (`side` / `fixed_rows` / `dedicated`
|
||||
+ implementation-owned `quit_action` and `origin_document`), `Side`,
|
||||
a depth-bounded `QuitAction`, `MIN_WINDOW_OUTER_ROWS = 2`,
|
||||
`Layout::compute(area, fixed)`, the `subtree_min_rows` /
|
||||
`interactive_min_rows` recursions, `boundary_below`, and the three
|
||||
new `FrontendView` fields (`panel_capable`, `frame_geometry`,
|
||||
`panel_hidden`).
|
||||
- `src/editor_core.rs`: `primary_document_window`, the non-side target
|
||||
rule, `display_buffer` + the Q#BP3 placement policy, `quit_window`,
|
||||
`reconcile_panel_layout_core`, `resize_boundary`, per-frontend
|
||||
`JumpEntry`s, and the shared `resolve_target_buffer` seam that the
|
||||
#148 initial-target bootstrap now routes through as well.
|
||||
- `src/editor.rs`: the reconciliation transaction, geometry
|
||||
declaration, the side-window `dispatch_idle_for` gate, the divider
|
||||
paint, and the divider drag.
|
||||
- `src/lua_bindings/window_panel.rs`: the whole `pmacs.window` panel
|
||||
surface plus the shared adopter-placement helpers;
|
||||
`builtin/runtime/window.lua` owns `window.panel-height` /
|
||||
`window.min-height` and the resize commands.
|
||||
- Adopters: `listview.open`, `compile.run`, `pmacs.terminal.open` all
|
||||
take `display = "current" | "panel"` (Stage 1 default `"current"`);
|
||||
LSP/compile visits route through `display_file`.
|
||||
- **Review round 1 addressed.** The load-bearing finding: the Q#BP6
|
||||
side-window split guard (`try_split_active`) had **no production
|
||||
caller** — `pmacs.window.split_horizontal` / `split_vertical`, and so
|
||||
`C-x 2` / `C-x 3`, still went through plain `split_active`. Splitting a
|
||||
focused panel made the root wrapper's final child a split rather than
|
||||
`Leaf(side)`, which both `Layout::compute`'s fixed pass and
|
||||
`document_subtree` key on. It survived the first round because the
|
||||
acceptance test called the core method **directly**; it now goes
|
||||
through the real Lua binding. This is the folding-arc round-2 lesson
|
||||
repeating exactly: *after wiring a guard into a production hook, pin it
|
||||
through the real path — a direct-call test misses the wiring.*
|
||||
Also fixed: the armed divider drag was not scoped to its arming
|
||||
frontend (it could cancel and swallow a peer's mouse events); a
|
||||
recompile carries no `display` and duplicated a panel-placed
|
||||
`*compilation*` into the document window; and
|
||||
`paint_mode_line_graphemes` had lost its doc block to an insertion.
|
||||
Five bite-verified fixes (three via `scripts/bite`, two by manual
|
||||
revert since their tests share `src/daemon.rs` with the production
|
||||
code).
|
||||
- Two Stage-2 hazard pins now exist in `src/daemon.rs`, closing the gap
|
||||
the review named: a fresh attach while `LOCAL` is focused in a panel
|
||||
inherits `LOCAL`'s **document** buffer, and an initial-target bootstrap
|
||||
whose `after-load` hook creates and selects a panel still reasserts
|
||||
into a document window.
|
||||
- **Review round 2 addressed.** The load-bearing finding: **Q#BP7 item 1
|
||||
— "growth reaching the live tail re-arms follow" — was never
|
||||
implemented.** `at_bottom` is the instantaneous geometric readout
|
||||
`scroll_offset == 0`, which a still-anchored view satisfies whenever it
|
||||
is momentarily tall enough to reach the tail, so the round-1 assertion
|
||||
could not see the gap: the next rows the child printed pushed the
|
||||
anchored view back into history. `src/terminal/view.rs` now has
|
||||
`rearm_follow_on_growth`, reached by one shared `declare_view_size`
|
||||
helper from every size-declaring path (`snapshot_for_view`,
|
||||
`record_view_size`, `view_status_for_size`) so grid and semantic
|
||||
declarations cannot disagree.
|
||||
Also fixed: the PTY fixtures emitted LF-only output, which staircases
|
||||
until every row clips to blanks — so the anchor assertions compared
|
||||
`""` with `""` and could not fail (now CRLF, each guarded by
|
||||
`assert!(!top_before.is_empty())`); acc33's contrast case asserted
|
||||
nothing; `start_run` let `already_in_panel` override an **explicit**
|
||||
`display = "current"`, which is the documented opt-out from the Stage 3
|
||||
flip (now gated on omission); and `window_drag` was a daemon-global
|
||||
slot that a peer's mode-line press could clear.
|
||||
- Durable test lessons from this round, both the same class:
|
||||
1. **A geometric readout is not a state predicate.** `at_bottom` says
|
||||
"the viewport currently reaches the tail", not "this view follows
|
||||
the tail". Pinning follow requires feeding MORE output and asserting
|
||||
the view moved (acc32b uses a filesystem gate between two bursts).
|
||||
2. **A PTY in the default mode does not translate LF to CRLF.** An
|
||||
`echo`-driven fixture staircases rightward and clips to blanks past
|
||||
the viewport width, so any text equality over it is vacuously true.
|
||||
Emit `\r\n`, and guard text comparisons with a non-empty assertion
|
||||
the way the daemon pin guards on `!panel_hidden`.
|
||||
- **Round-2 self-review caught a regression the round-2 commit
|
||||
introduced**, in the change it labelled "minor": routing
|
||||
`pmacs.window.buffer()`'s **no-argument** arm through the fid-scoped
|
||||
`selected_window` validator made it **fallible**, and
|
||||
`acting_frontend` can name a frontend with **no registered view** (a
|
||||
bare `dispatch_key` from an unattached peer does exactly that). The
|
||||
runtime calls that function on ordinary edits from `killring`,
|
||||
`syntax`, `autosave`, `pair`, `indent` and `comment` **without
|
||||
`pcall`**, so the raise never surfaced as an error — it silently
|
||||
dropped the operation. `kill_ring_acceptance` went 30/30 → 25/5
|
||||
(`frontend_detached_drops_per_frontend_state`: "B has kill state").
|
||||
The no-arg arm is back on ambient `active_buffer_id()` and documented
|
||||
as deliberately infallible; the explicit-window arm keeps its Q#BP11
|
||||
validation. New **acc19c** pins it through the real path (a
|
||||
`buffer.after-edit` subscriber during a viewless peer's `dispatch_key`)
|
||||
and bites against the regressing commit.
|
||||
Generalizes: **a "uniformity" cleanup that changes a function's
|
||||
fallibility is not minor** — check every caller's error discipline
|
||||
first, and remember that an ambient resolver's fallback IS its
|
||||
contract.
|
||||
- Verification on this branch: `cargo fmt --check` clean; strict
|
||||
workspace Clippy clean; 1,817 default + 1,994 CRDT library tests;
|
||||
`bottom_panel_stage1_acceptance` 46/46; kill ring 30 default + 30 CRDT;
|
||||
vterm Stage 1 9 default + 10 CRDT; M4 121; required GPU 152;
|
||||
compile 67; vterm Stage 2 4 / Stage 3 5 (7 CRDT); folding Stage 2 48;
|
||||
statusline 7; listview 6;
|
||||
**isolated-config workspace sweep 3,130 passed across 89 suites, zero
|
||||
failures**; `git diff --check` clean.
|
||||
- **Run the sweep with an isolated `XDG_CONFIG_HOME`.** The real
|
||||
`~/.config/pmacs/init.lua` on this desktop calls
|
||||
`pmacs.packages.install_local(...)`, so every editor the sweep builds
|
||||
races on one shared install root; a losing race sets a status message
|
||||
that leaks into the mode line and breaks
|
||||
`folding_stage2_acceptance::unfolded_frame_is_identical_to_the_pre_folding_baseline`,
|
||||
which compares whole painted frames. Standalone it is 48/48. This
|
||||
generalizes the known `compile_mode_acceptance` real-config trap:
|
||||
any suite that paints the status area inherits it.
|
||||
- **A latent pre-existing `main` bug surfaced while gating and is NOT
|
||||
this branch's**: `buffer::tests::proptests::rope_matches_crdt_projection_after_arbitrary_edits`
|
||||
fails on `main` @ `352bf0b` with `ops = [Insert(0,"a"),
|
||||
Insert(0,"aaa"), Replace(0,1,"a"), Undo]` — undo of a textually-null
|
||||
`Replace` returns a no-op edit result still carrying `crdt_op =
|
||||
Some`, violating the suite's own shape invariant. `src/buffer.rs` is
|
||||
byte-identical here, and the seed was deliberately **not** committed
|
||||
(it would make an unrelated failure deterministically red on this
|
||||
PR). Needs its own lane.
|
||||
- Durable test lesson from this round: `TerminalViewStatus.scroll_offset`
|
||||
is documented as the retained rows between **this viewport** and the
|
||||
live tail, so it necessarily tracks the viewport height. Asserting it
|
||||
constant across a panel height change is either vacuous or wrong —
|
||||
the invariant Q#BP7 actually states is that the **anchor** is frozen,
|
||||
which the acceptance now pins by comparing the first visible row's
|
||||
text, plus `at_bottom` for the follow re-arm.
|
||||
- `compile_mode_acceptance` needs `--test-threads=1` locally; it is
|
||||
67/67 there. Under default parallelism it fails roughly 1 run in 3,
|
||||
with a *different* test each time (acc14/acc25a, then acc24) —
|
||||
**verified pre-existing** by swapping in `githubsucks/main`'s
|
||||
`builtin/runtime/compile.lua` and reproducing the same rate. The
|
||||
`pmacs-gpu` bin tests have historically gone red under a loaded sweep
|
||||
(wgpu device contention). Rerun isolated before treating either as a
|
||||
regression.
|
||||
- Stage 2 (the GPU panel band, next available protocol version) has its
|
||||
own re-framing obligation before implementation; Stage 3 is the default
|
||||
placement flip.
|
||||
Stage 1 is on `main`; nothing in this arc is in flight. Stage 2 has **no
|
||||
branch and no framing yet** — the approved parent framing
|
||||
`docs/bottom-panel-framing.md` (rev 4) is what it re-scouts against.
|
||||
|
||||
- Stage 1 merged as **#155** (`main` @ `e745068`, 2026-07-24, after two
|
||||
review rounds). No protocol change. Durable substrate facts live in
|
||||
`docs/agent-handoff.md` §1; the two round lessons are in §5.
|
||||
- Retained, carrying nothing unmerged: branch `bottom-panel` and worktree
|
||||
`../pmacs-bottom-panel`.
|
||||
- **Stage 2 obligations, already named by the framing** — the starting
|
||||
point for its own framing doc: `InstanceMessage::PanelFrame` plus
|
||||
`FrontendEvent::{FrontendCellGeometry, PanelResizeRows, PanelPointer}`
|
||||
at the next available protocol version, gated in both directions and
|
||||
each extended enum byte-pinned on its own previous final variant;
|
||||
extracting `paint_frame`'s per-window body *together with* the
|
||||
active-window auto-scroll preparation; routing every consumer in the
|
||||
framing's §1.3 census of 23 transitive active-context reads through
|
||||
`primary_document_window`; the focus-chrome surface matrix (Q#BP14b);
|
||||
and Q#BP17's fold-projection parameter plus the stale invariant comment
|
||||
at `src/window.rs`. Stage 3 is the adopter default flip.
|
||||
- **Folding Stage 3 and this arc's Stage 2 both touch the semantic
|
||||
projection.** Whichever is framed second re-scouts the other's landed
|
||||
state.
|
||||
|
||||
## Folding lane (Arc 6) — Stages 1 and 2 MERGED; Stage 3 (GPU) is next
|
||||
|
||||
|
|
@ -721,6 +599,34 @@ git worktree add --track \
|
|||
|
||||
## Closed since the last snapshot
|
||||
|
||||
- **Bottom panel Stage 1 — MERGED as #155** (`main` @ `e745068`,
|
||||
2026-07-24, after two review rounds). Window placement, window
|
||||
parameters, TUI side windows, the divider, and the adopter `display`
|
||||
opt-in, with no protocol change. Both rounds found the same class of
|
||||
defect and are worth keeping:
|
||||
- **Round 1**: the Q#BP6 side-window split guard had *no production
|
||||
caller* — `C-x 2` still reached plain `split_active` — and survived
|
||||
because the acceptance test called the core method directly.
|
||||
- **Round 2**: Q#BP7's terminal growth re-arm had *never been
|
||||
implemented*, and the assertion meant to pin it (`at_bottom`) is a
|
||||
geometric readout that a still-anchored view satisfies; the anchor
|
||||
assertions beside it compared `""` with `""` because the PTY fixture
|
||||
emitted LF-only output.
|
||||
- **Post-round-2 self-review**, caught by CI going red on all four Test
|
||||
jobs: resolving `pmacs.window.buffer()`'s no-argument arm through the
|
||||
acting frontend made a total function partial, and six runtime modules
|
||||
silently dropped operations (`kill_ring_acceptance` 30/30 → 25/5).
|
||||
Fixed in `9110f9f` before merge.
|
||||
- Gating fact found on the way: **the workspace sweep must run with an
|
||||
isolated `XDG_CONFIG_HOME`**, because the real user `init.lua`
|
||||
installs a local package and the losing race leaks a status message
|
||||
into painted-frame comparisons. There is also a latent pre-existing
|
||||
`main` bug in the buffer CRDT undo path, unrelated to this arc.
|
||||
- `compile_mode_acceptance` is load-sensitive under default
|
||||
parallelism (~1 run in 3, a different test each time); verified
|
||||
pre-existing by swapping in `main`'s `compile.lua`. It is 67/67 at
|
||||
`--test-threads=1`.
|
||||
|
||||
- **GPU initial target — MERGED as #148** (`main` @ `0dd16a5`, 2026-07-24,
|
||||
after two review rounds). `pmacs --gpu [--socket …] FILE` opens a target
|
||||
before the GPU window appears. Protocol bumped 19 → 20: a semantic-session
|
||||
|
|
|
|||
|
|
@ -75,14 +75,77 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
`pmacs.path.canonicalize`. Its branch state, substrate facts, and
|
||||
verification live in `docs/active-work.md`; this section absorbs them
|
||||
when it merges.
|
||||
- **GPU initial target LANDED — #148**
|
||||
(`docs/gpu-initial-target-framing.md` rev 3; merge `0dd16a5`; two review
|
||||
rounds). `pmacs --gpu [--socket NAME|PATH] FILE` transports exact Unix path
|
||||
refresh #150, folding Stage 2 #149, ledger refresh #147, web grammars #146,
|
||||
LaTeX Stage 1 #144 / inline-math framing #145, and folding Stage 1 #142),
|
||||
protocol **v20** (`SUPPORTED=[6..=20]`; v16 = `ThemeFacts`, v17 =
|
||||
- Protocol **v20** (`SUPPORTED=[6..=20]`; v16 = `ThemeFacts`, v17 =
|
||||
`FontFacts`, v18 = `StatuslineSegments`, v19 = terminal frames/events, v20 =
|
||||
the GPU initial-target semantic bootstrap family).
|
||||
- **Bottom panel Stage 1 (window placement + TUI side windows) LANDED —
|
||||
#155** (`docs/bottom-panel-framing.md` rev 4; merge `e745068`; two review
|
||||
rounds). **No protocol change (still v20).** Arc 7's substrate: pmacs now
|
||||
has Emacs's `display-buffer` + window parameters, and a buffer can be
|
||||
displayed in a fixed-height window pinned to the bottom of the frame that
|
||||
feature code targets **by policy** instead of by stealing the selected
|
||||
window.
|
||||
- `src/window.rs`: `WindowParams { side, fixed_rows, dedicated }` plus
|
||||
implementation-owned `quit_action` / `origin_document` (Lua reads them,
|
||||
`set_params` refuses them); `MIN_WINDOW_OUTER_ROWS = 2`;
|
||||
`Layout::compute(area, fixed)` subtracts fixed children before dividing
|
||||
the remainder by weight, preserving last-flexible-takes-the-remainder, so
|
||||
a tree with no fixed leaves computes byte-identically to before.
|
||||
- **`Layout::compute` has TWO production callers**, and both must feed the
|
||||
same shared `panel_fixed_rows` map: `window_placements` and
|
||||
`src/overlay_paint.rs`'s peer-presence pass, which derives its own
|
||||
text-area `Rect` and never routes through the first. Leaving the second
|
||||
on unfixed geometry paints every peer cursor at the row it would occupy
|
||||
with no panel open.
|
||||
- **The minimum is recursive** (`subtree_min_rows`: horizontal splits sum,
|
||||
vertical splits max). "Two rows at the root" does not give each nested
|
||||
leaf two rows. `interactive_min_rows` is the same recursion over the
|
||||
user's `window.min-height` preference, and applies to drag/keyboard
|
||||
resize ONLY — the layout pass and frame-resize reconciliation use the
|
||||
structural floor, so changing a preference can never invalidate an
|
||||
existing layout.
|
||||
- **Hiding a panel is a durable state transition, not a per-frame effect**
|
||||
(`EditorState::reconcile_panel_layout`): it moves focus out and releases
|
||||
the terminal controller, because the terminal resize path merely returns
|
||||
on zero content without releasing. It runs after attach/resize/display/
|
||||
close and defensively before input dispatch, terminal sync, and paint.
|
||||
- `FrontendView` gains `panel_capable`, `frame_geometry`
|
||||
(`None` = **unknown**, never the GPU attach request's permanent 24×80
|
||||
placeholder), and derived `panel_hidden` — each spelled explicitly at
|
||||
every construction site, preserving folding's non-`Default` discipline.
|
||||
- `EditorCore::primary_document_window` is the Q#BP14 projection seam;
|
||||
`display_buffer` is Phase 1 of the display transaction (exact target →
|
||||
side affinity → ordinary reuse, with option-valued height/dedication);
|
||||
the Lua layer owns Phase 2 (activate → hook → reconcile → revalidate →
|
||||
final-focus matrix).
|
||||
- **Optimistic input is gated per WINDOW, not per buffer**:
|
||||
`dispatch_idle_for` returns `false` whenever the acting frontend's active
|
||||
window is a side window. Marking the panel's BUFFER round-trip would be
|
||||
wrong — `round_trip_buffers` is global by `BufferId`, so it would disable
|
||||
optimistic apply for another frontend editing that buffer as its document.
|
||||
- Jump entries are per frontend and carry their origin `WindowId`; a stale
|
||||
**side** origin is SKIPPED, because degrading it to an active-window
|
||||
switch is exactly the duplicate-panel corruption the arc removes.
|
||||
- `pmacs.window.display / display_file / quit / panel / params /
|
||||
set_params / resize / display_target`, plus `builtin/runtime/window.lua`
|
||||
(`window.panel-height`, `window.min-height`, `C-x ^` / `C-x C-^`).
|
||||
Adopters take `display = "current" | "panel"`; **Stage 1 default is
|
||||
`"current"`** and Stage 3 flips it.
|
||||
- The divider is the upper subtree's existing mode-line row — no row added
|
||||
or consumed, `ui.divider` restyles every exposed segment of one boundary,
|
||||
and drag state is `HashMap<FrontendId, _>` so frontends cannot steal each
|
||||
other's gestures.
|
||||
- `open_initial_target` now shares one `resolve_target_buffer` +
|
||||
exact-window install seam with `display_file`, and reasserts into a
|
||||
document window after hooks (a startup hook can now create a panel).
|
||||
- Final gates: 1,817 default + 1,994 CRDT library tests; the new
|
||||
`bottom_panel_stage1_acceptance` 46; kill ring 30; compile 67; M4 121;
|
||||
required GPU 152; initial-target 14 CRDT; all three vterm suites; folding
|
||||
Stage 2 48. All 12 CI checks green at merge.
|
||||
- **Stage 2 (the GPU panel band) needs its own re-framing** before
|
||||
implementation and takes the next available protocol version; the
|
||||
framing's §1.3 census of 23 transitive active-context reads is its map.
|
||||
Stage 3 is the adopter default flip.
|
||||
- **GPU initial target LANDED — #148**
|
||||
(`docs/gpu-initial-target-framing.md` rev 3; merge `0dd16a5`; two review
|
||||
rounds). `pmacs --gpu [--socket NAME|PATH] FILE` transports exact Unix path
|
||||
|
|
@ -580,8 +643,14 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
(GPU) is next**, unframed.
|
||||
- **Web grammars HTML+CSS LANDED — #146**, and **LaTeX Stage 1 — #144**
|
||||
with its inline-math parent framing **#145**.
|
||||
- Remaining ranked arcs: 6 folding Stage 3, 7 DAP, 8 GPU splits, plus
|
||||
the `.ipynb` arc (its JSON-grammar prerequisite shipped in #123).
|
||||
- **Arc 7 (bottom panel) Stage 1 LANDED — #155** — window placement,
|
||||
window parameters, TUI side windows, the divider, and the adopter
|
||||
`display` opt-in. **Stage 2 (the GPU band) is next and needs its own
|
||||
re-framing**; Stage 3 is the default flip. DAP was parked awaiting
|
||||
exactly this arc's Stage 1 and can now re-baseline its touch census.
|
||||
- Remaining ranked arcs: 6 folding Stage 3, 7 bottom-panel Stages 2–3,
|
||||
DAP, 8 GPU splits, plus the `.ipynb` arc (its JSON-grammar
|
||||
prerequisite shipped in #123).
|
||||
|
||||
## 2. How we work (the part that must not drift)
|
||||
|
||||
|
|
@ -848,6 +917,44 @@ final variant — its own round-trip cannot detect a discriminant shift.
|
|||
before any `FrontendEvent` touches render/size/editor state. Generalizes:
|
||||
when a new failure path can leave a handle installed without its owning
|
||||
session, dropping a handle is not the same as tearing down the connection.
|
||||
- **A guard with no production caller passes every direct-call test.**
|
||||
#155 round 1: `EditorCore::try_split_active` implemented the side-window
|
||||
split refusal, but `pmacs.window.split_horizontal` / `split_vertical` — and
|
||||
therefore `C-x 2` / `C-x 3` — still called plain `split_active`. The
|
||||
acceptance test called the core method directly, so reverting the guard
|
||||
entirely would have left every test green. Same shape as folding #142
|
||||
round 2. Assert through the outermost user-reachable seam
|
||||
(`try_exec(&s, "pmacs.window.split_horizontal()")`), then falsify by
|
||||
revert. When the test shares a file with the code it pins, `scripts/bite`
|
||||
cannot swap it — break the production line by hand and `git checkout --`.
|
||||
- **A geometric readout is not a state predicate.**
|
||||
`TerminalViewStatus::at_bottom` is defined as `scroll_offset == 0` — "the
|
||||
viewport currently reaches the tail", not "this view follows the tail". A
|
||||
still-anchored view satisfies it whenever it happens to be tall enough, so
|
||||
asserting it could not detect that Q#BP7's growth re-arm had never been
|
||||
implemented (#155 round 2): the next rows the child printed pushed the
|
||||
anchored view back into history. Pinning *following* requires advancing the
|
||||
world — feed more child output through a filesystem gate — and asserting the
|
||||
view came along. Related: `scroll_offset` is viewport-relative, so
|
||||
"unchanged across a height change" is vacuous or wrong; the invariant is
|
||||
the frozen ANCHOR.
|
||||
- **A PTY in the default mode does not translate LF to CRLF.** An
|
||||
`echo`-driven test fixture staircases rightward, and past the viewport
|
||||
width every row clips to blanks — so `assert_eq!(top_before, top_after)`
|
||||
compares `"" == ""` and passes for any regression (#155 round 2). Emit
|
||||
`printf '...\r\n'`, and guard text comparisons with
|
||||
`assert!(!observed.is_empty())` the same way the panel daemon pin guards on
|
||||
`!panel_hidden`.
|
||||
- **Widening an ambient resolver into a scoped one can make a total function
|
||||
partial.** #155 round 2 resolved both arms of `pmacs.window.buffer()`
|
||||
through the acting frontend "for uniformity". `acting_frontend` follows the
|
||||
interactive origin, which can name a frontend with no registered view (a
|
||||
bare `dispatch_key` from an unattached peer), so the no-argument arm began
|
||||
raising instead of answering. No runtime caller `pcall`s it, so killring,
|
||||
syntax, autosave, pair, indent and comment silently dropped operations —
|
||||
`kill_ring_acceptance` went 30/30 to 25/5 on every CI platform. The ambient
|
||||
resolver's fallback is what makes it *total*; keep it, and document that as
|
||||
deliberate. Uniformity is not free when the paths have different totality.
|
||||
- **An upgrade decision must be tracked independently of the outcome that
|
||||
triggered it.** #148 published a target's fresh `BufferSnapshot` to
|
||||
existing grid replicas only when the buffer was `newly_loaded ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue