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.
This commit is contained in:
Levi Neuwirth 2026-07-28 09:48:48 -04:00
parent c2b855e252
commit ec4191fd8e
3 changed files with 83 additions and 16 deletions

View File

@ -1,6 +1,6 @@
# Active work — cross-machine resume ledger # 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 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 entries when their PR merges; do not let this become a second permanent
backlog. 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 to recur; the next occurrence carries its own evidence under whoever's
PR, and a Stage B framing follows then. 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 - **Approved correction, not new product behavior.** GPU initial-target
framing Q#GT6 / acceptance 10 and Journey Stage 1a N2/N5 already make 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 - **Scope is one acceptance ratchet:** remove `"."` from the four
genuinely invalid cases and add a transport-level positive which genuinely invalid cases and add a transport-level positive which
requires snapshot-first + `InitialTargetResult::Opened` for `"."`, requires snapshot-first + `InitialTargetResult::Opened` for `"."`,
then proves the same daemon can open a following file target. No then consumes the post-quiescence replacement snapshot and requires
production source, protocol, framing decision, or coherence grade dired's canonical header plus a known directory entry before proving
changes. the same daemon can open a following file target. No production
- **Full gate matrix is green at `486ce16`:** 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`; - `cargo fmt --check`;
- strict workspace clippy; - strict workspace clippy;
- library **1,849 passed / 3 ignored**; - library **1,849 passed / 3 ignored**;
@ -457,10 +467,12 @@ remaining dependency.
`docs/agent-handoff.md` §1; the two round lessons are in §5. `docs/agent-handoff.md` §1; the two round lessons are in §5.
- Landed-docs follow-up merged as **#156** (`main` @ `d152120`, - Landed-docs follow-up merged as **#156** (`main` @ `d152120`,
2026-07-25). 2026-07-25).
- **Stage 2 framing: `docs/bottom-panel-stage2-framing.md` revision 5**, - **Stage 2 framing: `docs/bottom-panel-stage2-framing.md` revision 5**
on branch `githubsucks/bottom-panel-stage2-framing` (three commits, is commit `56301ed` on branch `githubsucks/bottom-panel-stage2b`,
one per pre-implementation revision), worktree `../pmacs-bp-stage2`, based on worktree `../pmacs-bp-stage2b`. Revisions 14 remain on
`githubsucks/main` @ `ccf29e3`. Round 1 closed 2 blocking + 3 high; `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 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 items; round 3 closed 1 blocking + 1 high + 1 medium. No open items
remain. Revision 5 adds no decision; it records the approved remain. Revision 5 adds no decision; it records the approved

View File

@ -1,6 +1,9 @@
# Agent handoff — cross-machine continuity # 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, materializes a terminal's whole retained range into an ordinary buffer,
plus `Buffer::set_generated_contents`, the first genuinely immutable plus `Buffer::set_generated_contents`, the first genuinely immutable
generated-buffer write path — and its landed-doc pair (#168); following 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 For volatile branches, checkpoints, verification, and recovery
commands, read `docs/active-work.md` immediately after this file. 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 - `main` @ `c2d56ff` (Journey Stage 1a #182, incorporating terminal
landed docs #169 and the PTY-terminate diagnostic #176, terminal copy 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 mode #178, the GPU-terminal-input landed docs #168, Lean 4 Stage 4a
#179, bottom-panel Stage 2A #179, bottom-panel Stage 2A
#177, the bottom-panel Stage 2 framing #175, terminal configuration #177, the bottom-panel Stage 2 framing #175, terminal configuration

View File

@ -223,6 +223,34 @@ mod crdt {
stream: UnixStream, 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::<InstanceMessage>(&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 { fn attach_target(socket: &Path, cwd: &Path, path: &Path) -> TargetSession {
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
@ -666,12 +694,34 @@ mod crdt {
fn directory_target_reaches_ready_and_leaves_the_daemon_usable() { fn directory_target_reaches_ready_and_leaves_the_daemon_usable() {
let temp = secure_tempdir(); let temp = secure_tempdir();
let socket = temp.path().join("directory-target.sock"); 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, &[]); let mut daemon = spawn_daemon(&socket, &[]);
// Journey Stage 1a superseded the old IsADirectory failure: // Journey Stage 1a superseded the old IsADirectory failure:
// `attach_target` requires the production snapshot-first sequence // `attach_target` requires the production snapshot-first sequence
// followed by `InitialTargetResult::Opened`. // followed by `InitialTargetResult::Opened`. The synchronous
let directory = attach_target(&socket, temp.path(), Path::new(".")); // 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"); 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")); let survivor = attach_target(&socket, temp.path(), Path::new("still-alive.txt"));