Commit Graph

630 Commits

Author SHA1 Message Date
Levi Neuwirth 907e4d87fc docs: record current-main integration
Point the active-work recovery ledger at the published merge of folding Stage 2
and the GPU initial-target second-review fixes.
2026-07-24 10:22:20 -04:00
Levi Neuwirth 6c06815ee4 Merge githubsucks/main into gpu-initial-target
Integrate folding Stage 2 and its landed-state documentation with the
protocol-v20 GPU initial-target branch. Preserve per-session fold projection
selection in the target bootstrap transaction and retain v19 compatibility
coverage after the later protocol bump.
2026-07-24 10:21:37 -04:00
Levi Neuwirth b3ed40cf60 docs: record published second-review fixes
Point the active-work ledger at the failure-containment and dedup-publication
checkpoint while leaving PR #148 open for user review.
2026-07-24 10:11:24 -04:00
Levi Neuwirth be8c67c30c fix(daemon): contain failed target sessions
Shut down bootstrap sockets on every dispatcher-side failure and reject
frontend events whose session state was never installed. This prevents a
lingering failed client from reaching absent render/size state.

Track target-side CRDT upgrades independently from load/create status so a
deduplicated hidden buffer is published to every existing grid replica. Add
real-daemon regressions for both failure containment and replica publication.
2026-07-24 10:10:31 -04:00
Levi Neuwirth b168dcad16
Merge pull request #150 from levineuwirth/docs-folding-stage2-landed
docs: record folding Stage 2 (#149) landing; open the Stage 3 lane
2026-07-24 14:00:23 +00:00
Levi Neuwirth 7fc7420b91 docs: record folding Stage 2 (#149) landing; open the Stage 3 lane
Post-merge housekeeping owed from #149, kept as its own docs-only PR per
the #138-#140 / #147 convention. No runtime code.

- active-work.md: base snapshot and the recovery check bump 47581f4 ->
  6ed4fe9. The Stage 2 lane is retired and replaced by a folding lane that
  records both stages as merged with nothing in flight, and states Stage 3
  (GPU) has no branch and no framing yet — carrying its named obligations
  (GPU collapse at TUI parity, caret/hit-test fold-awareness, the
  BufferSnapshot fold-mirror clear, CRDT-origin unfold, and flipping
  FrontendView.fold_projection true for semantic frontends) as that
  framing's starting point. "Closed since the last snapshot" gains #149
  and #147.
- agent-handoff.md §1: main @ 6ed4fe9, the "Last updated" line and section
  date, the Stage 2 bullet flipped from IMPLEMENTED/PR-OPEN to LANDED with
  the Stage 3 obligations attached, and the roadmap entry (remaining arcs
  now read "6 folding Stage 3").

Both stages' design points are recorded as traps Stage 3 inherits rather
than as history: the merged-hidden-component unit, per-window/per-target
map instances, per-frontend projection, position-not-row normalization,
and the post-intercept edit site.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-24 09:58:10 -04:00
Levi Neuwirth 6ed4fe99b7
Merge pull request #149 from levineuwirth/folding-tui
feat(fold): Stage 2 — grid (daemon-rendered) collapse
2026-07-24 13:43:10 +00:00
Levi Neuwirth 0a479ae8d0
Merge pull request #147 from levineuwirth/docs-folding-stage1-landed
docs: record folding Stage 1 (#142) landing; open Stage 2 lane
2026-07-24 13:41:18 +00:00
Levi Neuwirth f16d72fded docs: refresh the ledger to current main and Stage 2's real state
PR #149 review round 5 flagged this PR as stale: it still claimed `main`
@ `c49a8c7`, Stage 2 framing "rev 2, under review; no implementation, no
PR", while `main` is `47581f4` and Stage 2 is implemented and open.

- Base snapshot and the recovery check bump `c49a8c7` -> `47581f4`.
- The folding Stage 2 lane becomes IMPLEMENTED / PR #149 OPEN: framing
  rev 4 approved, the `VisibleLineMap` spine, the base-moved merge (and
  why it was merged rather than rebased), and the five review rounds'
  design-changing findings — each of which is a trap Stage 3 inherits.
- `main`'s ledger had gone unrefreshed through four merges, not one, so
  "Closed since the last snapshot" now also records web grammars HTML +
  CSS (#146) and LaTeX Stage 1 (#144) with its inline-math framing
  (#145), including their durable lessons.
- agent-handoff §1: `main` @ `47581f4`, the "Last updated" line, the
  Stage 2 substrate bullet, and the roadmap entry.

Rebased onto `47581f4` so it stays one documentation-only commit
directly off canonical main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 21:58:02 -04:00
Levi Neuwirth 5f7270d26a docs: record folding Stage 1 (#142) landing; open Stage 2 lane
Post-merge housekeeping owed from #142, kept as its own docs PR (no
runtime code).

- agent-handoff.md §1: bump main to c49a8c7, add the folding Stage 1
  substrate bullet (store/View, structural source, C-c @ surface,
  command-path unfold, FoldState production; no protocol bump), refresh
  the "Last updated" line and the roadmap Arc 6 entry, and note Stage 2
  is in framing on folding-tui (the visible-line-map reframe).
- active-work.md: retire the Stage 1 folding lane (PR #142 was OPEN),
  add a "Closed since the last snapshot" entry for #142, open the
  Stage 2 (grid/daemon collapse) framing lane on folding-tui, and
  refresh the canonical base snapshot to c49a8c7.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 21:58:02 -04:00
Levi Neuwirth b750000d06 fix(fold): key the managed Lua widening on the EFFECTIVE edit site
PR #149 review round 5, finding 1 — correct, and both round-4 bugs did
survive through the intercept path.

Round 4 moved the widening off the point and onto `edit_start_of(&op)`,
but ran it in `run_buffer_edit` BEFORE `run_managed_edit`. A managed
buffer intercept may legally rewrite `pos` / `start` / `end`
(`LuaInterceptView::intercept_edit`), so the requested op is not where
the edit lands:

  - requested outside -> intercept relocates inside: the edit stayed
    hidden;
  - requested inside -> intercept relocates outside: an unrelated fold
    opened.

The seam still covers BOTH paths — hooking only `run_managed_edit` would
let an interactive `bypass_intercept` edit escape, which is why the
framing put it on the common entry — but each path now keys on its own
effective site:

  - `run_bypass_edit` applies its op verbatim, so `run_buffer_edit`
    hooks it there;
  - `run_managed_edit` hooks after the intercept chain settles and
    before the apply, on the op the chain returned. A chain that raises
    applies nothing, so it unfolds nothing.

The registry borrow is released at that point, and the helper reads only
`SharedCore` + the fold registry, so no borrow conflicts with phase 3.

Three new tests, all through real `M-x` with a real
`pmacs.buffer.add_intercept`: relocate-into-a-fold must unfold,
relocate-out-of-a-fold must not, and a rejected chain must not. Each
asserts the buffer text first, so the test fails loudly if the intercept
stops relocating rather than silently passing.

Suite 45 -> 48.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 21:45:33 -04:00
Levi Neuwirth 65e500eba1 docs: record published GPU review fixes
Point the active-work recovery ledger at the verified review-fix checkpoint
and record that PR #148 remains open for user review.
2026-07-23 21:27:04 -04:00
Levi Neuwirth bef1c08133 fix(gpu): preserve session isolation during target publish
Keep foreign BufferSnapshot publications out of existing semantic GPU
sessions while retaining grid-replica coherence. Treat dead peer writes as
peer-local failures, restore active-frontend cleanup, deterministic probe
readiness, GPU logging, shared tilde expansion, and accurate docs.

Add focused publication and cleanup coverage and record the two-window
Wayland/Vulkan smoke plus the complete post-review gate results.
2026-07-23 21:25:33 -04:00
Levi Neuwirth 90bb86d355 fix(fold): address PR #149 review round 4
All four findings were correct.

F1 (major) — the Lua widening keyed on the POINT, not the edit site.
Q#FD19 condition (iii) is `edit.range.start`; `run_buffer_edit` discarded
`op` and opened whatever fold contained `window.cursor`. Two wrong
behaviors followed: a command inserting elsewhere opened an unrelated
fold at the point, and — worse — a command editing INTO a fold from an
outside point left its edit hidden. `run_buffer_edit` now reads
`edit_start_of(&op)` before `op` is consumed and passes it down. The
`apply_active_edit` funnel stays point-keyed, which is correct and
deliberate: the six primitives, yank, and query-replace all place point
at the edit site first, and only the Lua path can diverge — now said so
in the doc comment.

The acceptance test encoded the wrong behavior (inserted at byte 0,
expected the cursor's fold to open). Replaced by two tests that pin both
directions, plus the framing's named **comment-toggle** case driven
through the real `M-;` on a file-backed Rust buffer rather than a
synthetic mutator.

F2 (major) — hidden-cursor motion normalized only the row. `move_up` /
`move_down` clamped `coord.row` but derived `goal` from the hidden
line's raw column, and returned early at a buffer boundary without
normalizing at all, so `Up` inside a fold headed on line 0 left the
logical cursor hidden. Added `normalize_cursor_to_visible`, which
projects the whole POSITION through `visible_position` as a real
mutation before any step is computed (and drops the sticky goal column,
since the jump is discontinuous). Paging shares it — the same latent
bug. The old test used equal-width lines and asserted only the line, so
it could not tell the two apart; the new fixture is deliberately ragged
and asserts the resulting BYTE in both directions, plus the boundary
case.

F3 (moderate) — `set_view_top` bypassed the fold clamp. Q#FD12/Q#FD18
say `view_top` is always set through `clamp_view_top`, naming the
`set_view_top` contract specifically. Rendering repaired it at the next
frame, but until then `view_top()` handed out a hidden line and
command/event reckoning could start from a non-visible origin. The
clamp now lives in the setter — the contract's home, what `saveplace`
and `pmacs.editor.set_view_top` call. New test reads `view_top()`
directly after the setter, before any paint.

F4 (moderate) — the suite claimed items 1–14 but omitted approved
clauses. Added: peer SELECTION endpoint projection with hidden interiors
dropped; the crossing-fold repeat for the peer cursor AND a peer
selection endpoint; a style/syntax span straddling a fold (alignment on
the shifted row); the completion popup anchored below a fold; and peer
presence in the split-buffer case using the RECIPIENT window's map.

Suite: 35 -> 45 tests. Eight new bite cases, each falsifying exactly the
line that implements its claim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 20:46:47 -04:00
Levi Neuwirth 97a27e9873 Merge branch 'main' into folding-tui
`main` moved from c49a8c7 (folding Stage 1, #142) to 47581f4 (web
grammars, #146) while Stage 2 was in framing and implementation. The
text merge is clean, but it is NOT semantically clean: #146 added three
new `Viewport { .. }` literals to `src/highlight.rs`'s unit tests, and
Stage 2 gives `Viewport` a `folds` field. Merged alone, `cargo test
--lib` fails to compile — so the carry-over is resolved here rather
than left for CI to discover.

Merged (not rebased) so the four framing revisions the review rounds
cite by SHA (59410c0, e221f13, 8160d66, 4222ffa) stay reachable.

Full gate suite re-run on the merged tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 19:43:13 -04:00
Levi Neuwirth e6ace5c320 fix(fold): choose the projection in the crdt-gated daemon fixtures
`cargo test --lib --features crdt` compiles two `#[cfg(feature =
"crdt")]` daemon tests that call `build_fresh_frontend_view`. Both model
a semantic session, so they pass `false` — the Q#FD21 value a
`semantic_render` attach gets until Stage 3. Bet B8 in the framing is
exactly this: the projection is chosen explicitly at every construction
site, never inferred, so a new call site cannot silently default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 19:37:18 -04:00
Levi Neuwirth b3e18150cc test(fold): make the inactive-buffer unfold guard actually bite
Bite-verification found the Q#FD19 active-window-buffer requirement's
test vacuous: `other` held no fold, so removing the guard changed
nothing — `unfold_containing` on a store-less buffer is a no-op either
way. The guard's real job is to stop the invoking frontend's POINT from
naming a place in a buffer it is not looking at, so the fixture now
gives `other` a fold whose range contains the active window's cursor
byte. Reverting the guard now opens it (0 != 1).

Verified: with `if window.buffer_id != id { return; }` replaced by a
no-op, the test fails on a clean assertion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 19:33:35 -04:00
Levi Neuwirth 313b1ff77a feat(fold): Stage 2 — grid (daemon-rendered) collapse
Implements docs/folding-stage2-framing.md rev 4. The daemon grid
renderer now consults the fold store: hidden lines are omitted, rows
below shift up, and every consumer that assumed
`display_row = source_line - view_top` routes through one shared
projection. No wire schema change and no protocol bump (Bet B6) — the
collapse is entirely daemon-side; the GPU path is Stage 3.

The spine (Q#FD12) is `src/fold_view.rs`: a `VisibleLineMap` derived
from `FoldRegistry::folds` plus a window's line offsets and never
stored. Its unit is a merged **hidden component** — overlapping OR
adjacent hidden intervals unioned, each keeping the one visible
`head_line` and that line's exact `head_position`. Adjacent intervals
merge because the later fold's head is itself hidden, which is what
makes nesting, shared heads, and crossing overlap all resolve to a
head that can actually render (round-3 F2).

Instances are short-lived and built **per rendered window** and **per
command/event operation**, never once per frame: `paint_frame` renders
several windows that may show different buffers, so a singleton would
leak one pane's folds into another (round-2 F2). The render instance
rides on a lifetime-bearing `Viewport<'a>` as `Option<&'a
VisibleLineMap>` — a shared ref is `Copy`, so `Viewport` stays `Copy`
(Bet B7).

Rendering:
- `TextView::render` walks visible lines; the head line gets a
  trailing content-area ellipsis (Q#FD13).
- The gutter walks visible lines too: Absolute keeps the raw `line+1`,
  Relative/Hybrid measure VISIBLE distance anchored on the cursor's
  visible head (Q#FD14). The fold glyph takes the col-0 sign cell only
  when a gutter exists — line numbers default to Off, so with no gutter
  the ellipsis is the sole marker (Q#FD20, round-1 F3). A diagnostic
  clamped onto the head wins that cell by paint order.
- A diagnostic on a hidden line clamps its SIGN to the outermost
  visible head (most-severe merge); the squiggle needs a real row, so
  only the sign clamps (Q#FD15).
- Caret, local selection endpoints, and peer cursors project via
  `visible_position_of` — the head row AND the head's end-of-content
  column, never an arbitrary column (round-2 F3). Peer presence derives
  the RECIPIENT window's map.
- Style/search/completion overlays route through
  `Viewport::row_offset_of`; the mode-line indicator reckons in
  visible-line space.

Command/event time is scoped per frontend (Q#FD21): a
`fold_projection` flag on `FrontendView`, set at attach from the
negotiated `semantic_render` bit (grid ⇒ true, semantic ⇒ false until
Stage 3, LOCAL ⇒ true) and never inferred from a `FrontendId` (Bet
B8). Without it, shared `EditorCore` motion would make a simultaneous
unfolded GPU session's cursor skip lines it still displays. The map's
two axes stay separate (round-3 F1): the acting frontend supplies the
policy, the operation's TARGET window supplies the buffer — a wheel
event names a pane without activating it.

Motion (Q#FD17, ruled: include), paging, wheel, the click inverse, and
the auto-scroll clamp all step by visible lines under that gate;
motion from a hidden logical cursor normalizes to the visible head
first. `view_top` stays a source-line index (Bet B5), set only via
`clamp_view_top` so it never rests hidden.

Unfold widening (Q#FD19): the pre-edit unfold moves to the top of
`apply_active_edit` — one funnel that subsumes the six primitives'
calls and covers yank + query-replace, both of which place point at
the edit site first. Interactive Lua mutators hook the common
`run_buffer_edit`, above the managed/bypass split, gated on
`InteractiveCommandOrigin` AND the edit targeting that frontend's
active-window buffer. The remote/optimistic-CRDT path stays excluded
(Stage 3); undo/redo unfold stays deferred.

Acceptance: `tests/folding_stage2_acceptance.rs`, 35 tests asserting
on the real `paint_frame` cell grid, covering framing items 1–14
including crossing folds, a nested deeply-hidden cursor, a split of
two different buffers with an inactive-pane wheel, and simultaneous
grid+semantic motion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 19:24:07 -04:00
Levi Neuwirth 4f1651c8f0 Record GPU initial target PR
Update the active-work recovery ledger with PR #148 and the published
pre-PR checkpoint.
2026-07-23 19:17:11 -04:00
Levi Neuwirth 010a4b52eb Record portable GPU target checkpoint
Pin the published implementation branch and leave PR creation as the next
recoverable action.
2026-07-23 19:15:05 -04:00
Levi Neuwirth 19674a47ea Record integrated GPU target verification
Update the framing, durable handoff, and active-work ledger after integrating
current canonical main and completing the required gates and real GPU smoke.
2026-07-23 19:13:34 -04:00
Levi Neuwirth d6d4be6cfb Merge remote-tracking branch 'githubsucks/main' into gpu-initial-target 2026-07-23 19:03:41 -04:00
Levi Neuwirth 2dd30ec730 Implement session-scoped GPU initial targets
Add protocol-v20 semantic bootstrap and readiness result framing so
`pmacs --gpu FILE` opens the requested path before the GPU window becomes
ready. Keep target identity scoped to the authenticated frontend, preserve
legacy/no-target attach behavior, and publish fresh buffers coherently to
existing replicas.

Carry Unix path bytes and launcher cwd through the root broker, resolve paths
lexically in the daemon, reuse or create buffers without ambient-view state,
and preserve the managed daemon lifecycle from #141. Add focused parser,
wire, lifecycle, hook, isolation, and real-connector acceptance coverage.
2026-07-23 19:03:25 -04:00
Levi Neuwirth 4222ffae6e docs(folding): Stage 2 framing rev 4 — address review round 3
Route command-time visible-line maps through each operation's target
window, while retaining the acting frontend as the projection-policy
owner. Model nested and crossing folds as merged hidden components so
row and byte clamps always resolve to one actually visible head.

Also key projection on the negotiated render selection and correct the
unmerged status of the separate Stage 1 housekeeping PR.
2026-07-23 17:25:55 -04:00
Levi Neuwirth 8160d660a0 docs(folding): Stage 2 framing rev 3 — address review round 2
Round 2's three findings + two nits, all verified against c49a8c7:

- F1 (major): fold-aware motion must be frontend-projection scoped. Shared
  EditorCore::move_up/down/page_* would make a simultaneous unfolded GPU
  session skip source lines it still displays (a grid + a semantic session
  can attach to one buffer, daemon.rs:876). Add a per-FrontendView
  `fold_projection_active` flag (editor_core.rs:240, set at attach / cleared
  at detach); gate ALL command-time visible-line reckoning (motion, paging,
  wheel, click, auto-scroll) on it. Render-time clamps are already
  grid-path-only. New Q#FD21 + simultaneous TUI+semantic acceptance.
- F2 (major): render maps must be per WINDOW, not per frame — paint_frame
  and the presence pass iterate windows with distinct buffer_ids
  (editor.rs:2922, overlay_paint.rs:124). Specify one map per rendered
  nonterminal window (keyed on window buffer_id + TextView); peer presence
  uses the recipient window's map. New split-of-different-buffers acceptance.
- F3 (moderate): hidden positions need COLUMN projection, not only row
  clamping. Add `visible_position_of(pos)` -> outermost fold's range.start
  (end of visible head line, Stage 1's point-move target) for local/peer
  carets and selection endpoints; hidden interiors still drop. New
  hidden-cursor-column-differs acceptance.
- Nits: fix the Viewport<'a> typo; state build cost honestly as O(folds)
  with a byte->line lookup per fold (B4).

PR #147 (the #142 housekeeping) confirmed clean by the reviewer, no findings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 16:55:25 -04:00
Levi Neuwirth 47581f4034
Merge pull request #146 from levineuwirth/web-grammars
feat(web): HTML + CSS grammars + HTML script/style injections
2026-07-23 20:23:33 +00:00
Levi Neuwirth 515c76f5ab docs+test(web): name and pin the @attribute retro-paint (review round 3)
Review found that adding ("attribute", fg(3)) for HTML/CSS also colours the
@attribute capture three already-bundled grammars emit — rust (attribute_item),
lua (<const>), yaml (directives) — which were previously unpainted. Verified on
a Rust buffer: #[derive(Debug)] now paints uniformly yellow (fg 3), an
improvement over unpainted and the distinct-attribute convention most editors
follow.

Name this retro-paint as intended in the framing (Q#WEB4, rev 4) and pin it with
rust_attribute_repaints_via_shared_attribute_capture so it is a chosen effect,
not incidental. @tag is unaffected (HTML/CSS only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:11:47 -04:00
Levi Neuwirth e221f131f0 docs(folding): Stage 2 framing rev 2 — address review round 1
Round 1's five findings + two rulings, all verified against c49a8c7:

- F1 (major): nested folds. `head_of`(innermost) could clamp onto a
  still-hidden inner head. Replace with `visible_head_of` (outermost
  visible head); `view_top` clamps BACKWARD to the head, not forward
  past the fold; relative numbers anchor on the clamped visible cursor.
- F2 (major): the consumer census was incomplete. Add the full §2.2
  table — local selection (editor.rs:3241), peer presence
  (overlay_paint.rs:159, after paint_frame), mode-line indicator
  (editor.rs:3803), style/search/completion overlays — and make TUI
  peer-presence fold behavior explicit scope.
- F3 (major): line numbers default Off => gutter_w==0 => no sign cell.
  Make the fold glyph conditional: off => ellipsis only; on => sign
  cell with diagnostic priority. Dedicated column (unconditional) named
  as a deferred layout change.
- F4 (major): a frame-pinned map can't serve command-time motion, and
  Viewport is Copy. Reframe as one derivation primitive with per-phase
  short-lived instances (render via Option<&VisibleLineMap> on a
  lifetime-bearing Viewport, preserving Copy; after-frame direct;
  command-time fresh); home usable from EditorCore.
- F5 (moderate): key the Lua-path widening on InteractiveCommandOrigin
  (editor.rs:53), hook the common run_buffer_edit (not only
  run_managed_edit) so bypass_intercept edits don't escape, require the
  target to be the invoking frontend's active-window buffer, and
  explicitly DEFER undo/redo unfold.

Rulings: Q#FD17 include (normalize a hidden cursor to the visible head
before stepping); #142 housekeeping stays a separate docs PR.

Acceptance expanded to pin nested-fold/shared-cursor, local selection,
peer presence, an ordinary overlay across a fold, completion anchoring,
the scroll indicator, and both gutter-off/gutter-on fold-marker cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 16:08:22 -04:00
Levi Neuwirth 79f43b1b61 Merge remote-tracking branch 'githubsucks/main' into gpu-initial-target
# Conflicts:
#	docs/active-work.md
2026-07-23 16:01:58 -04:00
Levi Neuwirth 59410c004d docs(folding): frame Stage 2 — grid (daemon) collapse (rev 1)
Reframe Arc 6 folding Stage 2 in detail off canonical main @ c49a8c7
(Stage 1 / #142 merged), per the parent framing's §8/§14. Continues the
Q#FD scheme from Q#FD12.

Stage 2 makes the daemon grid renderer fold-aware: collapse hidden lines,
head-line ellipsis + gutter fold glyph, fold-aware line numbers
(visible-line relative distance), diagnostic-sign clamp-to-head, caret
clamp, visible-line viewport/scroll accounting, and the interactive-Lua
unfold widening (yank/query-replace/comment). No wire schema or protocol
change — FoldState production (Stage 1) is untouched; the GPU path is
Stage 3.

Scout findings that shaped the framing:
- The TUI has NO non-identity source-line->display-row map today; the
  identity `view_top + row` is baked into ~7 sites. Folding is the first
  such map, so Stage 2's spine is one shared per-frame visible-line map
  (Q#FD12) that the render loop and every view_top-arithmetic site
  consult; collapse lives in TextView::render, not the diff shell.
- Correcting the parent's premise: yank + query-replace are
  apply_active_edit callers (local), not Lua-mutator callers; only
  comment-toggle/yank-pop take the Lua path (shared with the
  remote/optimistic-CRDT apply that stays deferred to Stage 3). The
  widening hooks the local funnels only (Q#FD19).

One open scope fork flagged for the user: Q#FD17 (fold-aware vertical
line-motion vs render-time caret clamp only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 15:41:11 -04:00
Levi Neuwirth 244de001cb Record reviewed GPU initial-target framing
Advance the active lane to Revision 2 and record closure of all four
non-structural framing findings. Keep implementation gated on explicit user
approval.
2026-07-23 15:09:05 -04:00
Levi Neuwirth 71039d1699 Refine GPU initial-target framing after review
Pin launcher-owned tilde expansion, require same-buffer dedup hooks, fail
closed when hooks kill the target, and document stderr feedback during the
pre-window bootstrap wait. Record the observed protocol-version echo and
non-Unicode argv panic.
2026-07-23 15:07:06 -04:00
Levi Neuwirth 394d39942c feat(web): bundle HTML + CSS grammars + HTML injections
Register `html` (.html/.htm/.xhtml) and `css` (.css) entries in
BUILTIN_LANGUAGES, backed by the official tree-sitter-html 0.23 and
tree-sitter-css 0.25 grammars over the tree-sitter-language shim (ABI-fine, no
overlay — both export their query constants). The single `extensions` field
wires detection ahead of the LSP filetype map.

HTML's crate-exported INJECTIONS_QUERY lights up <script> -> javascript
(already registered) and <style> -> css (registered here) via the #122
injection engine — the north-star injection consumer.

The only capture reconciliation (Q#WEB4): the two web captures both grammars'
queries use that pmacs did not recognize — ("tag", fg(5)) and
("attribute", fg(3)) — added to highlight.rs's table; @tag.error prefix-walks
to tag, and everything else already maps.

Tests: table guards; load-and-parse smokes (roots document/stylesheet);
highlights-resolve (node-name compat gate, asserts @tag present); extension
resolution; a tag+attribute paint test (the attribute assertion is
load-bearing); and the injection payoff — an HTML buffer with embedded
<style>/<script> paints a CSS property and a JS keyword INSIDE the injected
regions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:04:10 -04:00
Levi Neuwirth c49a8c71be
Merge pull request #142 from levineuwirth/folding
Arc 6 folding — Stage 1: instance fold engine
2026-07-23 18:50:02 +00:00
Levi Neuwirth 05eab9e4e5 docs(web): frame HTML + CSS grammars + HTML injections (approved rev 3)
Add tree-sitter HTML and CSS grammars for .html/.htm/.xhtml and .css
highlighting, and light up HTML's <script>->javascript / <style>->css
injections (the north-star injection consumer). Both crates export their query
constants over the tree-sitter-language shim (no overlay, ABI-fine). The only
reconciliation is two new capture entries (tag, attribute) in highlight.rs.
Framing approved through three review rounds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 14:47:41 -04:00
Levi Neuwirth ec0e40117b Record GPU initial-target framing lane
Advance the volatile ledger to the current canonical base and record the
portable Revision 1 framing checkpoint, scope, recovery command, and approval
boundary.
2026-07-23 14:32:44 -04:00
Levi Neuwirth 60ac7fab46 Frame session-scoped GPU initial targets
Define the pmacs --gpu FILE contract, protocol-v20 semantic bootstrap,
raw Unix path and launcher-cwd transport, pre-window readiness barrier,
replica coherence requirements, and behavioral acceptance matrix.
2026-07-23 14:31:24 -04:00
Levi Neuwirth 036a994639 test(fold): address PR #142 review round 2 — pin the round-1 wiring
Round 2 correctly found the Finding-2/3 fixes were unpinned (reverting
them left the suite green). Both are now bite-verified:

- **Kill-path purge (Finding 2).** Replaced the direct
  `forget_buffer(id)` unit test with
  `killing_a_buffer_through_the_real_path_purges_its_fold_store`, which
  drives `pmacs.buffer.remove` — the production route through
  `after_buffer_removed` — and asserts the store is gone via the dead id
  (BufferIds never recycle). Mirrors config_registry's real-kill-path
  test. Bite-verified: reverting the `after_buffer_removed` fold branch
  turns it red.
- **close-all point move (Finding 3).** Added
  `close_all_command_moves_point_to_enclosing_head`, which invokes the
  `fold.close-all` command with the point inside the second of two
  top-level fns and asserts the cursor landed on that fn's head-line
  content end (and both folds exist). Bite-verified: reverting close_all's
  `maybe_move_point` loop turns it red.
- Ledger: `docs/active-work.md` folding lane now records PR #142 OPEN +
  the two landed review rounds (was "opens once the gate suite is green").

Correction to the round-1 gate report: the acceptance suite is **21**
tests (round 1 was 20, not 24 — a tally slip), green under default and
`--features crdt`. Full gate suite otherwise green (fmt, clippy
--workspace --all-targets, git diff --check).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 14:25:28 -04:00
Levi Neuwirth 4daa1b856b
Merge pull request #145 from levineuwirth/docs-inline-math-framing
docs(inline-math): commit the parent inline-math framing
2026-07-23 18:07:08 +00:00
Levi Neuwirth 5c70975fa3 docs(inline-math): commit the parent inline-math framing
The parent-arc framing was authored on the desktop but never tracked, so
references to it — from the merged latex-grammar lane framing and its Cargo.toml
comment (#144) — dangled on a fresh clone. Commit it as its own docs change and
drop the now-stale "untracked, desktop-only" caveat from the lane framing.

Frames the full four-tier inline-math renderer (detection -> parse -> layout ->
GPU render). Stage 1 (LaTeX grammar) shipped as #144; the math parser (Tier 2),
layout (Tier 3), GPU render (Tier 4), and (math_environment) @math injection are
deferred, tracked in docs/latex-grammar-math-substrate-framing.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 14:06:26 -04:00
Levi Neuwirth ab29656671
Merge pull request #143 from levineuwirth/docs-gpu-invocation-landed
Record one-command GPU invocation landing
2026-07-23 18:02:17 +00:00
Levi Neuwirth f09b0a1142
Merge pull request #144 from levineuwirth/latex-grammar
feat(latex): Stage 1 — LaTeX/TeX grammar highlighting (inline-math substrate)
2026-07-23 17:54:04 +00:00
Levi Neuwirth 9691dd4e9f fix(fold): address PR #142 review round 1
- **Finding 1 (bug):** a delete starting exactly at a fold's `end`
  removed the `\n` that `end` names — the last hidden line's terminator —
  but the strictly-after arm (`os >= e`) kept the fold, leaving a mid-line
  end. `translate`'s after-arm is now `os > e || (os == e && old_len == 0)`
  so a pure insert at `e` still stays outside while a delete at `e` falls
  to the drop arm, symmetric with the head side. New unit test
  `delete_starting_at_tail_boundary_drops_fold` (bite-verified).
- **Finding 2:** `pmacs.buffer.kill` didn't clean the fold registry.
  Added `FoldRegistry::forget_buffer(id)` (id-keyed; the view died with the
  buffer) and wired it into `after_buffer_removed`, mirroring the
  keymap/config cleanup; the registry is now stashed as Lua app-data.
  `forget(&mut Buffer)` is clarified as the revert/reload reset.
- **Finding 3:** `fold.close-all` now moves the invoking point to the head
  when it closes a fold around it (Q#FD3); the data-API `fold` exemption
  (programmatic, no invoking point) is named in the module doc.
- Nits: dropped the dead `!(both empty)` conjunct in `fold_state_msg`;
  replaced the trivial fresh-registry assert; added coverage for the
  stale-tree refuse via a fold command, the read-only-buffer rejection
  (Q#FD11), and unfold normalizing an arbitrary range.

Gates green: fmt, clippy --workspace --all-targets, --lib (1786),
--features crdt (1962), folding_acceptance (24), m4 (skip basedpyright),
required-GPU, git diff --check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 13:42:20 -04:00
Levi Neuwirth d9669746c1 Record one-command GPU invocation landing
Advance the durable snapshot to merge 63fbc66, record the green CI rerun, and
remove the completed GPU invocation lane from the volatile active-work ledger.
2026-07-23 13:33:09 -04:00
Levi Neuwirth 63fbc66943
Merge pull request #141 from levineuwirth/gpu-invocation
Add one-command managed GPU invocation
2026-07-23 17:29:31 +00:00
Levi Neuwirth 96e5647d5a docs(latex): de-dangle parent-arc references (review round 1)
The Cargo.toml comment and the lane framing both cited docs/inline-math-framing.md,
which is an untracked, desktop-only doc — the path dangles on a fresh clone.
Point the Cargo.toml comment at the committed lane framing instead, and note the
parent's untracked status in the framing header (committing it as its own docs
PR, or listing it in the handoff's machine-local inventory, remains a tracked
follow-up).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 13:16:29 -04:00
Levi Neuwirth 1d66089a8e test(latex): add paint half of acceptance 3 (review round 1)
The shipped latex_highlights_resolve covered only the compile / capture-name
gate; the approved framing's acceptance 3 also requires parsing a document and
asserting painted output (the grid_paints_injected_child_keyword template).
tree-sitter compiles a pattern that uses a valid field on the wrong node and
then silently never matches, which the compile gate cannot catch — a real risk
given this grammar cut's structural drift from what the nvim query targets.

latex_grid_paints_section_and_command parses `\section{Intro}` + `\foo{bar}` and
asserts the \foo command_name paints @function (non-default) and the section
title text paints @keyword.control (bold), proving the reconciled query actually
matches, not merely compiles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 13:16:29 -04:00
Levi Neuwirth 78339352d4 Record second GPU invocation review closure
Advance the framing to Revision 6 and record the strengthened non-CRDT,
Ctrl-C, strict-operand, probe-throttling, and PID-cleanup contracts. Update the
durable and volatile checkpoints to implementation commit 154cb9f.
2026-07-23 12:40:03 -04:00
Levi Neuwirth 154cb9f08d Close remaining GPU invocation review nits
Throttle the managed probe after its event channel closes, reject option-like
path operands, and document the connector test seam. Strengthen non-CRDT and
Ctrl-C acceptance so socket side effects and a pre-signal surviving frontend
are exercised, while avoiding cleanup signals to already-reaped daemon PIDs.
2026-07-23 12:38:11 -04:00
Levi Neuwirth 3b411dbb2a feat(fold): Arc 6 Stage 1 — instance fold engine (headless)
The fold engine behind `docs/folding-framing.md` (approved rev 5): a
per-buffer fold store, a structural tree-sitter fold source, the
state-aware Lua command + data-API surface with the Emacs hideshow
`C-c @` bindings, the dispatch-layer pre-edit unfold, and `FoldState`
production. No rendering — Stages 2 (grid) and 3 (GPU) consume the store.

- `src/fold.rs`: `FoldStore` (a buffer-attached `View` that translates
  ranges on every edit and drops any whose head/tail the edit crosses,
  provenance-blind — Q#FD6), the structural source (nearest block-like
  node >= 2 source lines -> introducer<->body -> **derived head line**,
  the line immediately above the first hidden line, so wrapped signatures
  and `where` clauses stay visible per R3-1 -> **closer-aware tail**, a
  closing-delimiter line stays visible per R2-5), injection-layer walk,
  `(start, end]` containment, and the state-aware ops (close innermost
  open / open outermost closed / org-TAB cycle). Stale/absent tree
  refuses (Q#FD10).
- `src/lua_bindings/fold.rs`: `pmacs.fold.*` — explicit-buffer data API
  (`fold`/`unfold`/`folds`/`toggle`) + interactive helpers, validation
  (Q#FD11: document buffer, UTF-8 boundaries, >= 1 hidden line — Q#FD9
  falls out of the last clause), point-moves-to-head (Q#FD3).
- `builtin/runtime/fold.lua`: `fold.toggle/close/open/close-all/open-all`
  commands + the `C-c @` prefix set (Q#FD4).
- `src/editor_core.rs`: the six point-anchored edit primitives run the
  pre-edit unfold keyed on the authenticated source's point (Q#FD5,
  command path); `EditorCore` owns the shared `FoldRegistry`.
- `src/semantic_render.rs`: the `FoldState` producer —
  authoritative-empty, diff-suppressed, baseline resets on
  `BufferSnapshot` (Q#FD8); the "never emitted" pin split so
  `BlockAdornments` stays unproduced.
- `tests/folding_acceptance.rs` (16) over real Rust/Python/markdown
  grammars + `fold_state_producer_transitions` + 15 engine unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q5BkezMppbpCgGAYk2ftxV
2026-07-23 12:14:00 -04:00