docs: record 1b-2 as landed; collapse the journey lane to one block

Review round 2 on #205, one finding, accepted. #204 is this PR's base,
so three places still describing it as open were simply false.

- `COHERENCE.md` §2's step-6 row: "(PR open) ends the silence" ->
  "(#204) ended the silence", and the "flips only on merge" clause is
  replaced by the reason the row is still Partial at all — a server
  that starts and then crashes is unsurfaced, which that landing did
  not touch.
- `docs/agent-handoff.md`: the 1b-2 bullet says LANDED (#204), with the
  same substituted reason.
- `docs/active-work.md`: 1b-2's per-stage block is removed rather than
  relabelled, per rule 4 — it has merged and its durable facts are in
  the handoff, which is the precondition for removal.

That last one exposed a structural problem the merge had created: 1b-2's
old lane body had come in *underneath* the unified journey header, so
the file carried two journey sections and the first one's text
described the second's predecessor. There is now one arc lane with
1b-3 nested under it as the only open stage.

Also corrects the reap-ledger lane header, which still read
"IMPLEMENTED, PR OPEN" after #202 merged. Same class of staleness,
noticed while editing the same file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lv428Fth9LRtffwJSsqH7T
This commit is contained in:
Levi Neuwirth 2026-07-31 16:50:27 -04:00
parent 94036774a8
commit 08bc1a153c
3 changed files with 22 additions and 69 deletions

View File

@ -394,7 +394,7 @@ Full verdict table:
| 3 | Open real project | **Works at the CLI** | Journey Stage 1a: `resolve_target_buffer` answers `ResolvedTarget::Directory` before the EISDIR-producing load, and `EditorState::open` / the daemon bootstrap dispatch the `path.open-directory` chain, whose fallback is dired (#165's buffer, reached rather than duplicated). Startup no longer fails: an unreadable directory, a crashed resolver, and a cleared handler all report on the status line and leave the session running. Because the listing is async and the bootstrap is synchronous, the commit runs against a destination captured at request time (`pmacs.window.commit_to`) rather than against the ambient frontend | | 3 | Open real project | **Works at the CLI** | Journey Stage 1a: `resolve_target_buffer` answers `ResolvedTarget::Directory` before the EISDIR-producing load, and `EditorState::open` / the daemon bootstrap dispatch the `path.open-directory` chain, whose fallback is dired (#165's buffer, reached rather than duplicated). Startup no longer fails: an unreadable directory, a crashed resolver, and a cleared handler all report on the status line and leave the session running. Because the listing is async and the bootstrap is synchronous, the commit runs against a destination captured at request time (`pmacs.window.commit_to`) rather than against the ambient frontend |
| 4 | Understand interface | **Partial** | Mode line gives name/modified/L:C/scroll + mode/LSP/terminal segments. Journey Stage 1b-3 adds a welcome in `*scratch*` and `M-x help`; **still Partial** because `C-h` deletes a word (deliberately — §18) and there is no tutorial | | 4 | Understand interface | **Partial** | Mode line gives name/modified/L:C/scroll + mode/LSP/terminal segments. Journey Stage 1b-3 adds a welcome in `*scratch*` and `M-x help`; **still Partial** because `C-h` deletes a word (deliberately — §18) and there is no tutorial |
| 5 | Edit | **Works** | Full CUA + Emacs keymap in 161 lines (`builtin/keymaps/default.lua`); isearch, query-replace, kill ring, undo/redo, auto-indent/pair/comment, atomic save. Genuinely excellent zero-config | | 5 | Edit | **Works** | Full CUA + Emacs keymap in 161 lines (`builtin/keymaps/default.lua`); isearch, query-replace, kill ring, undo/redo, auto-indent/pair/comment, atomic save. Genuinely excellent zero-config |
| 6 | Language intelligence | **Partial** | Rust grammar bundled and auto-attaches; rust-analyzer preconfigured (`builtin/runtime/lsp.lua`). **Journey Stage 1b-2 (PR open) ends the silence** for a server that fails to *start*: the status line names the command, language and errno once per `(language, root, command)`; the modeline reads `LSP:!` instead of nothing; and `M-x lsp.status` renders `*lsp*` over the `status_buffer_text()` renderer that had existed since M4.8 with no caller. **Still Partial**, and flips only on merge (§25): a server that starts and then *crashes* is still unsurfaced | | 6 | Language intelligence | **Partial** | Rust grammar bundled and auto-attaches; rust-analyzer preconfigured (`builtin/runtime/lsp.lua`). **Journey Stage 1b-2 (#204) ended the silence** for a server that fails to *start*: the status line names the command, language and errno once per `(language, root, command)`; the modeline reads `LSP:!` instead of nothing; and `M-x lsp.status` renders `*lsp*` over the `status_buffer_text()` renderer that had existed since M4.8 with no caller. **Still Partial**, for a reason unaffected by that landing: a server that starts and then *crashes* is still unsurfaced`LspEventKind::Crashed` is pushed and no builtin subscriber handles it |
| 7 | Find symbol / file | **File: fixed (open by path merged #162; browsing #165). Symbol: works but undiscoverable** | No find-file/dired/picker existed at audit. Now `C-x C-f` opens a known path and `C-x d` / `C-x C-j` browse (flat listing, `dired` mode keymap); `M-.`/`M-?`/`C-c o` still bound but advertised nowhere and server-gated; no workspace-symbol command; `pmacs.index.*` has no UI | | 7 | Find symbol / file | **File: fixed (open by path merged #162; browsing #165). Symbol: works but undiscoverable** | No find-file/dired/picker existed at audit. Now `C-x C-f` opens a known path and `C-x d` / `C-x C-j` browse (flat listing, `dired` mode keymap); `M-.`/`M-?`/`C-c o` still bound but advertised nowhere and server-gated; no workspace-symbol command; `pmacs.index.*` has no UI |
| 8 | Open terminal | **Works** | Full PTY with scrollback + modeline segment, bound to `C-c t` and configurable through three registered settings (`terminal.default-profile`, `terminal.scrollback-rows`, `terminal.escape-key`) plus named `pmacs.terminal.profiles` (PR #173), and searchable through `M-x terminal.copy-mode` / `C-c C-t`, which materializes the retained scrollback into an ordinary read-only buffer (Stage 2). Named limitations: `C-c t` is unreachable from *inside* a terminal window, where `C-c` is consumed as the escape — `M-x terminal` still works there; and there is still **no close/kill command**, which is the remaining half of this step's discoverability gap. *Was broken outright on the GPU frontend until the double terminal-layout sync was fixed: the child took a `SIGWINCH` storm at tick cadence, so typing into it was impossible while output still flowed.* | | 8 | Open terminal | **Works** | Full PTY with scrollback + modeline segment, bound to `C-c t` and configurable through three registered settings (`terminal.default-profile`, `terminal.scrollback-rows`, `terminal.escape-key`) plus named `pmacs.terminal.profiles` (PR #173), and searchable through `M-x terminal.copy-mode` / `C-c C-t`, which materializes the retained scrollback into an ordinary read-only buffer (Stage 2). Named limitations: `C-c t` is unreachable from *inside* a terminal window, where `C-c` is consumed as the escape — `M-x terminal` still works there; and there is still **no close/kill command**, which is the remaining half of this step's discoverability gap. *Was broken outright on the GPU frontend until the double terminal-layout sync was fixed: the child took a `SIGWINCH` storm at tick cadence, so typing into it was impossible while output still flowed.* |
| 9 | Build / test | **Works** | Journey Stage 1b-1 (#203): `C-c c` runs `compile.run`, and the first prompt is prefilled from the detected project kind (`pmacs.compile.defaults`, seeded `rust = "cargo build"`, extensible from `init.lua`) via `ProjectKind::Rust`**not** `Cargo`, see §24. The prompt **captures** its directory rather than re-resolving at accept time, so the command it offers and the directory it runs in cannot drift while the minibuffer waits. Still defaults cwd to the detected project root and parses Rust `-->` errors. Named limitation: after `pmacs <dir>` the active buffer is dired's and pathless, so the cwd falls back to the process cwd — §8's execution-location model owns that, and the degradation stays coherent (no suggestion is offered for a directory with no detected Cargo project) | | 9 | Build / test | **Works** | Journey Stage 1b-1 (#203): `C-c c` runs `compile.run`, and the first prompt is prefilled from the detected project kind (`pmacs.compile.defaults`, seeded `rust = "cargo build"`, extensible from `init.lua`) via `ProjectKind::Rust`**not** `Cargo`, see §24. The prompt **captures** its directory rather than re-resolving at accept time, so the command it offers and the directory it runs in cannot drift while the minibuffer waits. Still defaults cwd to the detected project root and parses Rust `-->` errors. Named limitation: after `pmacs <dir>` the active buffer is dired's and pathless, so the cwd falls back to the process cwd — §8's execution-location model owns that, and the degradation stays coherent (no suggestion is offered for a directory with no detected Cargo project) |

View File

@ -255,75 +255,27 @@ If it does not, stop and repair the remote/fetch configuration.
never been enforced. Any CI job that compiles the `crdt` targets has to never been enforced. Any CI job that compiles the `crdt` targets has to
fix them first or it will be red on arrival. fix them first or it will be red on arrival.
## Journey lane (P1) — 1a, 1b-1, 1b-2 MERGED; 1b-3 PR OPEN ## Journey lane (P1) — 1a, 1b-1, 1b-2 MERGED; 1b-3 PR #205 OPEN
**Rewritten, not removed.** Rule 4 removes a lane when its ARC is done; **Rewritten, not removed.** Rule 4 removes a lane when its ARC is done;
the journey arc is not — 1b-3 is the last stage of the 1b split and is the journey arc is not — 1b-3 is the last stage of the 1b split and is
still open. Stage 1a (#182/#183) and Stage 1b-1 (#203) are on `main` and still open. Stages 1a (#182/#183), 1b-1 (#203) and **1b-2 (#204)** are
their durable facts are in `docs/agent-handoff.md` §1, which is rule 4's all on `main` and their durable facts are in `docs/agent-handoff.md` §1,
precondition satisfied rather than deferred. which is rule 4's precondition satisfied rather than deferred — so their
per-stage blocks are gone from here rather than left to rot as
"PR OPEN".
**#203's merge obligation is DISCHARGED**: `COHERENCE.md` §2's step-9 **#203's merge obligation is DISCHARGED** on this branch: `COHERENCE.md`
row now reads **Works**, §2's keybinding-inversion paragraph records all §2's step-9 row reads **Works**, §2's keybinding-inversion paragraph
three examples answered (the quote itself deliberately unchanged), §20 records all three examples answered (the quote itself deliberately
Priority 1 and its arc list say "landed", and the handoff bullet says unchanged), §20 Priority 1 and its arc list say "landed", and the
LANDED. That flip rides *this* branch rather than a standalone docs PR, handoff bullet says LANDED. **#204's is discharged too**: §2's step-6
because #204 already touches all three files and a separate PR would row names it as landed and stays **Partial** for a reason that landing
re-conflict on every merge. did not touch — a server that starts and then *crashes* is still
unsurfaced. Both rode this branch rather than standalone docs PRs,
which would have re-conflicted on every merge.
- **Branch `journey-stage1b2-lsp-guidance`**, worktree ### Stage 1b-3 — IMPLEMENTED, PR #205 open
`../pmacs-journey-1b2`, based on `githubsucks/main` @ `fbcf235`,
**integrated with `main` @ `1f290d5` (#203)**.
`docs/journey-stage1b2-lsp-guidance-framing.md` revision 4, three
review rounds closed (round 1: two blocking, three major, one minor;
round 2: two blocking, two cleanups; round 3: one blocking; all
accepted). **Implemented; PR #204 open.**
- **What it is.** `COHERENCE.md` §1.2's canonical silence, journey step
6: a preconfigured-but-missing language server now reports with
guidance, marks the modeline `LSP:!`, and appears in `M-x lsp.status`.
- **Half of it was already built and unwired.**
`LspManager::status_buffer_text()` and `last_error()` have existed
since M4.8, exposed to Lua and tested, with **no production caller**
and no `*lsp*` buffer, while several `src/lsp.rs` and `src/project.rs`
doc comments refer to that buffer as though it existed.
- **The reporting shape was already adopted twice in `lsp.lua` itself**
(root resolvers, notification subscribers). The canonical case was
silent because nobody had converted it — this finishes an adoption.
- **`COHERENCE.md` §1.2's frequency note was wrong, and it decided the
design.** `LspManager::spawn` returns early *before* both
`status_tracker.ensure` and `clients.insert`, so a failed spawn leaves
**no record**, `pmacs.lsp.list()` cannot see it, and the affinity loop
re-spawns: the real rate is **once per file open**, not once per
project root. Hence **memoize the report, not the failure**.
- **The affinity key is `(language, key_uri)`, and `key_uri` is nil for
markerless files**, which deliberately share one server per language.
Lua cannot index by nil (`t[nil]` raises), so one encoding function
serves both tables with a `u`/`n` discriminator no URI can collide
with.
- **Three tables, three lifetimes**, plus a buffer-keyed projection for
the modeline — that provider runs for every window on every paint, so
deriving an affinity key inside it would invoke user root resolvers
during painting. **A success sweeps every projection sharing the key**,
and the projection has its own `pmacs.buffer.on_removed` teardown
because nothing existing reaches it (`attachments_under` iterates
`attachments`, and a failed buffer has none by construction).
- **ON MERGE of #204, flip the step-6 grade.** §2's step-6 row stays
**Partial** while the PR is open, per §25's landed-evidence rule, and
says so in the row.
- **Stage 1b-3 (welcome buffer, step 4) is unframed** — the last of the
1b split.
- Recovery from a clean checkout — **the two-argument form does not
work** (`git worktree add <path> <remote-only-branch>` fails with
`fatal: invalid reference`):
```sh
git fetch githubsucks
git worktree add ../pmacs-journey-1b2 \
-b journey-stage1b2-lsp-guidance \
githubsucks/journey-stage1b2-lsp-guidance
```
## Journey Stage 1b-3 (P1) — IMPLEMENTED, PR OPEN
- **Branch `journey-stage1b3-welcome`**, worktree `../pmacs-journey-1b3`, - **Branch `journey-stage1b3-welcome`**, worktree `../pmacs-journey-1b3`,
based on `githubsucks/main` @ `1f290d5`, **integrated with `main` @ based on `githubsucks/main` @ `1f290d5`, **integrated with `main` @
@ -508,7 +460,7 @@ compatible.
githubsucks/test-ambient-config-isolation githubsucks/test-ambient-config-isolation
``` ```
## Reap-ledger silent failures — IMPLEMENTED, PR OPEN ## Reap-ledger silent failures — MERGED (#202); kept for its parked follow-ons
- **Branch `reap-ledger-silent-failures`**, worktree - **Branch `reap-ledger-silent-failures`**, worktree
`../pmacs-reap-ledger`, based on `githubsucks/main` @ `22df6ab`. `../pmacs-reap-ledger`, based on `githubsucks/main` @ `22df6ab`.

View File

@ -332,12 +332,13 @@ commands, read `docs/active-work.md` immediately after this file.
because a selected candidate shadows typed text while `accept()` because a selected candidate shadows typed text while `accept()`
does `session.take()`, the pin asserts does `session.take()`, the pin asserts
`pmacs.minibuffer.selected() == "help"` **before** RET. `pmacs.minibuffer.selected() == "help"` **before** RET.
- **Journey arc (P1) — Stage 1b-2 IMPLEMENTED, PR open** - **Journey arc (P1) — Stage 1b-2 LANDED (#204)**
(`docs/journey-stage1b2-lsp-guidance-framing.md`, rev 4, three review (`docs/journey-stage1b2-lsp-guidance-framing.md`, rev 4, three review
rounds). `COHERENCE.md` §1.2's canonical silence: a preconfigured rounds). `COHERENCE.md` §1.2's canonical silence: a preconfigured
language server that is not installed now reports with guidance, marks language server that is not installed now reports with guidance, marks
the modeline `LSP:!`, and appears in `M-x lsp.status`. Per §25 the the modeline `LSP:!`, and appears in `M-x lsp.status`. §2's step-6 row
step-6 grade flips only on merge. **stays Partial** for a reason that landing did not touch: a server
that starts and then *crashes* is still unsurfaced.
- **`status_buffer_text()` had existed since M4.8, exposed to Lua and - **`status_buffer_text()` had existed since M4.8, exposed to Lua and
tested, with no production caller and no `*lsp*` buffer** — several tested, with no production caller and no `*lsp*` buffer** — several
`src/lsp.rs` and `src/project.rs` doc comments referred to that `src/lsp.rs` and `src/project.rs` doc comments referred to that