merge: integrate main @ 6c9e765, and absorb three landed lanes
Merges `main` (PRs #186 and #171) into the 2B-2 branch — a clean auto-merge, no conflict — and carries the ledger absorption those two merges left owed. `main` currently describes three lanes wrongly. The #186 lane still says "OPEN, PROPOSED, DO NOT MERGE" and the #171 lane still says "AT REVISION 9, AWAITING APPROVAL", because each PR merged carrying its own pre-merge lane text; #187's lane says "OPEN" for the same reason this commit exists. Rule 4 forbids relabelling a landed lane and allows removing it only once its durable facts reach `docs/agent-handoff.md`, so no earlier commit could legally fix any of them. This one does both halves together. Handoff §1 gains three arc bullets and an advanced anchor (`7586905` -> `6c9e765`): * bottom-panel Stage 2B-2, recording what the review round taught rather than what the feature does — a durable transition implemented as a per-frame effect is a bug shape and four of five findings were that one shape; a producer should be checked against the other frontend kind's equivalent; a panel may legitimately be wider than a PTY; and mutation testing cannot reach behaviour never modelled, which is why 16/16 passed while five real defects stood; * dired Stage 2 (#171) as an approved framing with no implementation, carrying the order-independence decision and the reason a token was rejected rather than built, the already-destructive refused kill, path-derived buffer names, and the uncorrelated URI-store writers; * the resource-op delete guard (#186) likewise, carrying the four-phase ordering, why `find_buffer_for_path` is the wrong lookup, that pmacs advertises no `workspace.workspaceEdit` capability at all, and that `pmacs.fs.remove` is guarded by neither lane. The ledger then drops both framing lanes (335 lines) and rewrites the bottom-panel lane to the remaining 2B-3 plan rather than deleting it, since 2B-3 and Stage 3 are still ahead. Two stale claims elsewhere in the file are corrected as a consequence: the intro's "#171's lane is below", and the recovery block's instruction not to start 2B-3 until #187 lands. #188 deliberately gets no lane here. Its lane lives on its own branch and arrives with it — writing one here for work that lands elsewhere is what makes this file re-conflict on every merge. No runtime code. No protocol change.
This commit is contained in:
commit
7c1563c2c2
|
|
@ -5,11 +5,26 @@ 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.
|
||||
|
||||
**No lane below is retained past its merge.** The PTY terminate
|
||||
diagnostic (#176) was the last one — retained because rule 4 removes a
|
||||
**No lane below is retained past its merge.** This snapshot removes the
|
||||
resource-op delete guard (#186) and dired Stage 2 framing (#171) lanes
|
||||
the moment their PRs merged, because the same commit put their
|
||||
load-bearing decisions into `docs/agent-handoff.md` §1 — rule 4's
|
||||
precondition, satisfied deliberately rather than deferred. The
|
||||
bottom-panel lane is not removed: 2B-2 landing leaves 2B-3 and Stage 3
|
||||
ahead of it, so the lane is rewritten to the remaining plan.
|
||||
|
||||
**One open PR has no lane here: #188**, the generated-buffer
|
||||
immutability framing. Its lane lives on its own branch and arrives with
|
||||
it, which is deliberate — with several PRs open, a lane written here for
|
||||
work that lands elsewhere re-conflicts on every merge.
|
||||
|
||||
The PTY terminate
|
||||
diagnostic (#176) was the last lane retained past its merge — retained
|
||||
because rule 4 removes a
|
||||
merged lane only *after* its durable facts reach
|
||||
`docs/agent-handoff.md`, and that absorption was unowned. This snapshot
|
||||
owns it: #176's facts are now in the handoff (§1's arc bullet and §5's
|
||||
`docs/agent-handoff.md`, and that absorption was unowned. The
|
||||
2026-07-28 snapshot
|
||||
owned it: #176's facts are now in the handoff (§1's arc bullet and §5's
|
||||
two ops lessons about ticking observers and proving child exit), so its
|
||||
lane is gone. The Lean 4, GPU-terminal-input, inline-math (#172), dired
|
||||
(#169), and terminal config + copy mode lanes were removed the same way
|
||||
|
|
@ -20,14 +35,15 @@ would stop re-conflicting in this file.
|
|||
number appears in `git log --first-parent githubsucks/main`, it has
|
||||
landed regardless of what a lane says.
|
||||
|
||||
**Two open PRs had no lane here at all before this snapshot** — #174 and
|
||||
#171. An open PR is exactly the volatile work this file exists to
|
||||
record, so its absence is a ledger defect rather than a tidy omission:
|
||||
#171 drifted **153 commits** while invisible here, and its still-green
|
||||
old CI run describes a tree nobody has looked at since. **When a PR is
|
||||
opened, give it a lane.** #174 has since merged, so per rule 4 its lane
|
||||
is gone again and its durable lesson is in `docs/agent-handoff.md` §5;
|
||||
#171's lane is below.
|
||||
**Two open PRs had no lane here at all before the 2026-07-28
|
||||
snapshot** — #174 and #171. An open PR is exactly the volatile work this
|
||||
file exists to record, so its absence is a ledger defect rather than a
|
||||
tidy omission: #171 drifted **153 commits** while invisible here, and
|
||||
its still-green old CI run described a tree nobody had looked at since.
|
||||
**When a PR is opened, give it a lane.** All three have since merged —
|
||||
#174, #171 and #186 — so per rule 4 their lanes are gone again and
|
||||
their durable facts are in `docs/agent-handoff.md` (§5 for #174's
|
||||
lesson, §1 for the two framings).
|
||||
|
||||
## Repository authority
|
||||
|
||||
|
|
@ -229,18 +245,16 @@ 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) — 2B-1 MERGED; 2B-2 PR #187 OPEN
|
||||
## Bottom-panel lane (Arc 7) — 2B-2 MERGED; 2B-3 IS NEXT
|
||||
|
||||
Stage 1, the Stage 2 framing, Stage 2A, and **Stage 2B-1 are all on
|
||||
`main`**. Framing revision 5's three-way split of 2B was explicitly
|
||||
approved on 2026-07-27; revision 6 records PR #184's review correction.
|
||||
**2B-2 — the daemon panel projection and epoch machine — is open as
|
||||
[PR #187](https://github.com/levineuwirth/pmacs/pull/187)** on branch
|
||||
`bottom-panel-stage2b2`, worktree `../pmacs-bp-stage2b2`. It branched
|
||||
fresh from landed 2B-1 rather than stacking on its feature branch, and
|
||||
has since integrated landed main through `7586905` (#174, #185, and
|
||||
#189). The exact pre-round-2 reviewed head was merge checkpoint
|
||||
`0dba358`; the round-2 code-and-test checkpoint is `bfaaf2b`.
|
||||
Stage 1, the Stage 2 framing, Stage 2A, Stage 2B-1, and **Stage 2B-2 are
|
||||
all on `main`**. Framing revision 5's three-way split of 2B was
|
||||
explicitly approved on 2026-07-27; revision 6 records PR #184's review
|
||||
correction. **2B-2 — the daemon panel projection and epoch machine —
|
||||
landed as [PR #187](https://github.com/levineuwirth/pmacs/pull/187)**,
|
||||
one review round of five findings on top of the implementation, 12/12
|
||||
green, 22/22 mutations biting. Its durable lessons are in
|
||||
`docs/agent-handoff.md` §1; what remains below is the 2B-3 plan.
|
||||
|
||||
**2B-2's boundaries, restated because they are easy to overrun:** the
|
||||
production `Hello` stays at v20 and `panel_capable` stays `false`. The
|
||||
|
|
@ -249,7 +263,7 @@ activation, the GPU band, and the negotiated capability flip are all
|
|||
2B-3's, and 2B-3 may **not** simply change the unsolicited `Hello` to
|
||||
21.
|
||||
|
||||
- **What PR #187 ships, dark by construction:** the semantic daemon's
|
||||
- **What PR #187 shipped, dark by construction:** the semantic daemon's
|
||||
`FrontendCellGeometry` epoch machine; one reconciled panel grid
|
||||
derivation; `PanelFrame::{Present, Absent}` projection on both document
|
||||
and terminal semantic paths; stable presentation epochs; resize and
|
||||
|
|
@ -293,9 +307,8 @@ activation, the GPU band, and the negotiated capability flip are all
|
|||
git rev-parse HEAD
|
||||
```
|
||||
|
||||
Require the remote branch to contain `bfaaf2b` or newer and confirm
|
||||
PR #187's exact-head checks before resuming. Do not start 2B-3 until
|
||||
#187 lands.
|
||||
#187 has landed, so `githubsucks/main` already contains this work and
|
||||
the branch is retained only for provenance. Start 2B-3 from `main`.
|
||||
- **Stage 2B-1 MERGED as #184** (`main` @ `6bee09d`, 2026-07-28; all
|
||||
twelve checks green on the reviewed head `5539b6e`; two review rounds
|
||||
plus a gate-found follow-up). Branch
|
||||
|
|
@ -508,58 +521,6 @@ has **no branch and no framing yet**.
|
|||
`FrontendView.fold_projection` to `true` for semantic frontends, which
|
||||
Stage 2 deliberately left `false` (Q#FD21).
|
||||
|
||||
## dired Stage 2 framing lane — PR #171 OPEN, STALE, DO NOT MERGE AS-IS
|
||||
|
||||
- Portable branch: `githubsucks/dired-stage2-framing` (head `ab42a79`,
|
||||
four framing commits); worktree `../pmacs-dired-stage1`. **PR #171**,
|
||||
base `main`. Framing only — `docs/dired-stage2-framing.md`, 1,570
|
||||
lines, no runtime code.
|
||||
- **Measured 2026-07-28: 4 commits ahead of `main`, 153 behind**, merge
|
||||
base `c8ec8f3`. GitHub reports it mergeable, and its old CI run is
|
||||
green — **both facts are about a tree nobody has looked at in 153
|
||||
commits**, and the document still says PROPOSED.
|
||||
- **The commit history embodies three review rounds. That is not the
|
||||
same as approval**, and GitHub records no formal review or comment on
|
||||
it. Do not read the round count as a green light.
|
||||
- **Its dependencies moved materially underneath it**, which is the real
|
||||
reason not to merge. Note that dired Stage 1 (#165) and find-file
|
||||
(#162) are its *base*, not new arrivals — the merge base `c8ec8f3`
|
||||
**is** #165's merge commit. Eighteen PRs landed after it, and at least
|
||||
three change ground the framing stands on:
|
||||
- **#178 gave generated buffers a write invariant**
|
||||
(`Buffer::set_generated_contents`). Dired's listing is a generated
|
||||
buffer, and dired is named in the handoff as one of the writer
|
||||
mechanisms that has **not** adopted it. Stage 2's marks and
|
||||
operations write that buffer constantly.
|
||||
- **#182 (Journey Stage 1a) made `resolve_target_buffer` the single
|
||||
directory-open path**, with dired demoted to a *replaceable slot*
|
||||
(`pmacs.path.directory_handler`) rather than a hook subscriber. Any
|
||||
Stage 2 claim about how a directory reaches dired is now describing
|
||||
a mechanism that no longer exists in that form.
|
||||
- **#179/#181 landed the typed-edit consumer chain**, which is the
|
||||
fan-out a rename transaction has to survive.
|
||||
|
||||
Re-scout against `6bee09d`, publish a new revision, and get explicit
|
||||
framing approval before any implementation. **The re-scout is under
|
||||
way** on the existing branch, so PR #171 keeps its three-round
|
||||
history; the product is a revision 5, not a new document. (`main` has
|
||||
since advanced to `0442d78`, but the only difference is the test-only
|
||||
#174, so no re-scout conclusion turns on it.)
|
||||
- **The rename problem the framing must still answer**, restated because
|
||||
it is the hard part: a rename is a transaction across **five** path
|
||||
owners — the buffer path, the buffer name, the URI-keyed LSP stores
|
||||
plus `DiagnosticView` (whose URI is set once at construction), dired's
|
||||
pathless handles, and a captured Lua local that no transaction can
|
||||
reach.
|
||||
- Intended serial implementation once approved: **2a** rename/delete
|
||||
reconciliation substrate with no dired UI, **2b** marks and
|
||||
operations, **2c** mkdir/copy/recursive-delete primitives, then Stage
|
||||
3 wdired.
|
||||
- **Ownership warning:** dired 2a overlaps `src/editor_core.rs`,
|
||||
`builtin/runtime/lsp.lua`, and the URI-keyed LSP state with other
|
||||
coherence work. Do not run it concurrently with Journey Stage 1b
|
||||
without assigning those files to one lane first.
|
||||
|
||||
## Parked lane: kill-ring browser + persistence
|
||||
|
||||
- Portable branch: `githubsucks/kill-ring-browser`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,13 @@
|
|||
# Agent handoff — cross-machine continuity
|
||||
|
||||
**Last updated: 2026-07-28, after the docs-only coherence listview
|
||||
correction (#189) and landed-state refresh (#185) merged; the canonical
|
||||
landed base is `7586905`. The runtime anchor beneath them is the M4
|
||||
**Last updated: 2026-07-28, as bottom-panel Stage 2B-2 (#187) — the
|
||||
daemon panel projection and the epoch machine — lands on `6c9e765`,
|
||||
which is the dired Stage 2 framing (#171) atop the resource-op delete
|
||||
guard framing (#186). Those two are framing-only: both are approved
|
||||
documents with no runtime code, and neither has begun implementation.
|
||||
Beneath them, the docs-only coherence listview
|
||||
correction (#189) and landed-state refresh (#185); the canonical
|
||||
landed base beneath those is `7586905`. The runtime anchor beneath them is the M4
|
||||
config-sink race fix (#174) and bottom-panel Stage 2B-1 (#184). #174 is
|
||||
test-only. #184 is the substantive one — the reserved protocol-v21
|
||||
bottom-panel wire family, dark by construction, with the production
|
||||
|
|
@ -52,7 +57,10 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
|
||||
## 1. Where the project stands (2026-07-28)
|
||||
|
||||
- `main` @ `7586905` (the docs-only coherence listview correction #189,
|
||||
- `main` @ `6c9e765` (the dired Stage 2 framing #171 and the resource-op
|
||||
delete guard framing #186 — both framing-only, no runtime code, no
|
||||
implementation started — atop
|
||||
the docs-only coherence listview correction #189,
|
||||
atop the docs-only landed-state refresh #185, the M4 config-sink race
|
||||
fix #174 — test-only — atop bottom-panel Stage 2B-1 #184, the
|
||||
Journey/GPU directory-target ratchet #183, Journey Stage 1a #182,
|
||||
|
|
@ -603,6 +611,97 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
statusline and Vterm Stage 3 ladders still pinned v20 and rejected
|
||||
v21, in both structural and real-headless-probe form. Grep for the
|
||||
outgoing version across `tests/` before calling a bump complete.
|
||||
- **Bottom panel Stage 2B-2 (daemon projection + epoch machine) LANDED
|
||||
— #187** (one review round of five findings on top of the
|
||||
implementation; 12/12 green; 22/22 mutations bite). What it
|
||||
establishes, beyond the feature:
|
||||
- **A durable transition implemented as a per-frame effect is a bug
|
||||
shape, not a style.** Four of the five review findings were one
|
||||
defect: a renderer-side conditional with a durable twin that
|
||||
disagreed with it. Wire-area exhaustion hid the rendered frame but
|
||||
left panel state live; a stale `panel_epoch` could address a
|
||||
reopened same-buffer panel; `NoMessage` cleared statusline segments
|
||||
it should have retained. The fix that generalizes is
|
||||
`presentable_panel_grid` — **one** private derivation behind both
|
||||
the renderer and `reconcile_panel_layout_core`, because two
|
||||
derivations of one predicate is *how* they drift. When touching
|
||||
panel rendering, ask of every conditional: is there a durable twin,
|
||||
and does it agree?
|
||||
- **Ask what the other frontend kind's equivalent does.** The
|
||||
semantic panel terminal missed the pre-child-drain resize its
|
||||
document sibling had; the repro is a 4×20 panel reporting 3×120.
|
||||
The new `sync_semantic_panel_terminal_layout` is disjoint from that
|
||||
sibling *by construction* — one resolves through
|
||||
`primary_document_window`, the other through `side_window_for` — so
|
||||
the SIGWINCH storm the original extraction prevented cannot recur
|
||||
through the new path.
|
||||
- **A panel may legitimately be wider than a PTY.** `>512` columns
|
||||
are legal on the wire (2B-1's `WireGridLimits` parameter), but
|
||||
`snapshot_for_view` refused the band's content rect and the band
|
||||
went `Absent` with `panel_hidden` false. Clamp the *terminal
|
||||
projection*, not the band: the child takes the columns a PTY can
|
||||
have and the remainder is band background.
|
||||
- **Mutation testing cannot reach behaviour never modelled.** All 16
|
||||
original mutations passed while five real defects stood; one of
|
||||
them even fired, removing an `Absent` the test asserted. Mutations
|
||||
prove assertions bite the code that exists. They say nothing about
|
||||
the assertion never written.
|
||||
- **One durability hole is accepted deliberately:** epoch exhaustion
|
||||
stays a per-frame `Absent`, flagged rather than hidden, because
|
||||
making it durable needs a new "presentation permanently
|
||||
unavailable" reason in `FrontendView` for a state requiring 2^64
|
||||
presentations in one session.
|
||||
- **dired Stage 2 framing LANDED (document only) — #171**
|
||||
(`docs/dired-stage2-framing.md`, revision 9; seven review rounds).
|
||||
**Approved as a framing; no runtime code and no implementation
|
||||
started.** Load-bearing decisions a reader must not re-derive:
|
||||
- **Reconciliation is order-independent, deliberately.** Reply order
|
||||
is *not* execution order — `AsyncRuntime::tick` drains the bus with
|
||||
`try_recv`, so a worker can finish first and be descheduled before
|
||||
sending. An ordering token was rejected rather than built: no
|
||||
static rule rescues the hazard anyway (rename `dir`→`newdir` racing
|
||||
delete `dir/child.txt` needs opposite orders depending on which ran
|
||||
first), and no production path can produce it. The trigger to
|
||||
revisit is named: the first production caller that fire-and-forgets
|
||||
two interdependent mutations.
|
||||
- **A refused mid-edit kill is already destructive.**
|
||||
`kill_buffer` clears round-trip state and moves windows *before*
|
||||
`BufferRegistry::remove` can return `ConcurrentEdit`, so
|
||||
`editing_in_progress` must be preflighted rather than relied on to
|
||||
refuse cleanly.
|
||||
- **Path-backed buffer names are not full paths.**
|
||||
`get_or_load_buffer` takes the name from the path *as given* and
|
||||
normalizes only the stored path, so a relative open is named
|
||||
`foo.rs`. Rename provenance is path-*equivalence*, not equality.
|
||||
- **URI-keyed stores have uncorrelated writers.**
|
||||
`textDocument/publishDiagnostics` is absorbed unconditionally, and
|
||||
`mark_document_stale` takes no `LspServerId` at all while creating
|
||||
URI keys across three stores. A route purge keyed on request
|
||||
responses cannot cover either.
|
||||
- **Resource-op delete guard framing LANDED (document only) — #186**
|
||||
(`docs/resource-op-delete-guard-framing.md`, revision 5; five review
|
||||
rounds). **Approved as a framing; no runtime code.** It owns the
|
||||
urgent **pre-filesystem refusal** for synchronous `apply_resource_op`
|
||||
— which on `main` today destroys unsaved work — while #171 owns full
|
||||
post-delete lifecycle reconciliation. Carried facts:
|
||||
- The sequence is `stat/no-op -> enumerate and validate -> mutate
|
||||
filesystem -> reconcile`. Validation inspects without removing, so
|
||||
a failed deletion leaves buffers intact and `on_removed` still
|
||||
observes the path already gone.
|
||||
- **`EditorCore::find_buffer_for_path` is the wrong lookup** — it
|
||||
delegates to first-match-only `find_by_path`, and
|
||||
`pmacs.buffer.from_file` creates path-bound buffers with no dedup,
|
||||
so a clean first match can hide a modified second.
|
||||
- **LSP does not promise batch atomicity, and pmacs advertises no
|
||||
`workspace.workspaceEdit` capability at all** — no
|
||||
`documentChanges`, no `resourceOperations`, no `failureHandling`.
|
||||
Recovery is the client's declared choice, and there is no spec
|
||||
default for a client that declares none. Say only that observed
|
||||
pmacs behaviour *resembles* abort-style application.
|
||||
- **`pmacs.fs.remove` has no dirty check of its own** and neither
|
||||
lane adds one. After both land the guards sit one layer above it.
|
||||
Latent — zero production callers — but "both lanes guard deletion"
|
||||
reads as the primitive being guarded, and it is not.
|
||||
- **GPU initial target LANDED — #148**
|
||||
(`docs/gpu-initial-target-framing.md` rev 3; merge `0dd16a5`; two review
|
||||
rounds). `pmacs --gpu [--socket NAME|PATH] FILE` transports exact Unix path
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue