docs(discovery): finalize Stage 1 framing review
Correct the M-x prompt census: six of the eleven canonical commands need a second prompt, including describe-command. Make the apropos substring negative discriminate against fuzzy matching with a concrete non-contiguous fixture and a no-substring precondition. Update the help index mutation to the twelfth canonical command, and carry all three corrections into the active-work ledger.
This commit is contained in:
parent
f4359f12b4
commit
513a7dfa58
|
|
@ -380,14 +380,15 @@ which would have re-conflicted on every merge.
|
||||||
githubsucks/journey-stage1b3-welcome
|
githubsucks/journey-stage1b3-welcome
|
||||||
```
|
```
|
||||||
|
|
||||||
## Discovery Stage 1 (P4) — FRAMING APPROVED (rev 5); implementation next
|
## Discovery Stage 1 (P4) — FRAMING APPROVED (rev 6); implementation next
|
||||||
|
|
||||||
- **Branch `discovery-stage1-commands`**, worktree `../pmacs-p4-discovery`,
|
- **Branch `discovery-stage1-commands`**, worktree `../pmacs-p4-discovery`,
|
||||||
based on `githubsucks/main` @ `54a092e`. **Framing only; no code, no
|
based on `githubsucks/main` @ `54a092e`. **Framing only; no code, no
|
||||||
PR yet.** `docs/discovery-stage1-command-family-framing.md` revision 5,
|
PR yet.** `docs/discovery-stage1-command-family-framing.md` revision 6,
|
||||||
three review rounds closed (round 1: two blocking, two major; round 2:
|
three review rounds closed (round 1: two blocking, two major; round 2:
|
||||||
two blocking, two major; round 3: two factual corrections; all
|
two blocking, two major; round 3: two factual corrections; all
|
||||||
accepted), and **Q#D2 / Q#D3 decided by the user**.
|
accepted), Q#D2 / Q#D3 decided by the user, and the final review's
|
||||||
|
acceptance corrections applied.
|
||||||
- **What it is.** `COHERENCE.md` §20 Priority 4 — "almost pure wiring,
|
- **What it is.** `COHERENCE.md` §20 Priority 4 — "almost pure wiring,
|
||||||
the best payoff-per-effort in this document". **Eleven commands under
|
the best payoff-per-effort in this document". **Eleven commands under
|
||||||
one `help.*` prefix**: nine new (describe-key/mode/hook/buffer,
|
one `help.*` prefix**: nine new (describe-key/mode/hook/buffer,
|
||||||
|
|
@ -399,7 +400,10 @@ which would have re-conflicted on every merge.
|
||||||
- **`apropos` matches by SUBSTRING, not fuzzy** (Q#D3). `fuzzy_score`
|
- **`apropos` matches by SUBSTRING, not fuzzy** (Q#D3). `fuzzy_score`
|
||||||
is subsequence-based and descriptions are long sentences, so fuzzy
|
is subsequence-based and descriptions are long sentences, so fuzzy
|
||||||
would match nearly every command. Pinned by a
|
would match nearly every command. Pinned by a
|
||||||
subsequence-that-is-not-a-substring finding nothing.
|
`test.apropos-subsequence-fixture` whose `qzjx` letters occur as `q z
|
||||||
|
j x`, only after asserting no registered name or description contains
|
||||||
|
`qzjx` as a substring; it must find nothing, whereas fuzzy finds the
|
||||||
|
fixture.
|
||||||
- **It adds no Rust.** `pmacs.describe.*`, `pmacs.keymap.list()`,
|
- **It adds no Rust.** `pmacs.describe.*`, `pmacs.keymap.list()`,
|
||||||
`pmacs.command.list()` and `pmacs.config.list()` already return
|
`pmacs.command.list()` and `pmacs.config.list()` already return
|
||||||
everything needed, and `parse_completion_source` accepts a **Lua
|
everything needed, and `parse_completion_source` accepts a **Lua
|
||||||
|
|
@ -422,8 +426,11 @@ which would have re-conflicted on every merge.
|
||||||
corrected, repeated one PR later. The path is dispatch `M-x` →
|
corrected, repeated one PR later. The path is dispatch `M-x` →
|
||||||
`editor.execute-command` → assert the selected candidate **before**
|
`editor.execute-command` → assert the selected candidate **before**
|
||||||
RET (`accept()` does `session.take()`) → accept → `invoke_interactive`.
|
RET (`accept()` does `session.take()`) → accept → `invoke_interactive`.
|
||||||
Five of the nine commands open a **second** prompt the pins must drive
|
Six of the eleven canonical commands (`help.describe-command`,
|
||||||
too; a pin that stops after the first RET has tested the palette.
|
`help.describe-setting`, `help.describe-key`, `help.describe-hook`,
|
||||||
|
`help.where-is`, and `help.apropos`) open a **second** prompt the pins
|
||||||
|
must drive too; a pin that stops after the first RET has tested the
|
||||||
|
palette.
|
||||||
- **One owner for `*help*` writes — NOT a one-site migration.**
|
- **One owner for `*help*` writes — NOT a one-site migration.**
|
||||||
`src/help.rs` has semantic renderers for command/key/buffer/mode/
|
`src/help.rs` has semantic renderers for command/key/buffer/mode/
|
||||||
hook/view and **none for settings, lists or apropos**, and
|
hook/view and **none for settings, lists or apropos**, and
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,28 @@
|
||||||
# Discovery Stage 1 — the describe/list command family
|
# Discovery Stage 1 — the describe/list command family
|
||||||
|
|
||||||
**Status: framing, rev 5 — Q#D2 and Q#D3 decided; ready for implementation approval.**
|
**Status: framing, rev 6 — final review corrections applied; ready for
|
||||||
|
implementation approval.**
|
||||||
**Serves `COHERENCE.md` §5 (unify discoverability), §1.1 (substrate
|
**Serves `COHERENCE.md` §5 (unify discoverability), §1.1 (substrate
|
||||||
without surface), §20 Priority 4.**
|
without surface), §20 Priority 4.**
|
||||||
|
|
||||||
## 0. Revision history
|
## 0. Revision history
|
||||||
|
|
||||||
|
- rev 6 (2026-07-31) — final review corrections applied.
|
||||||
|
- **The second-prompt census now includes `help.describe-command`.**
|
||||||
|
Six of the eleven canonical commands take an argument, not five:
|
||||||
|
`describe-command`, `describe-setting`, `describe-key`,
|
||||||
|
`describe-hook`, `where-is`, and `apropos`. The full M-x driver must
|
||||||
|
accept each command's second prompt before it has tested the command.
|
||||||
|
- **The negative substring pin now has a discriminating fixture.** It
|
||||||
|
registers `test.apropos-subsequence-fixture` with a description whose
|
||||||
|
`qzjx` letters occur only as the non-contiguous sequence `q z j x`, then
|
||||||
|
first asserts that no registered command name or description contains
|
||||||
|
`qzjx` as a substring. `help.apropos qzjx` finding nothing therefore
|
||||||
|
fails under a fuzzy implementation rather than passing as an ordinary
|
||||||
|
no-match.
|
||||||
|
- **The index-property arithmetic follows the eleven-command family.**
|
||||||
|
Its targeted mutation is now adding a twelfth canonical command
|
||||||
|
without indexing it.
|
||||||
- rev 5 (2026-07-31) — **Q#D2 and Q#D3 answered by the user**; no review
|
- rev 5 (2026-07-31) — **Q#D2 and Q#D3 answered by the user**; no review
|
||||||
findings at `1cc9d96`.
|
findings at `1cc9d96`.
|
||||||
- **Q#D2 → `help.*` is canonical, with two forwarders.**
|
- **Q#D2 → `help.*` is canonical, with two forwarders.**
|
||||||
|
|
@ -397,11 +414,11 @@ The pre-RET assertion is not decoration: `accept()` does
|
||||||
`session.take()`, so afterwards nothing about the accepted value
|
`session.take()`, so afterwards nothing about the accepted value
|
||||||
survives, and a selected candidate shadows typed text.
|
survives, and a selected candidate shadows typed text.
|
||||||
|
|
||||||
**Commands that take an argument open a SECOND prompt** (`where-is`,
|
**Six of the eleven canonical commands take an argument and open a SECOND
|
||||||
`describe-key`, `describe-hook`, `describe-setting`, `apropos`). Those
|
prompt** (`describe-command`, `describe-setting`, `describe-key`,
|
||||||
pins drive that prompt too, and assert against it with the same
|
`describe-hook`, `where-is`, `apropos`). Those pins drive that prompt too,
|
||||||
pre-accept discipline. A pin that stops after the first RET has tested
|
and assert against it with the same pre-accept discipline. A pin that stops
|
||||||
the palette, not the command.
|
after the first RET has tested the palette, not the command.
|
||||||
|
|
||||||
### 4.1 Pins
|
### 4.1 Pins
|
||||||
|
|
||||||
|
|
@ -418,11 +435,14 @@ the palette, not the command.
|
||||||
4. **N — `apropos` matches descriptions, not only names, and does so by
|
4. **N — `apropos` matches descriptions, not only names, and does so by
|
||||||
substring.** Two assertions: a word appearing in exactly one
|
substring.** Two assertions: a word appearing in exactly one
|
||||||
command's *description* and no command *name* finds that command
|
command's *description* and no command *name* finds that command
|
||||||
(what distinguishes apropos from a name filter); and a
|
(what distinguishes apropos from a name filter); and a deliberately
|
||||||
**subsequence that is not a substring** — letters present in order
|
discriminating negative: register
|
||||||
but not contiguous — finds **nothing**. The second is what pins
|
`test.apropos-subsequence-fixture`, whose description's `qzjx` letters
|
||||||
Q#D3's decision rather than leaving matching semantics to whatever
|
occur only as the non-contiguous sequence `q z j x`, assert that **no**
|
||||||
the implementation reaches for.
|
registered command name or description contains `qzjx` as a substring,
|
||||||
|
then assert `help.apropos qzjx` finds **nothing**. A fuzzy implementation
|
||||||
|
finds the fixture, so this pins Q#D3's substring decision rather than
|
||||||
|
passing as an ordinary no-match.
|
||||||
5. **N — `describe-setting` completes, and a non-matching typo still
|
5. **N — `describe-setting` completes, and a non-matching typo still
|
||||||
reaches the existing error path.** Two assertions, because §3.2 has
|
reaches the existing error path.** Two assertions, because §3.2 has
|
||||||
two outcomes: (a) typing a real setting's prefix makes it the
|
two outcomes: (a) typing a real setting's prefix makes it the
|
||||||
|
|
@ -432,7 +452,7 @@ the palette, not the command.
|
||||||
*Rev 1 asserted a typo "cannot reach `on_accept`", which
|
*Rev 1 asserted a typo "cannot reach `on_accept`", which
|
||||||
`resolve_accepted_value` contradicts.*
|
`resolve_accepted_value` contradicts.*
|
||||||
6. **N — `M-x help` lists the family.** A property over the family list,
|
6. **N — `M-x help` lists the family.** A property over the family list,
|
||||||
so adding a tenth command without indexing it fails.
|
so adding a twelfth canonical command without indexing it fails.
|
||||||
7. **P — every command's `*help*` write goes through `_show_help`.**
|
7. **P — every command's `*help*` write goes through `_show_help`.**
|
||||||
Replace that function with a counting stub, drive all **eleven**
|
Replace that function with a counting stub, drive all **eleven**
|
||||||
through §4.0's path, and assert the count equals eleven. Pins §3.4's
|
through §4.0's path, and assert the count equals eleven. Pins §3.4's
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue