docs: record dired Stage 1 (PR #165) and what it falsified
docs/dired-framing.md rev 6: §0 gains the Stage 1 implementation notes
(S1-1..S1-9) -- the normalizer is exposed rather than mirrored (so B2 is
false by one small binding, in the direction Q#DR2 preferred); R2-3's
dedication claim is falsified by the display policy; acceptance 3c
cannot pin the descent routing and now says so; dired is the first
builtin to bind a mode-scoped key, which one pre-existing lib test
assumed impossible; `C-x d` takes no completion source on purpose;
ownership is the handle table alone; the mark column ships blank; a
symlinked directory needs a probe; and interactive origin does not
survive an await.
COHERENCE.md, per its §25 (an audited claim this PR changes updates
here, riding the PR): §1.1's interactive-file-opening fact, §2's journey
step 7, §4's beginner-level `files`, §14's tree bullet (Stage 1 landed a
flat listing and did NOT invent a tree convention), and §15's Priority 1
list. Step 3 stays **Missing at the CLI** with the mechanism spelled
out: `pmacs .` still exits 1, and this arc deliberately does not claim
the CLI path -- it supplies the buffer a directory should resolve to.
docs/active-work.md: the dired lane rewritten for Stage 1, including why
the branch is a fresh cut rather than a rebase of `dired`, the durable
substrate facts, the bite results (one VACUOUS, recorded rather than
relabelled), and the verification. Its canonical-base line was four
merges stale and now names 8c86d34.
docs/agent-handoff.md: one forward pointer only. The handoff describes
merged state, so it absorbs the substance when this merges.
This commit is contained in:
parent
e7fa9e9720
commit
8b685dc127
37
COHERENCE.md
37
COHERENCE.md
|
|
@ -119,10 +119,10 @@ detailed in §1.1–§1.3: **substrate without surface**, **the silence
|
|||
asymmetry**, and **per-arc coherence debt**.
|
||||
|
||||
Coherence-shaped work already in flight at audit time: find-file /
|
||||
dired Stage 0 (`C-x C-f`, PR #162, `docs/dired-framing.md`), bottom
|
||||
panel Stage 1 (merged #155), multi-root LSP affinity (branch
|
||||
`lsp-multi-root-affinity`), the config registry foundation (merged
|
||||
#127).
|
||||
dired Stage 0 (`C-x C-f`, merged #162, `docs/dired-framing.md`) and its
|
||||
Stage 1 directory view (PR #165), bottom panel Stage 1 (merged #155),
|
||||
multi-root LSP affinity (branch `lsp-multi-root-affinity`), the config
|
||||
registry foundation (merged #127).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -192,9 +192,13 @@ working, unreachable capability:
|
|||
is Lua-bound; no builtin command opens `*lsp*` (§2, §9).
|
||||
- **Interactive file opening.** `pmacs.buffer.find_or_open`
|
||||
(`src/lua_bindings/mod.rs:3103`) had no interactive caller at audit
|
||||
time; a complete 1,384-line dired exists as a frozen test fixture
|
||||
(`tests/fixtures/pmacs-dired/init.lua`). Being fixed now: dired Stage
|
||||
0 (PR #162).
|
||||
time; a complete 1,384-line dired existed only as a frozen test
|
||||
fixture (`tests/fixtures/pmacs-dired/init.lua`). **Fixed:** dired
|
||||
Stage 0 opens a path (`C-x C-f`, merged #162) and Stage 1 ships the
|
||||
browsing view as a builtin (`C-x d` / `C-x C-j`, PR #165). The fixture
|
||||
stays frozen — its `install_local` + `require` routing *is* the M8
|
||||
package-universality proof (Q#DR1) — and shrinking it is scheduled
|
||||
after Stage 3.
|
||||
|
||||
The strategic consequence: **most coherence gaps in pmacs are doors,
|
||||
not engines** — deliberately deferred surface, not design error. That is
|
||||
|
|
@ -331,11 +335,11 @@ Full verdict table:
|
|||
|---|---|---|---|
|
||||
| 1 | Install | **Partial** | Source build only: `cargo build --release --workspace --features pmacs/crdt` (`README.md`). No binaries, no packaging. Runtime deps (`/bin/sh`, git, tar, coreutils) documented, never checked at runtime |
|
||||
| 2 | Launch unconfigured | **Works** | `EditorState::new()` → empty `*scratch*`; missing config is not an error (`src/config.rs:7-9`); recentf/saveplace/autosave default-on |
|
||||
| 3 | Open real project | **Missing** | `pmacs .` exits 1 (above). No directory handling anywhere |
|
||||
| 3 | Open real project | **Missing at the CLI** | `pmacs .` still exits 1 (above): `load_file` does `File::open` (which succeeds on a directory) then `read_to_end` → EISDIR, which is not `NotFound`, so `resolve_target_buffer`'s create-a-`[new file]` arm never fires. Dired Stage 1 (PR #165) supplies the buffer a directory should resolve *to*; routing `pmacs .` into it is Journey Stage 1's work, which must not invent a second directory surface |
|
||||
| 4 | Understand interface | **Partial** | Mode line gives name/modified/L:C/scroll + mode/LSP/terminal segments; but no welcome text (`EditorCore::new` sets `status: String::new()`), no cheat sheet, and `C-h` deletes a word (§18) |
|
||||
| 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:44-52`) — but a missing binary fails silently (§1.2) and highlighting masks it. No LSP status command exists to diagnose |
|
||||
| 7 | Find symbol / file | **File: missing → in flight (PR #162). Symbol: works but undiscoverable** | No find-file/dired/picker existed at audit; `M-.`/`M-?`/`C-c o` 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 PR #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 but undiscoverable** | Full PTY with scrollback + modeline segment — reachable only as `M-x terminal`, no keybinding |
|
||||
| 9 | Build / test | **Partial** | `M-x compile.run` works, defaults cwd to detected project root, parses Rust `-->` errors — but no keybinding, an **empty first prompt** (`initial = last and last.cmdline or ""`, `builtin/runtime/compile.lua:1134-1138`), and no `cargo build`/`cargo test` suggestion despite `ProjectKind::Cargo` existing (`src/project.rs:77`) |
|
||||
| 10 | Inspect error | **Partial (good once reached)** | `E:n W:n` modeline counts, underlines, `M-g n/p` + ``C-x ` `` walking a unified compile/grep/diag source, message echo, `RET` visits. Gated entirely on step 6 or 9 succeeding first |
|
||||
|
|
@ -428,7 +432,8 @@ level is the one missing. Audited level-by-level:
|
|||
**Beginner** (should see: files, buffers, search, diagnostics, terminal,
|
||||
build actions, menus, missing-tool guidance):
|
||||
|
||||
- files ✗ (no find-file at audit; PR #162 in flight) · buffers ✓ (`C-x
|
||||
- files ✓ since #162 / PR #165 (`C-x C-f` opens a path, `C-x d` browses;
|
||||
neither is advertised anywhere but the keymap) · buffers ✓ (`C-x
|
||||
b`, `*buffer-list*`) · search ✓ (`C-s`/`C-r`/`C-M-s`; project.search
|
||||
is M-x-only) · diagnostics ✓ once a server runs · terminal ✓ but
|
||||
M-x-only · build ✓ but M-x-only with empty prompt · menus △
|
||||
|
|
@ -1139,7 +1144,11 @@ Primitive-by-primitive against the list above:
|
|||
hierarchy, package dependency graph, worker trees, git status) will
|
||||
each need it; building it once *before* dired's directory view and
|
||||
the workers tree harden their own conventions is exactly this
|
||||
section's point.
|
||||
section's point. Dired Stage 1 (PR #165) landed **without** inventing
|
||||
one: its listing is flat (Emacs parity), and the recursive
|
||||
in-buffer case — `i` insert-subdirectory — is a named deferral in
|
||||
`docs/dired-framing.md` §13, which is where a shared tree primitive
|
||||
would land.
|
||||
- **Structured table / inspector / diff view** ✗ — none. (`describe.*`
|
||||
tables are the inspector's data model without a view; the
|
||||
wire-declared `ResourceOffer` family was reserved for diff/blame
|
||||
|
|
@ -1346,8 +1355,10 @@ missing runtime entity — a real arc).
|
|||
|
||||
Establish the end-to-end workflow; treat regressions as release
|
||||
blockers. **State: broken at step 3 (§2). Mostly wiring, and unusually
|
||||
cheap:** directory-argument handling; a find-file surface (in flight,
|
||||
PR #162); surfacing the LSP spawn failure with guidance (§1.2); a
|
||||
cheap:** directory-argument handling (the remaining half of step 3 —
|
||||
dired Stage 1 landed the buffer it should resolve to); a find-file
|
||||
surface (**done**: #162 open-by-path, PR #165 browsing); surfacing the
|
||||
LSP spawn failure with guidance (§1.2); a
|
||||
compile keybinding + `cargo build`/`test` default from the existing
|
||||
`ProjectKind::Cargo`; a terminal keybinding; a welcome buffer. The
|
||||
journey acceptance suite (§19) is the ratchet that keeps it fixed.
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ backlog.
|
|||
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` @ `0dd16a5` (GPU initial-target #148 atop folding Stage 2
|
||||
landed-doc refresh #150, folding Stage 2 #149, the ledger refresh #147, web
|
||||
grammars HTML+CSS #146, and the LaTeX Stage 1 #144 / inline-math framing
|
||||
#145 pair; protocol v20).
|
||||
`githubsucks/main` @ `8c86d34` (the dired framing #164 atop find-file
|
||||
#162, COHERENCE.md #163, Lean 4 Stage 1 #160, the minimap blank-slab fix
|
||||
#159, bottom-panel Stage 1 #155, the inline-math re-scout #154, the vterm
|
||||
PTY-flake fix #153, and the GPU initial-target doc refresh #152; protocol
|
||||
v20).
|
||||
- On the transfer source, `origin/main` named a release mirror at
|
||||
`d3fa632` and lagged badly. On the current destination, `origin` names
|
||||
the canonical URL. This difference is why all recovery begins by
|
||||
|
|
@ -51,7 +52,7 @@ git worktree list
|
|||
git status --short --branch
|
||||
```
|
||||
|
||||
The `git log` command must expose `0dd16a5` or a newer intentional main.
|
||||
The `git log` command must expose `8c86d34` or a newer intentional main.
|
||||
If it does not, stop and repair the remote/fetch configuration.
|
||||
|
||||
## Lean 4 lane (Arc 8) — Stage 1 IN REVIEW (PR #160)
|
||||
|
|
@ -124,44 +125,108 @@ If it does not, stop and repair the remote/fetch configuration.
|
|||
or markerless scratch files fragment into one server per directory for
|
||||
every language.
|
||||
|
||||
## Dired lane — framing APPROVED; Stage 0 MERGED, Stage 1 next
|
||||
## Dired lane — Stage 0 MERGED; Stage 1 IN REVIEW (PR #165)
|
||||
|
||||
- Approved framing: `docs/dired-framing.md` (revision 5), landing as its
|
||||
own docs PR off `githubsucks/main` @ `2af1ab3`, branch
|
||||
`githubsucks/dired-framing`, worktree `../pmacs-dired-framing`. The
|
||||
repo's `-framing`-branch convention (`vterm-framing`,
|
||||
`gpu-initial-target-framing`, `tab-width-parity-framing`).
|
||||
- Approved framing: `docs/dired-framing.md` **revision 6** — rev 5 is the
|
||||
approved text (merged as its own docs PR #164), rev 6 adds §0's Stage 1
|
||||
implementation notes (S1-1…S1-9). Stages 2 (marks and operations) and 3
|
||||
(wdired) each get their own detailed framing after the prior stage lands.
|
||||
- **Stage 0 (`C-x C-f` find-file) MERGED as #162** (`main` @ `2af1ab3`,
|
||||
2026-07-25, one review round, 12/12 CI green). Durable facts moved to
|
||||
`docs/agent-handoff.md` §1 per rule 3 below.
|
||||
- **Stage 1 (the dired view) is next and unstarted.** Branch `dired`
|
||||
(worktree `../pmacs-dired-arc`) carries the framing commits only and is
|
||||
based on the now-superseded `0827dd1`; **rebase it onto the `main`
|
||||
resulting from the framing PR before implementing**, or cut a fresh
|
||||
branch — its framing commits become redundant once the docs PR lands.
|
||||
- Stage 1's scope, from the framing §10: `builtin/runtime/dired.lua`; the
|
||||
`dired` major mode + mode keymap; buffer-per-directory with lexical
|
||||
canonicalization and the ownership check; read-only intercept +
|
||||
`set_round_trip_input`; visit routing through `window.display_file`;
|
||||
parent/sort/revert/quit; `C-x d` (with the `display` opt) / `C-x C-j`;
|
||||
cursor preservation by basename; the `dired.kill-when-opening` config
|
||||
key; **and the tolerant `read_dir` opt** — the only Rust in the stage.
|
||||
- The one Rust change is load-bearing and is why Stage 1 is not
|
||||
pure-Lua: `read_dir_blocking` (`src/fs.rs:201`) fails the **entire
|
||||
listing** on any of five per-entry conditions, and the tolerant wrapper
|
||||
its own module doc delegates to package authors **cannot be written in
|
||||
Lua** — the primitive returns one error and no partial vec.
|
||||
- Coherence (framing §0.5, required since #163): serves `COHERENCE.md`
|
||||
§20 Priority 1, which names this work explicitly; journey steps 7 and
|
||||
(partially) 3; **adds no interaction island** — keys are a mode-scoped
|
||||
keymap, and wdired is a mode swap; adopts `pmacs.config` for
|
||||
`dired.kill-when-opening`; inherits §9's worker-attribution gap for its
|
||||
`read_dir` jobs without worsening it.
|
||||
- **Stage 1 branch: `githubsucks/dired-stage1`**, worktree
|
||||
`../pmacs-dired-stage1`, based on `githubsucks/main` @ `8c86d34` (the
|
||||
framing merge #164). **A fresh cut, not a rebase:** the older `dired`
|
||||
branch (`ffdd642`, worktree `../pmacs-dired-arc`) was based on the
|
||||
superseded `0827dd1` and carried only the framing content #164 already
|
||||
put on `main`, so merging it would have reconciled two histories of one
|
||||
document. It is left untouched and carries nothing unmerged.
|
||||
- **Stage 1 implemented; no wire change (protocol stays v20).** What
|
||||
landed on the branch:
|
||||
- `builtin/runtime/dired.lua`: one buffer per directory named
|
||||
`*dired:<canonical path>*` with the handle-table ownership check;
|
||||
read-only intercept + `set_round_trip_input`; the `dired` major mode
|
||||
and its mode-scoped keymap (`RET`/`f`, `^`, `n`/`p`, `g`, `q`, `s`);
|
||||
basename cursor re-seating across every wholesale repaint;
|
||||
`display_file` for file visits and same-window reuse for directory
|
||||
descent; `C-x d` / `C-x C-j`; the `dired.kill-when-opening` setting.
|
||||
Loaded after `window.lua`.
|
||||
- `src/fs.rs`: `ReadDirTolerance`, `FsDirEntryError`, `FsDirListing`,
|
||||
and one walk that either fails on a per-entry condition or records it
|
||||
(Q#DR6). `src/async_runtime.rs` carries the listing in
|
||||
`ReplyKind::ReadDir` / `JobResult::ReadDir`; `src/lua_bindings/mod.rs`
|
||||
keys the Lua result **shape** on `errors.is_some()`, so the bare array
|
||||
the frozen M8.2 fixture consumes with `ipairs` is untouched;
|
||||
`builtin/runtime/fs.lua` validates read-op opts and **rejects unknown
|
||||
keys** (a typo'd `tolerant` used to degrade silently to fatal).
|
||||
- `src/editor_core.rs` + `src/lua_bindings/mod.rs`:
|
||||
`normalize_buffer_path` is `pub` and exposed as
|
||||
`pmacs.path.canonicalize` — Q#DR2's preferred end state, so no Lua
|
||||
mirror exists and Stage 2 owes no mirror removal. This makes B2
|
||||
("tolerant `read_dir` is the only Rust change") false by one small
|
||||
binding, deliberately.
|
||||
- `tests/dired_acceptance.rs`: 22 tests over framing items 1–16,
|
||||
dispatch-driven; item 17 is the m8_1/m8_2/m8_3 additivity gate.
|
||||
- **The framing claim the substrate falsified (S1-2):** R2-3 expected a
|
||||
dedicated dired panel to carry its dedication across a descent.
|
||||
`display_buffer` never replaces the buffer in a slot dedicated to
|
||||
another one — it discards every side-specific parameter and falls back
|
||||
to the document window (Q#BP3 2.iii), and the exact-window arm errors.
|
||||
Dired does not unpin the user's panel; both arms are pinned.
|
||||
- **The vacuity the bites found (S1-3):** acceptance 3c cannot pin the
|
||||
descent *routing*. Dired holds focus in its own panel, so a raw
|
||||
`switch_buffer` lands in the same window and every 3c assertion holds
|
||||
either way. Dedication is the only discriminator, so the
|
||||
dedicated-panel test is the real pin — and the vacuity is documented at
|
||||
the assertion rather than relabelled.
|
||||
- **The pre-existing test dired's first mode-scoped binding broke
|
||||
(S1-4):** `describe_key_identifies_every_default_binding` asserted every
|
||||
binding in the stack resolves through `describe.key` context-free, which
|
||||
held only while the modes table was empty. It now sets the effective
|
||||
context per binding and explicitly *clears* the mode for global ones,
|
||||
because a leaked mode legitimately shadows a global chord of the same
|
||||
name (dired's `RET` shadows `edit.newline-and-indent`).
|
||||
- Durable substrate facts, independent of this arc:
|
||||
- `pmacs.buffer.kill` (not `remove`) redirects windows off a doomed
|
||||
buffer before removal, so `kill-when-opening` kills **after** the
|
||||
replacement is displayed.
|
||||
- Interactive origin does **not** survive an await: work resumed in
|
||||
`tick_async` sees no `InteractiveCommandOrigin`, so `pmacs.window.*`
|
||||
acts for the *ambient* active frontend (S1-9).
|
||||
- Kinds are lstat-based in both `read_dir` and `stat`, so nothing in an
|
||||
entry says whether a symlink points at a directory; `RET` probes by
|
||||
trying to list it (S1-8).
|
||||
- A path-backed buffer's *name* is its full path, not its basename —
|
||||
worth knowing before writing any name assertion.
|
||||
- `C-x d` takes **no** completion source on purpose (S1-5): with one,
|
||||
RET on an empty field opens whatever sorts first, and
|
||||
RET-on-where-you-are is the gesture the binding exists for. The field
|
||||
is prefilled instead.
|
||||
- **Bite verification:** 15 claims, each mutated in place and required to
|
||||
fail the test that names it. `dired.lua` is new, so `scripts/bite`'s
|
||||
file swap does not apply; every mutation was applied and reverted with
|
||||
`git checkout --`. One came back VACUOUS and is recorded above.
|
||||
- Verification on this branch: `cargo fmt --check` clean; strict workspace
|
||||
Clippy clean; 1,829 default + 2,006 CRDT library tests; dired acceptance
|
||||
22 default + 22 CRDT; m8_1 10 / m8_2 15 / m8_3 32 unchanged; M4 121;
|
||||
required GPU 155; **isolated-`XDG_CONFIG_HOME` workspace sweep 3,186
|
||||
passed across 92 suites, zero failures**; `git diff --check` clean. The
|
||||
sweep needs the isolated config for the reason recorded in the
|
||||
bottom-panel lane below.
|
||||
- Coherence (framing §0.5, required since #163): serves `COHERENCE.md` §20
|
||||
Priority 1, which names this work explicitly; journey step 7's file half
|
||||
goes from no surface to a surface; **adds no interaction island** — keys
|
||||
are a mode-scoped keymap, and wdired will be a mode swap; adopts
|
||||
`pmacs.config` for `dired.kill-when-opening`; inherits §9's
|
||||
worker-attribution gap for its `read_dir` jobs without worsening it. The
|
||||
audited claims this changes are updated in `COHERENCE.md` itself, per its
|
||||
§25.
|
||||
- **Boundary with the Journey Stage 1 arc** (`COHERENCE.md` §20 arc-cut
|
||||
1): CLI directory-argument handling (`pmacs .` exits 1) belongs there,
|
||||
not here. The two meet at `resolve_target_buffer`; dired supplies the
|
||||
buffer a directory should resolve *to*, and `pmacs .` should route into
|
||||
it rather than growing a second directory surface.
|
||||
not here — Stage 1 does **not** fix it. The two meet at
|
||||
`resolve_target_buffer`; dired supplies the buffer a directory should
|
||||
resolve *to*, and `pmacs .` should route into it rather than growing a
|
||||
second directory surface.
|
||||
|
||||
## Bottom-panel lane (window placement + side windows) — Stage 1 IN REVIEW
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,11 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
against an open buffer yet fails to load one that is not open —
|
||||
find-file expands the tilde Lua-side. Loading through the normalized
|
||||
path is a named deferral.
|
||||
- **Stage 1 (the directory view) is IN REVIEW as PR #165** — the
|
||||
builtin `dired.lua`, the per-entry-tolerant `read_dir` opt, and
|
||||
`pmacs.path.canonicalize`. Its branch state, substrate facts, and
|
||||
verification live in `docs/active-work.md`; this section absorbs them
|
||||
when it merges.
|
||||
- **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
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
# Dired — framing
|
||||
|
||||
**Revision 5 — 2026-07-25. Status: APPROVED; Stage 0 MERGED as #162.**
|
||||
**Revision 6 — 2026-07-25. Status: APPROVED; Stage 0 MERGED as #162;
|
||||
Stage 1 IN REVIEW as PR #165.**
|
||||
Rev 1 passed a ground-truth review; rev 2 fixed round 1's seven findings;
|
||||
rev 3 fixed round 2's six and was approved; rev 4 recorded what Stage 0's
|
||||
implementation falsified in the approved text (§0); rev 5 adds the
|
||||
**coherence impact** statement now required of every framing
|
||||
(`CLAUDE.md`, `COHERENCE.md` §20) — see §0.5. Deliberately
|
||||
(`CLAUDE.md`, `COHERENCE.md` §20) — see §0.5; rev 6 records what Stage
|
||||
1's implementation falsified (§0, S1-1…S1-9). Deliberately
|
||||
unnumbered: the roadmap's Arc 8 is GPU
|
||||
structural parity but `docs/lean4-mode-framing.md` also claims Arc 8, so
|
||||
the arc space is already forked in uncommitted work. (Rev 2 also cited
|
||||
|
|
@ -203,6 +205,94 @@ the correction belongs here rather than only in the code.
|
|||
same normalize-before-lookup family as Q#DR5's `apply_resource_op`
|
||||
correction.
|
||||
|
||||
### Stage 1 implementation notes (rev 5 → rev 6)
|
||||
|
||||
Implementing Stage 1 (PR #165) falsified four things the approved text
|
||||
asserted and settled five it left open. Recorded here rather than only
|
||||
in the code, per the rev-4 precedent.
|
||||
|
||||
- **S1-1. The normalizer is EXPOSED, not mirrored — so B2 is partly
|
||||
false, in the direction Q#DR2 preferred.** Q#DR2 made the mirror
|
||||
conditional (`Stage 1 may still mirror if exposure turns out to drag
|
||||
in EditorCore borrow plumbing it does not otherwise need`).
|
||||
`normalize_buffer_path` is a **free function** (`editor_core.rs`), so
|
||||
exposure drags in nothing: it is now `pub` and reachable as
|
||||
`pmacs.path.canonicalize`. Consequences, all deliberate: B2 ("tolerant
|
||||
`read_dir` is the only Rust change Stage 1 needs") is false by one
|
||||
small binding; acceptance 3b degenerates to the round-trip form the
|
||||
framing described; and the Stage 2 mirror-removal follow-up **is not
|
||||
owed** — there is no second canonical form to remove. The parity
|
||||
acceptance is still carried, now as "the Lua binding and the Rust
|
||||
function agree over one shared edge list", which is exactly the claim
|
||||
a future re-mirroring would break.
|
||||
- **S1-2. R2-3's dedication claim is falsified by the substrate.** It
|
||||
read "a dedicated dired panel stays dedicated across descent and the
|
||||
new dired buffer inherits it". `display_buffer` never replaces the
|
||||
buffer in a slot dedicated to another one: it discards every
|
||||
side-specific parameter and falls back to the document window (Q#BP3
|
||||
2.iii), and the exact-window arm errors outright. Dired therefore does
|
||||
**not** try to unpin the user's panel — which is also what Emacs's
|
||||
`display-buffer` does with a dedicated window. Acceptance 3c is split:
|
||||
a non-dedicated panel keeps the descent, and a dedicated one keeps its
|
||||
buffer *and* its pin while the new directory appears in the document
|
||||
window.
|
||||
- **S1-3. Acceptance 3c cannot pin the descent ROUTING, and the test now
|
||||
says so.** Dired holds the focus in its own panel, so a raw
|
||||
`switch_buffer` lands in that same window and every 3c assertion holds
|
||||
either way — the mutation is *vacuous* against it. Dedication is the
|
||||
only thing that distinguishes `display { side = … }` from the raw
|
||||
switch, so the dedicated-panel test is the discriminating pin. Found
|
||||
by running the bite rather than by reading the test; the vacuity is
|
||||
documented at the assertion instead of being left to be believed.
|
||||
- **S1-4. Dired is the first builtin to bind a mode-scoped key, and one
|
||||
pre-existing lib test assumed none existed.**
|
||||
`describe_key_identifies_every_default_binding` iterated *every*
|
||||
binding in the stack and asserted `pmacs.describe.key` resolves it
|
||||
context-free, which held only while the modes table was empty. It now
|
||||
sets the effective context per binding — and explicitly *clears* the
|
||||
mode for a global one, because a mode left over from a previous
|
||||
iteration legitimately shadows a global chord of the same name
|
||||
(dired's `RET` shadows `edit.newline-and-indent`, which is the point
|
||||
of the mode).
|
||||
- **S1-5. `C-x d` deliberately takes NO completion source.** It is the
|
||||
direct consequence of S0-1/S0-4: with a `files` source, RET on an
|
||||
empty field opens whatever sorts first (the minibuffer selects
|
||||
candidate 0 whenever the list is non-empty, and a selected candidate
|
||||
shadows typed text), and RET-on-the-directory-you-are-in is exactly
|
||||
the gesture `C-x d` exists for. The field is **prefilled** with the
|
||||
current directory instead — Emacs's own shape here — and free text
|
||||
always reaches `on_accept` because `CompletionSource::None` bypasses
|
||||
candidate resolution entirely. Directory-name completion is what dired
|
||||
itself replaces.
|
||||
- **S1-6. Ownership is the handle table ALONE**, narrower than Q#DR2's
|
||||
"present in dired's handle table, or `major_mode(buf) == "dired"`". A
|
||||
foreign buffer that carries the mode *is* the case the check exists to
|
||||
refuse, and a builtin's handle table cannot be lost the way a
|
||||
reloadable package's can. Acceptance 4 sets the mode on the foreign
|
||||
buffer to pin the stronger reading.
|
||||
- **S1-7. The mark column ships in Stage 1, rendered blank.** Q#DR4 is a
|
||||
Stage 2 decision, but reserving the two columns now means Stage 2 does
|
||||
not move every offset and Stage 3's column-classifying intercept can
|
||||
be written against constants that did not shift under it. The
|
||||
constants are computed from the widths (the fixture hardcoded
|
||||
`NAME_START = 39` and paid for it in every wdired test) and exported
|
||||
as `pmacs.dired._layout` so acceptance cannot drift from them.
|
||||
- **S1-8. A symlinked directory needs a probe, because kinds are
|
||||
lstat-based.** Both `read_dir` and `stat` report a link as
|
||||
`"symlink"`, so nothing in the entry says whether it points at a
|
||||
directory. `RET` on a symlink therefore *tries* to list the target
|
||||
(one extra syscall, on symlink lines only) and descends if that
|
||||
succeeds, else visits it as a file. Q#DR10 specified only the
|
||||
dir/file arms; this is the third.
|
||||
- **S1-9. Interactive origin does not survive the await.** Every listing
|
||||
is worker-dispatched, so the work after the first `:await()` resumes
|
||||
inside `tick_async`, where `InteractiveCommandOrigin` is empty and
|
||||
`pmacs.window.*` falls back to the **ambient** active frontend. Single
|
||||
frontend: correct. Multi-frontend: a dired opened from peer B while A
|
||||
is ambient would display for A. Not fixable from Lua (the display
|
||||
surface takes no frontend argument) and named here rather than
|
||||
discovered later.
|
||||
|
||||
## 0.5. Coherence impact (`COHERENCE.md` §20)
|
||||
|
||||
Required of every framing since #163. This arc was scouted and approved
|
||||
|
|
|
|||
Loading…
Reference in New Issue