From 486ce167480ba8ad34c2757cc3b76d33cc2e8e9e Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Mon, 27 Jul 2026 22:53:36 -0400 Subject: [PATCH 1/9] test(journey): ratchet directory GPU bootstrap success Replace the stale directory-negative in the GPU initial-target suite with an explicit snapshot-first readiness path, while retaining all genuinely malformed and unloadable failure cases. Record the portable side-quest and bottom-panel dependency state. --- docs/active-work.md | 158 ++++++++++++++--------------- tests/gpu_invocation_acceptance.rs | 22 +++- 2 files changed, 98 insertions(+), 82 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 83c3a51..f785bfb 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -1,6 +1,6 @@ # Active work — cross-machine resume ledger -**Snapshot: 2026-07-26.** This file records volatile work that has not +**Snapshot: 2026-07-27.** This file records volatile work that has not landed on `main`. Read it after `docs/agent-handoff.md`. Remove completed entries when their PR merges; do not let this become a second permanent backlog. @@ -27,19 +27,12 @@ landed regardless of what a lane says. machine-local: `origin` may name this canonical URL, a release mirror, or something else, and therefore has no authority by name alone. - Canonical base at this snapshot: - `githubsucks/main` @ `42025e4` (Lean 4 Stage 4b #181, atop the dired - Stage 1 landed docs #169 and the PTY-terminate diagnostic #176, - terminal copy mode #178, the GPU-terminal-input landed docs #168, Lean - 4 Stage 4a #179, bottom-panel Stage 2A #177, the bottom-panel Stage 2 - framing #175, terminal configuration Stage 1 #173, Lean 4 Stage 3b - #170, Stage 3a #167, the CRDT undo repro #157, the inline-math - landed-doc refresh #172, the bottom-panel landed-doc refresh #156, the - inline-math slice #158, dired Stage 1 #165, the GPU terminal input fix - #166, Lean 4 Stage 2 #161, the dired framing #164, COHERENCE.md #163, - find-file #162, Lean 4 Stage 1 #160, and the minimap blank-slab fix - #159; protocol v20). The previous snapshot named `74301d1`, and **the - recovery floor advances with it**: the check below now requires - `42025e4` or newer, so a tree at `74301d1` no longer passes. That is + `githubsucks/main` @ `c2d56ff` (Journey Stage 1a #182, which + incorporated terminal configuration + copy mode #180, atop Lean 4 + Stage 4b #181 and the previously recorded landed work; protocol v20). + The previous snapshot named `42025e4`, and **the recovery floor + advances with it**: the check below now requires `c2d56ff` or newer, + so a tree at `42025e4` no longer passes. That is deliberate — the floor moves with the base, because a check that accepts an older commit than the declared base passes on a tree the rest of this file does not describe. @@ -78,7 +71,7 @@ git worktree list git status --short --branch ``` -The `git log` command must expose `42025e4` — the base named above — or a +The `git log` command must expose `c2d56ff` — the base named above — or a newer intentional main. Keep this threshold and the canonical-base line in step: a recovery check that accepts an older commit than the base it declares canonical will pass on a tree the rest of this file does not @@ -178,50 +171,29 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey Stage 1a — PR #182 OPEN, review round 1 closed +## Journey/GPU directory-target ratchet — IN GATING, no PR -- Framing `docs/journey-stage1a-framing.md` **rev 8** (four review - rounds, two correction revisions found during implementation, one from - review round 1 of PR #182). - Branch `journey-stage1a-directory-open`, based on `githubsucks/main` - @ `42025e4` (rebased onto `74301d1`, then integrated `42025e4` and the - landed-docs work below by merge — the branch is under review, so its - history is no longer rewritten). -- Recovery: `git fetch githubsucks && git checkout - journey-stage1a-directory-open`. Everything below is committed and - pushed; nothing depends on a worktree or `/tmp`. -- **Ships:** the directory arm on `resolve_target_buffer`, - `EditorState::open` rewritten as a caller of it (the unification), the - `path.open-directory` chain + `pmacs.path.directory_handler` fallback - slot, `pmacs.window.commit_to` with its scoped frontend and preflight, - the nonconstructible destination userdata, the daemon bootstrap arm, - and `tests/journey_acceptance.rs` (**24 pins** as of rev 8 — a count, - not a constant; re-read it rather than quoting this line). No protocol - change — still v20. -- **Doc updates ride the PR** per COHERENCE §25: §2 grade + step-3 - verdict row, §20 Priority 1 + the arc list, the GPU initial-target - framing's Q#GT6 / acceptance 10 supersession, handoff §1. -- **Bite results** (each mutation run against the full suite): scope - stops swapping `core.active_frontend` → N6a + P3 fail, nothing else; - preflight moved after the callback → P1 + P2 fail, nothing else; drop - the `ScopedFrontend` arm from `acting_frontend` → N4b fails, nothing - else. That last mutation is why N4b exists — it left N4 green. - Round 1 of PR #182 added two more: dired's `display` back to - `switch_buffer`, and `prev` read from the ambient window → each fails - **N4c** alone. **The scope pins the frontend, not the window** — every - routing pin before N4c varied frontend identity and none varied the - selected window within one frontend, so 23 green pins missed it. -- Ordering: PR #177 MERGED (2026-07-26), so 1a was unblocked. 1a lands - before dired Stage 2. When 1a lands, Stage 2 must re-scout and revise - its framing around the scoped `pmacs.window.commit_to` boundary before - its implementation branch is cut. That revision is a prerequisite, not - a review-time discovery. -- **Named deferrals carried out of this stage:** dired's *interactive* - paths (`C-x d`, tree descent, refresh) still rely on the ambient - frontend a tick later and are not migrated onto captured destinations; - the stale startup scratch buffer is still not removed (only the false - doc comment is corrected); `resolve_target_buffer`'s directory arm has - no picker, only the chain that leaves room for one. +- **Approved correction, not new product behavior.** GPU initial-target + framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make + a directory target a success; `COHERENCE.md` §2 treats that path as a + protected journey. The stale GPU integration test still listed `"."` + among malformed/unloadable targets after #182 landed. +- Branch `journey-gpu-directory-ratchet`, based directly on canonical + `main` @ `c2d56ff`. Recovery: `git fetch githubsucks && git checkout + journey-gpu-directory-ratchet`. Everything described here is + committed and pushed; nothing depends on the `/tmp` worktree. +- **Scope is one acceptance ratchet:** remove `"."` from the four + genuinely invalid cases and add a transport-level positive which + requires snapshot-first + `InitialTargetResult::Opened` for `"."`, + then proves the same daemon can open a following file target. No + production source, protocol, framing decision, or coherence grade + changes. +- Touched suite is **15/15 CRDT** after building its documented + `pmacs-gpu` prerequisite. Full standing gates are pending. Initial + fresh-worktree attempts without that binary and without out-of-sandbox + Unix-socket permission were setup failures, not product evidence. +- This side quest lands before bottom-panel 2B-1 opens its PR. After it + merges, 2B-1 integrates the new `main` and reruns its full matrix. ## The CRDT half of the test corpus is dark in CI — NEEDS A LANE @@ -358,10 +330,43 @@ If it does not, stop and repair the remote/fetch configuration. never been enforced. Any CI job that compiles the `crdt` targets has to fix them first or it will be red on arrival. -## Bottom-panel lane (Arc 7) — Stages 1, 2A + framing MERGED; 2B is next +## Bottom-panel lane (Arc 7) — 2B-1 GATED; waiting on ratchet side quest -Stage 1, the Stage 2 framing, and Stage 2A are all on `main`. **Stage 2B -has not started.** +Stage 1, the Stage 2 framing, and Stage 2A are on `main`. Framing +revision 5's three-way split of 2B was explicitly approved on +2026-07-27. **Stage 2B-1 is implemented, integrated with canonical +`main`, and pushed at `b9123c2`; no PR is open.** Its own omissions found +by gating are corrected. The Journey/GPU ratchet lane above is its sole +remaining dependency. + +- **Stage 2B-1 branch:** `bottom-panel-stage2b`, based on + `githubsucks/main` @ `c2d56ff` by merge because review had begun. + Recovery: `git fetch githubsucks && git checkout + bottom-panel-stage2b`. Everything is committed and pushed; nothing + depends on a worktree or `/tmp`. +- **Ships only the v21 wire layer:** the four wire shapes, version bump, + shared cell-grid validator, and version-ladder move. It has no + producer, consumer, or capability change; `panel_capable` stays + `false`, so this slice changes no user-visible journey grade. +- **Review round 1 closed:** two P1s and one P2, all corrected at + `9b364ad`: `PanelFrame` now identifies its buffer, the transport + ratchet covers the actual attach path rather than a detached codec + assertion, and shared grid bounds have one validator. +- **The full gate found and corrected two further 2B-1 omissions at + `b9123c2`:** the statusline version ladder still pinned v20/rejected + v21, and Vterm Stage 3 pinned v20 both structurally and in its real + headless probe. Those ratchets now expect v21 and, where applicable, + reject v22. +- **Green evidence except for the main-side stale ratchet this side + quest owns:** formatting and strict Clippy; default/CRDT libraries; + every bottom-panel, folding, GPU-font, statusline, semantic, Vterm, + M4, and required-GPU gate; and the isolated-config full-workspace + sweep. The exact counts and the classified M8 timing rerun live at + `b9123c2`. +- **Next ordering is fixed:** 2B-2 branches from `main` only after 2B-1 + lands; 2B-3 branches only after 2B-2 lands. The daemon epoch machine + belongs to 2B-2; the GPU band and negotiated capability flip belong + to 2B-3. - **Stage 2A MERGED as #177** (`main` @ `0a3fcd1`, 2026-07-26, all twelve checks green at `8424172`, three review rounds). Branch @@ -374,19 +379,7 @@ has not started.** `primary_document_window` returns `view.active` in every existing configuration, so this is seam adoption that becomes load-bearing in 2B. -- **Stage 2B is approved and unstarted.** It branches from `main`, **not - stacked on 2A**, per the framing §9. Scope: protocol v21, the daemon - panel projection, the GPU band, and the negotiated `panel_capable` - flip. `docs/bottom-panel-stage2-framing.md` §7.2 carries its five - acceptance criteria (A2B-1..5) plus the reassertion of parent - criterion 52, and §8 records **no open items**, so 2B needs no further - framing round. Its sharpest trap is §5.3's three-boundary split: the - GPU `text_area_bottom` is `status_band_top`, - `geometry_capacity_bottom` and `document_text_bottom` at once, and a - blanket rewrite moves the status chrome along with the document while - still satisfying an "everything moved" assertion — hence A2B-4's - contrast form. -- Verification on the merge result: `cargo fmt --check` clean; strict +- **Stage 2A verification on its merge result:** `cargo fmt --check` clean; strict workspace Clippy clean; **1,832 default + 2,015 CRDT** library tests; `bottom_panel_stage2a_acceptance` **17**; bottom-panel Stage 1 46; statusline segments 8 CRDT; m11_5 semantic 2 CRDT; GPU initial target @@ -442,26 +435,29 @@ has not started.** `docs/agent-handoff.md` §1; the two round lessons are in §5. - Landed-docs follow-up merged as **#156** (`main` @ `d152120`, 2026-07-25). -- **Stage 2 framing: `docs/bottom-panel-stage2-framing.md` revision 4**, +- **Stage 2 framing: `docs/bottom-panel-stage2-framing.md` revision 5**, on branch `githubsucks/bottom-panel-stage2-framing` (three commits, - one per revision), worktree `../pmacs-bp-stage2`, based on + one per pre-implementation revision), worktree `../pmacs-bp-stage2`, based on `githubsucks/main` @ `ccf29e3`. Round 1 closed 2 blocking + 3 high; round 2 closed 1 blocking + 2 high + 1 medium and decided both open items; round 3 closed 1 blocking + 1 high + 1 medium. No open items - remain. The approved + remain. Revision 5 adds no decision; it records the approved + 2B-1/2B-2/2B-3 implementation split. The parent framing `docs/bottom-panel-framing.md` (rev 4) remains authoritative, **including its acceptance criteria 37–55**. - Retained, carrying nothing unmerged: branch `bottom-panel` and worktree `../pmacs-bottom-panel`. -- **Stage 2 ships as two serial slices**, 2A landing before 2B branches: +- **Stage 2 ships as four serial implementation slices**, each landing + before the next branches: **2A** = classified §1.3 census routing + `paint_frame` per-window painter extraction (with the active-window auto-scroll preparation), no - protocol change; **2B** = protocol **v21** + protocol change; **2B-1** = protocol **v21** (`InstanceMessage::PanelFrame` plus `FrontendEvent::{FrontendCellGeometry, PanelResizeRows, PanelPointer}`, gated both directions, each extended enum byte-pinned on its own - previous final variant), daemon panel projection, the GPU band, and the - negotiated `panel_capable` flip. Stage 3 is the adopter default flip. + previous final variant); **2B-2** = daemon panel projection and epoch + machine; **2B-3** = the GPU band and negotiated `panel_capable` flip. + Stage 3 is the adopter default flip. - **Correction — this entry previously mis-stated the census contract.** It is **not** "route every consumer through `primary_document_window`". Q#BP14 classifies the 23 reads into four classes and routes only the diff --git a/tests/gpu_invocation_acceptance.rs b/tests/gpu_invocation_acceptance.rs index 5371438..91203de 100644 --- a/tests/gpu_invocation_acceptance.rs +++ b/tests/gpu_invocation_acceptance.rs @@ -662,6 +662,27 @@ mod crdt { assert!(probe.close().success()); } + #[test] + fn directory_target_reaches_ready_and_leaves_the_daemon_usable() { + let temp = secure_tempdir(); + let socket = temp.path().join("directory-target.sock"); + let mut daemon = spawn_daemon(&socket, &[]); + + // Journey Stage 1a superseded the old IsADirectory failure: + // `attach_target` requires the production snapshot-first sequence + // followed by `InitialTargetResult::Opened`. + let directory = attach_target(&socket, temp.path(), Path::new(".")); + + fs::write(temp.path().join("still-alive.txt"), "alive\n").expect("write survivor"); + let survivor = attach_target(&socket, temp.path(), Path::new("still-alive.txt")); + assert_eq!(survivor.replica.materialize_string(), "alive\n"); + + drop(directory); + drop(survivor); + signal_pid(daemon.id(), Signal::SIGTERM); + assert!(wait_for_exit(&mut daemon, Duration::from_secs(5)).success()); + } + #[test] fn malformed_or_unloadable_targets_fail_closed_without_poisoning_the_daemon() { let temp = secure_tempdir(); @@ -673,7 +694,6 @@ mod crdt { (cwd.clone(), Vec::new()), (cwd.clone(), b"bad\0name".to_vec()), (cwd.clone(), vec![b'x'; 32 * 1024 + 1]), - (cwd.clone(), b".".to_vec()), ]; for (index, (bad_cwd, bad_path)) in invalid.into_iter().enumerate() { let (frontend_id, mut stream, messages) = open_raw_target(&socket, bad_cwd, bad_path); From a5107ca32db2e406d3022769011c8fe04fe4d63e Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Mon, 27 Jul 2026 23:15:10 -0400 Subject: [PATCH 2/9] docs(active-work): record directory ratchet gates Capture the complete green gate matrix and retain the diagnosed setup and transient full-sweep failures so the lane remains recoverable and the evidence is not flattened into an unexplained rerun. --- docs/active-work.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index f785bfb..03cb487 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -171,7 +171,7 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey/GPU directory-target ratchet — IN GATING, no PR +## Journey/GPU directory-target ratchet — GATED, PR PENDING - **Approved correction, not new product behavior.** GPU initial-target framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make @@ -188,10 +188,29 @@ If it does not, stop and repair the remote/fetch configuration. then proves the same daemon can open a following file target. No production source, protocol, framing decision, or coherence grade changes. -- Touched suite is **15/15 CRDT** after building its documented - `pmacs-gpu` prerequisite. Full standing gates are pending. Initial - fresh-worktree attempts without that binary and without out-of-sandbox +- **Full gate matrix is green at `486ce16`:** + - `cargo fmt --check`; + - strict workspace clippy; + - library **1,849 passed / 3 ignored**; + - CRDT library **2,034 passed / 4 ignored**; + - touched GPU initial-target suite **15/15**; + - connected Journey/Dired/find-file/theme/bottom-panel acceptance + suites **125/125**; + - M4 **121 passed / 3 ignored / 1 filtered**; + - required GPU package **202/202**; + - `git diff --check`; + - isolated-config, one-invocation full workspace sweep green on its + final run. +- **Gate diagnostics retained:** initial fresh-worktree attempts without + the documented `pmacs-gpu` prerequisite and without out-of-sandbox Unix-socket permission were setup failures, not product evidence. + The first full-workspace attempt then exhausted the `/tmp` filesystem + quota while linking. Moving only the disposable Cargo target to disk + let the sweep run; its first completed pass exposed one transient + `pmacs-gpu` font-facts unit-test red after the standalone GPU gate had + passed. The exact test passed immediately against the identical build, + and the required complete one-invocation rerun was green, including + GPU **202/202**. - This side quest lands before bottom-panel 2B-1 opens its PR. After it merges, 2B-1 integrates the new `main` and reruns its full matrix. From c2b855e252d7bf2f81288a76a89525eca49b89d8 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Mon, 27 Jul 2026 23:19:05 -0400 Subject: [PATCH 3/9] docs(active-work): record directory ratchet PR Attach the gated Journey/GPU side-quest lane to PR #183 and make its intentional open, unmerged review state explicit. --- docs/active-work.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/active-work.md b/docs/active-work.md index 03cb487..735bc9c 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -171,7 +171,7 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey/GPU directory-target ratchet — GATED, PR PENDING +## Journey/GPU directory-target ratchet — PR #183 OPEN, GATED - **Approved correction, not new product behavior.** GPU initial-target framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make @@ -182,6 +182,9 @@ If it does not, stop and repair the remote/fetch configuration. `main` @ `c2d56ff`. Recovery: `git fetch githubsucks && git checkout journey-gpu-directory-ratchet`. Everything described here is committed and pushed; nothing depends on the `/tmp` worktree. +- PR #183: + . It is intentionally + open and unmerged pending user review. - **Scope is one acceptance ratchet:** remove `"."` from the four genuinely invalid cases and add a transport-level positive which requires snapshot-first + `InitialTargetResult::Opened` for `"."`, From ec4191fd8efe965b4c70472951290ff447f08ec2 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Tue, 28 Jul 2026 09:48:48 -0400 Subject: [PATCH 4/9] test(journey): pin post-quiescence GPU dired surface Consume the directory session's later replacement snapshot and assert the canonical dired header plus a known listing entry before checking daemon reuse. Correct the bottom-panel revision-5 recovery branch and advance the durable handoff to the Journey Stage 1a main anchor. --- docs/active-work.md | 32 ++++++++++++------ docs/agent-handoff.md | 13 ++++--- tests/gpu_invocation_acceptance.rs | 54 ++++++++++++++++++++++++++++-- 3 files changed, 83 insertions(+), 16 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 735bc9c..676de4f 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -1,6 +1,6 @@ # Active work — cross-machine resume ledger -**Snapshot: 2026-07-27.** This file records volatile work that has not +**Snapshot: 2026-07-28.** This file records volatile work that has not landed on `main`. Read it after `docs/agent-handoff.md`. Remove completed entries when their PR merges; do not let this become a second permanent backlog. @@ -171,7 +171,7 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey/GPU directory-target ratchet — PR #183 OPEN, GATED +## Journey/GPU directory-target ratchet — PR #183 REGATING REVIEW ROUND 1 - **Approved correction, not new product behavior.** GPU initial-target framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make @@ -188,10 +188,20 @@ If it does not, stop and repair the remote/fetch configuration. - **Scope is one acceptance ratchet:** remove `"."` from the four genuinely invalid cases and add a transport-level positive which requires snapshot-first + `InitialTargetResult::Opened` for `"."`, - then proves the same daemon can open a following file target. No - production source, protocol, framing decision, or coherence grade - changes. -- **Full gate matrix is green at `486ce16`:** + then consumes the post-quiescence replacement snapshot and requires + dired's canonical header plus a known directory entry before proving + the same daemon can open a following file target. No production + source, protocol, framing decision, or coherence grade changes. +- **Review round 1: three findings, all real and corrected.** The + first test stopped at the deliberately pre-existing bootstrap + document, so it did not pin the resolver's later dired commit. The + Stage 2 rev-5 recovery bullet named rev 4's framing branch. And the + durable handoff still named pre-Journey `main` even though this ledger + had advanced. The first is now a post-quiescence transport assertion; + the latter two are corrected in this revision. The touched suite is + green **15/15**; the full gate matrix is being rerun before this round + closes. +- **Pre-review full gate matrix was green at `486ce16`:** - `cargo fmt --check`; - strict workspace clippy; - library **1,849 passed / 3 ignored**; @@ -457,10 +467,12 @@ remaining dependency. `docs/agent-handoff.md` §1; the two round lessons are in §5. - Landed-docs follow-up merged as **#156** (`main` @ `d152120`, 2026-07-25). -- **Stage 2 framing: `docs/bottom-panel-stage2-framing.md` revision 5**, - on branch `githubsucks/bottom-panel-stage2-framing` (three commits, - one per pre-implementation revision), worktree `../pmacs-bp-stage2`, based on - `githubsucks/main` @ `ccf29e3`. Round 1 closed 2 blocking + 3 high; +- **Stage 2 framing: `docs/bottom-panel-stage2-framing.md` revision 5** + is commit `56301ed` on branch `githubsucks/bottom-panel-stage2b`, + worktree `../pmacs-bp-stage2b`. Revisions 1–4 remain on + `githubsucks/bottom-panel-stage2-framing` (head `4fbd47f`, four + framing commits, revision 4 at `49757e5`). Round 1 closed 2 blocking + + 3 high; round 2 closed 1 blocking + 2 high + 1 medium and decided both open items; round 3 closed 1 blocking + 1 high + 1 medium. No open items remain. Revision 5 adds no decision; it records the approved diff --git a/docs/agent-handoff.md b/docs/agent-handoff.md index 6607df6..47f7dce 100644 --- a/docs/agent-handoff.md +++ b/docs/agent-handoff.md @@ -1,6 +1,9 @@ # Agent handoff — cross-machine continuity -**Last updated: 2026-07-26, after terminal copy mode (#178) — `C-c C-t` +**Last updated: 2026-07-28, after Journey Stage 1a (#182), which made +directory startup one coherent local/daemon/GPU path and incorporated +the terminal configuration + copy mode landed-doc work (#180); following +terminal copy mode (#178) — `C-c C-t` materializes a terminal's whole retained range into an ordinary buffer, plus `Buffer::set_generated_contents`, the first genuinely immutable generated-buffer write path — and its landed-doc pair (#168); following @@ -39,10 +42,12 @@ reads it the way you just did. For volatile branches, checkpoints, verification, and recovery commands, read `docs/active-work.md` immediately after this file. -## 1. Where the project stands (2026-07-26) +## 1. Where the project stands (2026-07-28) -- `main` @ `42025e4` (Lean 4 Stage 4b #181, atop the dired Stage 1 - landed docs #169 and the PTY-terminate diagnostic #176, terminal copy +- `main` @ `c2d56ff` (Journey Stage 1a #182, incorporating terminal + configuration + copy mode landed docs #180, atop Lean 4 Stage 4b #181, + the dired Stage 1 landed docs #169 and the PTY-terminate diagnostic + #176, terminal copy mode #178, the GPU-terminal-input landed docs #168, Lean 4 Stage 4a #179, bottom-panel Stage 2A #177, the bottom-panel Stage 2 framing #175, terminal configuration diff --git a/tests/gpu_invocation_acceptance.rs b/tests/gpu_invocation_acceptance.rs index 91203de..13dc020 100644 --- a/tests/gpu_invocation_acceptance.rs +++ b/tests/gpu_invocation_acceptance.rs @@ -223,6 +223,34 @@ mod crdt { stream: UnixStream, } + impl TargetSession { + fn wait_for_replacement_snapshot(&mut self) -> (pmacs::buffer::BufferId, String) { + let deadline = Instant::now() + Duration::from_secs(10); + loop { + assert!( + Instant::now() < deadline, + "target frontend did not receive a replacement buffer snapshot" + ); + match read_message::(&mut self.stream) + .expect("read target frontend after bootstrap") + { + InstanceMessage::BufferSnapshot { + buffer_id, + crdt_snapshot, + } if buffer_id != self.buffer_id => { + let replica = + CrdtState::new(self.frontend_id.0).expect("replacement buffer replica"); + replica + .import_snapshot(&crdt_snapshot) + .expect("import replacement buffer snapshot"); + return (buffer_id, replica.materialize_string()); + } + _ => {} + } + } + } + } + fn attach_target(socket: &Path, cwd: &Path, path: &Path) -> TargetSession { use std::os::unix::ffi::OsStrExt; @@ -666,12 +694,34 @@ mod crdt { fn directory_target_reaches_ready_and_leaves_the_daemon_usable() { let temp = secure_tempdir(); let socket = temp.path().join("directory-target.sock"); + let listed_name = "listed-before-bootstrap.txt"; + fs::write(temp.path().join(listed_name), "listed\n").expect("write listed file"); let mut daemon = spawn_daemon(&socket, &[]); // Journey Stage 1a superseded the old IsADirectory failure: // `attach_target` requires the production snapshot-first sequence - // followed by `InitialTargetResult::Opened`. - let directory = attach_target(&socket, temp.path(), Path::new(".")); + // followed by `InitialTargetResult::Opened`. The synchronous + // snapshot is deliberately the pre-existing document; dired's + // post-await commit replaces it on a later daemon tick. + let mut directory = attach_target(&socket, temp.path(), Path::new(".")); + let bootstrap_buffer = directory.buffer_id; + let (dired_buffer, listing) = directory.wait_for_replacement_snapshot(); + assert_ne!( + dired_buffer, bootstrap_buffer, + "the asynchronous resolver must replace the bootstrap document" + ); + let canonical = fs::canonicalize(temp.path()).expect("canonical directory"); + let mut lines = listing.lines(); + let expected_header = format!("{}:", canonical.display()); + assert_eq!( + lines.next(), + Some(expected_header.as_str()), + "the replacement snapshot must be dired's directory surface:\n{listing}" + ); + assert!( + lines.any(|line| line.trim_end().ends_with(listed_name)), + "dired must list the file that existed before bootstrap:\n{listing}" + ); fs::write(temp.path().join("still-alive.txt"), "alive\n").expect("write survivor"); let survivor = attach_target(&socket, temp.path(), Path::new("still-alive.txt")); From 3be4285f7c7d6833811853b3bf82bd22c3dd7daa Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Tue, 28 Jul 2026 10:01:18 -0400 Subject: [PATCH 5/9] docs(active-work): record review-round gates Close PR 183 review round 1 in the volatile ledger and record the post-correction full gate matrix at ec4191f. --- docs/active-work.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 676de4f..95b6e9b 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -171,7 +171,7 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey/GPU directory-target ratchet — PR #183 REGATING REVIEW ROUND 1 +## Journey/GPU directory-target ratchet — PR #183 GATED AFTER REVIEW ROUND 1 - **Approved correction, not new product behavior.** GPU initial-target framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make @@ -198,10 +198,9 @@ If it does not, stop and repair the remote/fetch configuration. Stage 2 rev-5 recovery bullet named rev 4's framing branch. And the durable handoff still named pre-Journey `main` even though this ledger had advanced. The first is now a post-quiescence transport assertion; - the latter two are corrected in this revision. The touched suite is - green **15/15**; the full gate matrix is being rerun before this round - closes. -- **Pre-review full gate matrix was green at `486ce16`:** + the latter two are corrected in this revision. The complete matrix + below is green on the corrected tree. +- **Post-review full gate matrix is green at `ec4191f`:** - `cargo fmt --check`; - strict workspace clippy; - library **1,849 passed / 3 ignored**; @@ -217,6 +216,10 @@ If it does not, stop and repair the remote/fetch configuration. - **Gate diagnostics retained:** initial fresh-worktree attempts without the documented `pmacs-gpu` prerequisite and without out-of-sandbox Unix-socket permission were setup failures, not product evidence. + During the review rerun, an in-sandbox library attempt reproduced the + latter setup failure as `EPERM` in three attach socket tests; the + authoritative out-of-sandbox rerun passed all **1,849** non-ignored + tests. The first full-workspace attempt then exhausted the `/tmp` filesystem quota while linking. Moving only the disposable Cargo target to disk let the sweep run; its first completed pass exposed one transient From 34b8f28cf2ff42d0323c256c5fcce019df7a23ef Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Tue, 28 Jul 2026 10:27:22 -0400 Subject: [PATCH 6/9] test(journey): ratchet the public GPU directory path Drive pmacs --gpu . through the root broker and real managed GPU connector, keep the session alive through the asynchronous dired replacement, and assert its canonical listing before daemon reuse. Expose snapshot count and materialized text through the private display-less acceptance probe so the public path is observable. --- docs/active-work.md | 25 ++++-- pmacs-gpu/src/main.rs | 101 ++++++++++++++++++++---- tests/gpu_invocation_acceptance.rs | 121 ++++++++++++++++------------- 3 files changed, 172 insertions(+), 75 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 95b6e9b..2525cc3 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -171,7 +171,7 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey/GPU directory-target ratchet — PR #183 GATED AFTER REVIEW ROUND 1 +## Journey/GPU directory-target ratchet — PR #183 REGATING PUBLIC PATH - **Approved correction, not new product behavior.** GPU initial-target framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make @@ -186,12 +186,15 @@ If it does not, stop and repair the remote/fetch configuration. . It is intentionally open and unmerged pending user review. - **Scope is one acceptance ratchet:** remove `"."` from the four - genuinely invalid cases and add a transport-level positive which - requires snapshot-first + `InitialTargetResult::Opened` for `"."`, - then consumes the post-quiescence replacement snapshot and requires - dired's canonical header plus a known directory entry before proving - the same daemon can open a following file target. No production - source, protocol, framing decision, or coherence grade changes. + genuinely invalid cases and drive the public `pmacs --gpu .` root + broker through the real managed GPU connector. The positive requires + snapshot-first + `InitialTargetResult::Opened`, then consumes the + post-quiescence replacement snapshot and requires dired's canonical + header plus a known directory entry before proving the same daemon can + open a following file target. The private display-less acceptance + probe now reports its snapshot count and final materialized text so + that public path is observable. No normal frontend/daemon behavior, + protocol, framing decision, or coherence grade changes. - **Review round 1: three findings, all real and corrected.** The first test stopped at the deliberately pre-existing bootstrap document, so it did not pin the resolver's later dired commit. The @@ -200,6 +203,14 @@ If it does not, stop and repair the remote/fetch configuration. had advanced. The first is now a post-quiescence transport assertion; the latter two are corrected in this revision. The complete matrix below is green on the corrected tree. +- **Live public-path check tightened that correction further.** A user + report that `pmacs --gpu .` differed from `pmacs .` did not reproduce: + the live default daemon delivered both snapshots, and a traced + windowed invocation applied both and displayed dired. It nevertheless + exposed that the corrected acceptance still attached a raw protocol + client rather than invoking the public root broker and real GPU + connector. The test now covers those surfaces and passes **15/15**; + its full matrix is being rerun before this revision is pushed. - **Post-review full gate matrix is green at `ec4191f`:** - `cargo fmt --check`; - strict workspace clippy; diff --git a/pmacs-gpu/src/main.rs b/pmacs-gpu/src/main.rs index a26f340..86132fc 100644 --- a/pmacs-gpu/src/main.rs +++ b/pmacs-gpu/src/main.rs @@ -936,10 +936,20 @@ fn run_headless_managed_probe( } }; let mut client = managed.client; + let initial_message = client.take_initial_message(); let initial_target_ready = matches!( - client.take_initial_message(), + initial_message.as_ref(), Some(InstanceMessage::BufferSnapshot { .. }) ); + let mut buffer_facts = ManagedProbeBufferFacts::default(); + if let Some(message) = initial_message.as_ref() + && let Err(error) = buffer_facts.observe(message) + { + let contents = format!("phase=error\nerror={error}\n"); + let _ = write_probe_report(report, &contents); + eprintln!("pmacs-gpu managed probe: {error}"); + return 7; + } let daemon = managed.daemon; let protocol = client.server_protocol_version(); @@ -961,8 +971,14 @@ fn run_headless_managed_probe( let mut last_wait_result = None; let mut last_disconnect = String::new(); if ready - && let Err(error) = - write_managed_probe_report(report, "ready", protocol, &daemon, &disconnect) + && let Err(error) = write_managed_probe_report( + report, + "ready", + protocol, + &daemon, + &buffer_facts, + &disconnect, + ) { eprintln!( "pmacs-gpu managed probe: writing {} failed: {error}", @@ -976,11 +992,23 @@ fn run_headless_managed_probe( } match event_rx.recv_timeout(Duration::from_millis(50)) { Ok(AttachEvent::Message(message)) => { - if matches!(*message, InstanceMessage::BufferSnapshot { .. }) && !ready { + let is_snapshot = matches!(*message, InstanceMessage::BufferSnapshot { .. }); + if let Err(error) = buffer_facts.observe(&message) { + let contents = format!("phase=error\nerror={error}\n"); + let _ = write_probe_report(report, &contents); + eprintln!("pmacs-gpu managed probe: {error}"); + return 7; + } + if is_snapshot { ready = true; - if let Err(error) = - write_managed_probe_report(report, "ready", protocol, &daemon, &disconnect) - { + if let Err(error) = write_managed_probe_report( + report, + "ready", + protocol, + &daemon, + &buffer_facts, + &disconnect, + ) { eprintln!( "pmacs-gpu managed probe: writing {} failed: {error}", report.display() @@ -1006,9 +1034,14 @@ fn run_headless_managed_probe( || wait_result != last_wait_result || disconnect != last_disconnect) { - if let Err(error) = - write_managed_probe_report(report, "ready", protocol, &daemon, &disconnect) - { + if let Err(error) = write_managed_probe_report( + report, + "ready", + protocol, + &daemon, + &buffer_facts, + &disconnect, + ) { eprintln!( "pmacs-gpu managed probe: writing {} failed: {error}", report.display() @@ -1021,9 +1054,14 @@ fn run_headless_managed_probe( } if ready && stdin_closed { - if let Err(error) = - write_managed_probe_report(report, "complete", protocol, &daemon, &disconnect) - { + if let Err(error) = write_managed_probe_report( + report, + "complete", + protocol, + &daemon, + &buffer_facts, + &disconnect, + ) { eprintln!( "pmacs-gpu managed probe: writing {} failed: {error}", report.display() @@ -1043,11 +1081,42 @@ fn run_headless_managed_probe( } } +#[derive(Default)] +struct ManagedProbeBufferFacts { + snapshots: u32, + last_snapshot_text: String, +} + +impl ManagedProbeBufferFacts { + fn observe(&mut self, message: &InstanceMessage) -> Result<(), String> { + let InstanceMessage::BufferSnapshot { crdt_snapshot, .. } = message else { + return Ok(()); + }; + let doc = loro::LoroDoc::new(); + doc.import(crdt_snapshot) + .map_err(|error| format!("BufferSnapshot import failed: {error:?}"))?; + self.snapshots += 1; + self.last_snapshot_text = doc.get_text(LORO_TEXT_CONTAINER).to_string(); + Ok(()) + } +} + +fn hex_bytes(bytes: &[u8]) -> String { + use std::fmt::Write as _; + + let mut encoded = String::with_capacity(bytes.len() * 2); + for byte in bytes { + let _ = write!(encoded, "{byte:02x}"); + } + encoded +} + fn write_managed_probe_report( report: &Path, phase: &str, protocol: u32, daemon: &attach::ManagedDaemonFacts, + buffer_facts: &ManagedProbeBufferFacts, disconnect: &str, ) -> std::io::Result<()> { use std::fmt::Write as _; @@ -1056,6 +1125,12 @@ fn write_managed_probe_report( let _ = writeln!(out, "phase={phase}"); let _ = writeln!(out, "server_protocol_version={protocol}"); let _ = writeln!(out, "buffer_snapshot=true"); + let _ = writeln!(out, "buffer_snapshots={}", buffer_facts.snapshots); + let _ = writeln!( + out, + "last_snapshot_hex={}", + hex_bytes(buffer_facts.last_snapshot_text.as_bytes()) + ); let _ = writeln!(out, "spawned_daemon={}", daemon.spawned_daemon()); let _ = writeln!( out, diff --git a/tests/gpu_invocation_acceptance.rs b/tests/gpu_invocation_acceptance.rs index 13dc020..ec6be89 100644 --- a/tests/gpu_invocation_acceptance.rs +++ b/tests/gpu_invocation_acceptance.rs @@ -121,6 +121,19 @@ mod crdt { .collect() } + fn decode_hex(encoded: &str) -> String { + assert_eq!(encoded.len() % 2, 0, "hex payload must have even length"); + let bytes = encoded + .as_bytes() + .chunks_exact(2) + .map(|pair| { + let pair = std::str::from_utf8(pair).expect("hex pair is UTF-8"); + u8::from_str_radix(pair, 16).expect("decode hex pair") + }) + .collect::>(); + String::from_utf8(bytes).expect("snapshot text is UTF-8") + } + fn wait_for_fact( report: &Path, key: &str, @@ -223,34 +236,6 @@ mod crdt { stream: UnixStream, } - impl TargetSession { - fn wait_for_replacement_snapshot(&mut self) -> (pmacs::buffer::BufferId, String) { - let deadline = Instant::now() + Duration::from_secs(10); - loop { - assert!( - Instant::now() < deadline, - "target frontend did not receive a replacement buffer snapshot" - ); - match read_message::(&mut self.stream) - .expect("read target frontend after bootstrap") - { - InstanceMessage::BufferSnapshot { - buffer_id, - crdt_snapshot, - } if buffer_id != self.buffer_id => { - let replica = - CrdtState::new(self.frontend_id.0).expect("replacement buffer replica"); - replica - .import_snapshot(&crdt_snapshot) - .expect("import replacement buffer snapshot"); - return (buffer_id, replica.materialize_string()); - } - _ => {} - } - } - } - } - fn attach_target(socket: &Path, cwd: &Path, path: &Path) -> TargetSession { use std::os::unix::ffi::OsStrExt; @@ -384,6 +369,16 @@ mod crdt { } impl ManagedProbe { + fn from_child(mut child: Child, report: &Path) -> Self { + let stdin = child.stdin.take().expect("probe stdin"); + Self { + child, + stdin: Some(stdin), + report: report.to_owned(), + daemon_pid: None, + } + } + fn spawn(socket: &Path, report: &Path, daemon_executable: &Path, home: &Path) -> Self { Self::spawn_with_env(socket, report, daemon_executable, home, &[]) } @@ -446,18 +441,11 @@ mod crdt { for (key, value) in envs { command.env(key, value); } - let mut child = command.spawn().expect("spawn managed probe"); - let stdin = child.stdin.take().expect("probe stdin"); - Self { - child, - stdin: Some(stdin), - report: report.to_owned(), - daemon_pid: None, - } + Self::from_child(command.spawn().expect("spawn managed probe"), report) } - fn wait_ready(&mut self) -> HashMap { - let facts = wait_for_fact(&self.report, "phase", "ready", Duration::from_secs(10)); + fn wait_for(&mut self, key: &str, expected: &str) -> HashMap { + let facts = wait_for_fact(&self.report, key, expected, Duration::from_secs(10)); if facts .get("spawned_daemon") .is_some_and(|value| value == "true") @@ -467,6 +455,10 @@ mod crdt { facts } + fn wait_ready(&mut self) -> HashMap { + self.wait_for("phase", "ready") + } + fn close(mut self) -> std::process::ExitStatus { self.stdin.take(); wait_for_fact(&self.report, "phase", "complete", Duration::from_secs(5)); @@ -691,25 +683,46 @@ mod crdt { } #[test] - fn directory_target_reaches_ready_and_leaves_the_daemon_usable() { + fn public_gpu_directory_target_reaches_dired_and_leaves_the_daemon_usable() { let temp = secure_tempdir(); let socket = temp.path().join("directory-target.sock"); + let report = temp.path().join("directory-target-report"); + let wrapper = temp.path().join("headless-gpu"); let listed_name = "listed-before-bootstrap.txt"; fs::write(temp.path().join(listed_name), "listed\n").expect("write listed file"); - let mut daemon = spawn_daemon(&socket, &[]); - - // Journey Stage 1a superseded the old IsADirectory failure: - // `attach_target` requires the production snapshot-first sequence - // followed by `InitialTargetResult::Opened`. The synchronous - // snapshot is deliberately the pre-existing document; dired's - // post-await commit replaces it on a later daemon tick. - let mut directory = attach_target(&socket, temp.path(), Path::new(".")); - let bootstrap_buffer = directory.buffer_id; - let (dired_buffer, listing) = directory.wait_for_replacement_snapshot(); - assert_ne!( - dired_buffer, bootstrap_buffer, - "the asynchronous resolver must replace the bootstrap document" + write_script( + &wrapper, + "test \"$1\" = \"--managed-attach\"\n\ + socket=$2\n\ + daemon=$3\n\ + shift 3\n\ + exec \"$PMACS_REAL_GPU\" --headless-managed-probe \ + \"$socket\" \"$PMACS_TEST_REPORT\" \"$daemon\" \"$@\"", ); + + let mut command = Command::new(pmacs_binary()); + command + .args(["--gpu", "--socket"]) + .arg(&socket) + .arg(".") + .current_dir(temp.path()) + .env(TEST_GPU_OVERRIDE, &wrapper) + .env("PMACS_REAL_GPU", gpu_binary()) + .env("PMACS_TEST_REPORT", &report) + .env("HOME", temp.path()) + .env("XDG_CONFIG_HOME", temp.path()) + .stdin(Stdio::piped()) + .stdout(Stdio::null()) + .stderr(Stdio::null()); + let mut directory = + ManagedProbe::from_child(command.spawn().expect("spawn public GPU command"), &report); + + // The public root broker and real managed GPU connector must stay + // alive through Journey N2's asynchronous dired commit. Snapshot + // one is the deliberately pre-existing bootstrap document; snapshot + // two is the post-quiescence directory surface. + let facts = directory.wait_for("buffer_snapshots", "2"); + let listing = decode_hex(&facts["last_snapshot_hex"]); let canonical = fs::canonicalize(temp.path()).expect("canonical directory"); let mut lines = listing.lines(); let expected_header = format!("{}:", canonical.display()); @@ -727,10 +740,8 @@ mod crdt { let survivor = attach_target(&socket, temp.path(), Path::new("still-alive.txt")); assert_eq!(survivor.replica.materialize_string(), "alive\n"); - drop(directory); drop(survivor); - signal_pid(daemon.id(), Signal::SIGTERM); - assert!(wait_for_exit(&mut daemon, Duration::from_secs(5)).success()); + assert!(directory.close().success()); } #[test] From 22dc46c184746c0886bf03efc8c1749953871796 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Tue, 28 Jul 2026 10:33:26 -0400 Subject: [PATCH 7/9] docs(active-work): record public-path gates Record the green full matrix for the public pmacs --gpu directory acceptance revision at 34b8f28. --- docs/active-work.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/active-work.md b/docs/active-work.md index 2525cc3..2520abe 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -171,7 +171,7 @@ If it does not, stop and repair the remote/fetch configuration. to recur; the next occurrence carries its own evidence under whoever's PR, and a Stage B framing follows then. -## Journey/GPU directory-target ratchet — PR #183 REGATING PUBLIC PATH +## Journey/GPU directory-target ratchet — PR #183 GATED ON PUBLIC PATH - **Approved correction, not new product behavior.** GPU initial-target framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make @@ -210,8 +210,8 @@ If it does not, stop and repair the remote/fetch configuration. exposed that the corrected acceptance still attached a raw protocol client rather than invoking the public root broker and real GPU connector. The test now covers those surfaces and passes **15/15**; - its full matrix is being rerun before this revision is pushed. -- **Post-review full gate matrix is green at `ec4191f`:** + its full matrix is green at `34b8f28`. +- **Full gate matrix is green on the public-path revision at `34b8f28`:** - `cargo fmt --check`; - strict workspace clippy; - library **1,849 passed / 3 ignored**; From dc2dc4262767e84ece92a29856e5a728cc02cd5a Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Tue, 28 Jul 2026 11:02:48 -0400 Subject: [PATCH 8/9] test(journey): retain daemon cleanup while awaiting dired Capture the managed daemon's lifecycle facts from the ready report before waiting for the post-quiescence directory snapshot. If that regression assertion times out, the acceptance harness can now terminate the daemon instead of leaving it orphaned. --- tests/gpu_invocation_acceptance.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/gpu_invocation_acceptance.rs b/tests/gpu_invocation_acceptance.rs index ec6be89..b4e3102 100644 --- a/tests/gpu_invocation_acceptance.rs +++ b/tests/gpu_invocation_acceptance.rs @@ -721,6 +721,13 @@ mod crdt { // alive through Journey N2's asynchronous dired commit. Snapshot // one is the deliberately pre-existing bootstrap document; snapshot // two is the post-quiescence directory surface. + // Capture the spawned daemon's PID from the ready report first so + // ManagedProbe::drop can terminate it if snapshot two never arrives. + let ready = directory.wait_ready(); + assert_eq!( + ready.get("spawned_daemon").map(String::as_str), + Some("true") + ); let facts = directory.wait_for("buffer_snapshots", "2"); let listing = decode_hex(&facts["last_snapshot_hex"]); let canonical = fs::canonicalize(temp.path()).expect("canonical directory"); From 22c1b14b18256074dd6d72e00391ba5459cb8344 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Tue, 28 Jul 2026 11:03:36 -0400 Subject: [PATCH 9/9] docs(active-work): record review-round cleanup gates Record the second-pass daemon-cleanup finding, its correction, and the green verification matrix on the updated PR branch. --- docs/active-work.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/active-work.md b/docs/active-work.md index 2520abe..a269a70 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -211,6 +211,22 @@ If it does not, stop and repair the remote/fetch configuration. client rather than invoking the public root broker and real GPU connector. The test now covers those surfaces and passes **15/15**; its full matrix is green at `34b8f28`. +- **Review round 2 found and fixed one failure-path cleanup gap at + `dc2dc42`.** The public-path test waited directly for dired's second + snapshot, but `ManagedProbe` only retained a spawned daemon's PID after + a successful wait. If the exact missing-snapshot regression recurred, + the timeout would therefore be unable to terminate that daemon. The + test now consumes the initial ready report first, retaining lifecycle + facts before it starts the post-quiescence assertion. +- **Review-round-2 gates are green:** `cargo fmt --check`; strict + workspace clippy; library **1,849 passed / 3 ignored**; CRDT library + **2,034 passed / 4 ignored**; focused public-path test **1/1** and full + GPU invocation suite **15/15**; M4 **121 passed / 3 ignored / 1 + filtered**; required GPU package **202/202**; `git diff --check`. + The first in-sandbox GPU-package attempt reproduced the repository's + documented Unix-socket restriction as three attach failures plus a + blocked peer read; the authoritative out-of-sandbox rerun passed all + **202** tests in under one second. - **Full gate matrix is green on the public-path revision at `34b8f28`:** - `cargo fmt --check`; - strict workspace clippy;