diff --git a/COHERENCE.md b/COHERENCE.md index 670b235..15a05d9 100644 --- a/COHERENCE.md +++ b/COHERENCE.md @@ -98,7 +98,7 @@ remain open to them. | 2 | Golden product journey | **Runs to step 10** | `pmacs .` opens the directory (1a); the interface introduces itself (1b-3); a missing language server says so (1b-2, #204); a build is bound and prefilled (1b-1, #203). Steps 1, 11 and 12 remain the thin end | | 3 | Zero-configuration state | **Partial** | Defaults genuinely strong; missing-tool failure is silent, not graceful | | 4 | Progressive disclosure | **Inverted** | The advanced level is real; the beginner level is the missing one | -| 5 | Unified discoverability | **Substrate without surface** | Best-in-class registration metadata; almost no way for a user to reach it | +| 5 | Unified discoverability | **Partial** | Discovery Stage 1: eleven `help.*` commands (describe key/mode/hook/buffer/command/setting, where-is, list commands/keybindings/settings, apropos) over the existing registries, indexed by `M-x help`. Commands, keys, modes, hooks and settings are now reachable; **packages and workers are not** (§13, §9), `Command` still has no title/category/flags, M-x rows are still bare names, and the Rust help layer is still orphaned | | 6 | Interaction islands | **Weak, and growing** | Six hardcoded key-interception shadows; no transient-keymap mechanism exists | | 7 | First-class workspaces | **Missing (conventions only)** | Marker walk + four independent consumers; no workspace object | | 8 | Execution locations | **Missing (architecture ready)** | SSH attach works; "location" is not a value anywhere | @@ -557,7 +557,25 @@ This suggests a general pmacs principle: ### Ground truth -**Grade: substrate without surface — the sharpest instance of §1.1.** +**Grade: partial — Discovery Stage 1 built the first surface.** + +Eleven `help.*` commands now render the registries that were already +there: describe-key/mode/hook/buffer/command/setting, where-is, list +commands/keybindings/settings, and a substring apropos over names and +descriptions, indexed by `M-x help`. It needed **no Rust** — the data +was all reachable from Lua, and even the settings completion source is a +Lua function through `CompletionSource::Custom`. + +**What is still missing** is itemized below and unchanged by that stage: +`Command` has no title/category/aliases/flags/arg-schema; the predicate +is still never evaluated; M-x rows are still bare name strings; the Rust +help layer is still orphaned (Stage 1 funnels every command through one +Lua seam so the eventual migration is enumerated per subject rather than +per call site); packages and workers have no discovery surface; settings +value provenance is still absent; and there is still no help prefix key. + +*The original audit grade, for reference:* **substrate without surface — +the sharpest instance of §1.1.** **What the substrate already has (genuinely strong):** diff --git a/docs/active-work.md b/docs/active-work.md index 7628388..a009815 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -380,11 +380,11 @@ which would have re-conflicted on every merge. githubsucks/journey-stage1b3-welcome ``` -## Discovery Stage 1 (P4) — FRAMING APPROVED (rev 6); implementation next +## Discovery Stage 1 (P4) — IMPLEMENTED, PR OPEN - **Branch `discovery-stage1-commands`**, worktree `../pmacs-p4-discovery`, - based on `githubsucks/main` @ `54a092e`. **Framing only; no code, no - PR yet.** `docs/discovery-stage1-command-family-framing.md` revision 6, + based on `githubsucks/main` @ `54a092e`. **Implemented; PR open.** + `docs/discovery-stage1-command-family-framing.md` revision 6, three review rounds closed (round 1: two blocking, two major; round 2: two blocking, two major; round 3: two factual corrections; all accepted), Q#D2 / Q#D3 decided by the user, and the final review's @@ -453,6 +453,24 @@ which would have re-conflicted on every merge. a behaviour change); help-layer unification; closed-set acceptance; and the **help prefix key**, which this stage does not touch because #205 recorded why `C-h` is not free. +- **Implementation notes.** `runtime/help.lua` is new and owns the + family plus the `help` index, which **moved out of `welcome.lua`** so + the greeting file keeps only the greeting; it loads after welcome.lua + so the index can read `pmacs.welcome.entries`. +- **The seam-counting pin caught a real bypass immediately.** The two + renamed commands were still calling the file-local `show_help_text`, + so the funnel the framing promised was fiction for exactly the two + commands that predate the seam. They now call + `pmacs.editor._show_help`, with a comment saying why the in-scope + local is deliberately not used. +- **Bites, all directed** — six mutations, each failing exactly one pin: + fuzzy apropos, name-only apropos, static where-is, a dropped + forwarder, an unindexed family command, and one command writing + `*help*` itself (seam count 10 vs 11). +- **§5 moves substrate-without-surface → Partial ON THIS PR** per §25, + with the remaining gaps named in the row: packages and workers have no + surface, `Command` still lacks title/category/flags, M-x rows are bare + names, and the Rust help layer is still orphaned. - Recovery: ```sh diff --git a/docs/agent-handoff.md b/docs/agent-handoff.md index d4542f4..2ac5266 100644 --- a/docs/agent-handoff.md +++ b/docs/agent-handoff.md @@ -300,6 +300,37 @@ commands, read `docs/active-work.md` immediately after this file. disagree — and it still establishes no identity, because it is read inside the same read-then-act window and no portable mechanism closes that for a *group* (`pidfd` covers a process; macOS has neither). +- **Discovery arc (P4) — Stage 1 IMPLEMENTED, PR open** + (`docs/discovery-stage1-command-family-framing.md`, rev 6, three + review rounds). Eleven `help.*` commands over the existing registries, + indexed by `M-x help`. **§5 moves substrate-without-surface → + Partial.** No Rust: the data was all reachable from Lua, and the + settings completion source is a Lua function through + `CompletionSource::Custom` — correcting a `default.lua` comment that + claimed `source` was a fixed Rust-side vocabulary. + - **Completion is assistance, not validation.** + `resolve_accepted_value` returns the literal typed text whenever no + candidate is selected, so a typo still reaches `on_accept`; and a + fuzzy near-miss would silently select a *different* value. Refusing + a non-candidate is Rust work, deferred. + - **`apropos` is substring, not fuzzy.** `fuzzy_score` is + subsequence-based and descriptions are long sentences, so fuzzy + matches nearly everything. Pinned by a fixture whose description + contains the needle only as a non-contiguous subsequence. + - **One owner for `*help*` writes is what the seam buys — not a + one-site migration.** `src/help.rs` has renderers for + command/key/buffer/mode/hook/view and **none** for settings, lists + or apropos, and `_show_help` takes already-flattened text. Rendering + is therefore a named per-subject function, so the future Rust work + is enumerated per subject (three new renderers) rather than + discovered per call site. + - **The seam-counting pin caught a real bypass**: the two renamed + commands were still calling the file-local `show_help_text`, so the + funnel was fiction for exactly the two that predate it. + - **`Command.predicate` is still never evaluated** — read only at + `src/help.rs:76` and one test. A preservation pin registers a + *raising* predicate and asserts the command still runs, so a stage + that starts evaluating must change that pin knowingly. - **Journey arc (P1) — Stage 1b-3 IMPLEMENTED, PR open** (`docs/journey-stage1b3-welcome-framing.md`, rev 4, three review rounds). The last of the 1b split. An unconfigured launch greets in diff --git a/docs/keybindings.md b/docs/keybindings.md index 1d3cbae..b08e4f4 100644 --- a/docs/keybindings.md +++ b/docs/keybindings.md @@ -189,8 +189,26 @@ Source: `builtin/runtime/compile.lua`. | `M-!` | `shell.command` — asynchronous output in `*shell-command*` | | `C-c c` | `compile.run` — prompts, prefilled from the detected project kind | -`M-x help` renders this file's essentials as a `*help*` buffer inside -the editor, and is what the startup welcome points at. It is the root of +`M-x help` is the **index of the discovery family**, rendered as a +`*help*` buffer inside the editor, and is what the startup welcome +points at. The family — all reachable by name, none bound to a key: + +| Command | Shows | +|---|---| +| `help.describe-command` | a command's description and bindings | +| `help.describe-setting` | a setting's type, default, effective value | +| `help.describe-key` | what a chord runs in **this** buffer | +| `help.describe-mode` | the active buffer's major mode | +| `help.describe-buffer` | the active buffer | +| `help.describe-hook` | a hook and its listeners | +| `help.where-is` | which keys run a command | +| `help.list-commands` | every command with its description | +| `help.list-keybindings` | every binding, grouped by scope | +| `help.list-settings` | every registered setting | +| `help.apropos` | substring search over names **and** descriptions | + +`editor.describe-command` and `editor.describe-setting` still work as +deprecated aliases of their `help.*` counterparts. It is the root of the eventual help family (`help.keys` and friends arrive with the discovery arc), so it takes no keybinding yet — `C-h` is **not** free: it deletes a word because non-kitty terminals cannot tell Ctrl+Backspace