docs: absorb the config registry (#127) into the handoff
Merges canonical main up to2e37c04and records the second of the two arcs that landed while this lane was open. Vterm Stage 1 (#126) was already recorded; this adds the config registry and reconciles every claim the two merges falsified. Handoff §1: main pointer moved to2e37c04, and a config-registry entry covering the parts a future agent cannot re-derive from the code --- the always-store rule and why the "equal-value set is a no-op" reading silently voids a buffer-local pin; the two-scope model and the no-ambient-buffer contract on get(name); explicit-dispose-only listener lifetime and the absence of any MetaMethod::Gc; the InitCompleteFlag freeze that kept editor.rs untouched; and the strict-registry / lenient-wrapper split that preserves trim_on_save("yes") and interval_ms(1500.7). Handoff §5 gains two lessons. Tab width is a rendering-parity bug, not a config gap: five sites across two crates with two different values, and no tab expansion at all on the GPU main text path, so editor.tab-width is the obvious-looking first adopter and is not one. And "a test that never runs passes" --- pmacs.editor.save() is the raw save while buffer.before-save fires inside the buffer.save COMMAND, and save() no-ops on an unmodified buffer, which made two review-round tests vacuous until the buffer was dirtied and the command invoked. Handoff §6: the three config-registry-blocked deferrals are resolved (the per-buffer auto-pair toggle shipped as editing.auto-pair), replaced by the registry's own named deferrals --- persistence, list-settings, a settings completion source, table-valued settings, the unmigrated scalar setters, and a scope = "global" flag, since set_local is currently accepted for autosave.interval-ms where a per-buffer value is meaningless. active-work.md: base pointer and recovery assertion moved to 2e37c04; the Vterm Stage 2 lane is told to cut from current main rather than 643d1e1; a closed-since-last-snapshot section records the merged lane and the parallel-lane result --- two arcs in sibling worktrees with the shared files assigned one lane each in advance rebased with zero conflicts, which is worth repeating and states its precondition. side-quest-backlog.md: both original north-star items have now shipped, so the board is re-ranked to locals-query processing, mode-system wiring (promoted --- every editor resolve still passes &[], making it the largest remaining scoping gap), and tab-width parity. The config-registry entry is struck and tab width is split out of it, since listing tab width as a config consequence is what made it look like a cheap adopter. Documentation only: the diff against main touches no runtime code. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
1aa19c3bb5
commit
30464bcffd
|
|
@ -14,7 +14,7 @@ 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` @ `643d1e1` (#126 merged; protocol v18).
|
||||
`githubsucks/main` @ `2e37c04` (#127 merged; protocol v18).
|
||||
- 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
|
||||
|
|
@ -48,7 +48,7 @@ git worktree list
|
|||
git status --short --branch
|
||||
```
|
||||
|
||||
The first command must expose `643d1e1` or a newer intentional main.
|
||||
The first command must expose `2e37c04` or a newer intentional main.
|
||||
If it does not, stop and repair the remote/fetch configuration.
|
||||
|
||||
|
||||
|
|
@ -57,6 +57,9 @@ If it does not, stop and repair the remote/fetch configuration.
|
|||
- Portable branch: `githubsucks/vterm-framing`
|
||||
- Approved framing head: `fb4f8f0`
|
||||
- Base: canonical `main` @ `643d1e1` (Vterm Stage 1 / PR #126 merged).
|
||||
`main` has since advanced to `2e37c04` (config registry #127, no
|
||||
runtime overlap with vterm); cut the Stage 2 lane from current `main`,
|
||||
not from `643d1e1`.
|
||||
- State: `docs/vterm-framing.md` Revision 7 is framing-only, reviewed, and
|
||||
approved for implementation. It closes the final `at_bottom`, terminal
|
||||
`C-c` binding-reachability, and context-implicit Lua failure-mode findings.
|
||||
|
|
@ -103,7 +106,24 @@ git worktree add --track \
|
|||
durable handoff refresh, and the keybinding reference correction.
|
||||
- It changes no runtime code.
|
||||
- Review and merge this documentation branch separately; it must not be
|
||||
folded into PR #123 or either feature framing branch.
|
||||
folded into a feature framing branch.
|
||||
- Now also absorbs both landed arcs: Vterm Stage 1 (#126) and the config
|
||||
registry (#127). Canonical `main` is merged into it up to `2e37c04`,
|
||||
so its diff against `main` is documentation only.
|
||||
|
||||
## Closed since the last snapshot
|
||||
|
||||
- **Config registry — MERGED as #127** (`main` @ `2e37c04`). Its lane
|
||||
(`config-registry`, worktree `../pmacs-config-registry`) is done; the
|
||||
branch is kept but carries nothing unmerged. Durable substrate facts
|
||||
moved to `docs/agent-handoff.md` §1 per rule 3 below.
|
||||
- Both this and Vterm Stage 1 ran as **concurrent lanes in sibling
|
||||
worktrees off `main`**, with the shared files (`src/editor.rs`,
|
||||
`src/lua_bindings/mod.rs`, `src/lib.rs`) assigned to one lane each in
|
||||
advance. The rebase of the second lane onto the first had **zero
|
||||
conflicts** — worth repeating for future parallel work, along with its
|
||||
precondition: agree the file split before either lane starts, and keep
|
||||
each lane's footprint in the other's files to a single line.
|
||||
|
||||
## Update protocol
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
# Agent handoff — cross-machine continuity
|
||||
|
||||
**Last updated: 2026-07-21, after Vterm Stage 1 terminal core (#126)
|
||||
landed on `main` atop completed Themes Arc 4 (#120/#124/#125). Vterm
|
||||
Stages 2 and 3 are not implemented.**
|
||||
**Last updated: 2026-07-21, after the config registry (#127) and Vterm
|
||||
Stage 1 terminal core (#126) both landed on `main`, atop completed
|
||||
Themes Arc 4 (#120/#124/#125). Vterm Stages 2 and 3 are not
|
||||
implemented.**
|
||||
This file is the
|
||||
bridge between development machines. If you are an agent reading
|
||||
this on a fresh clone: this document plus the `docs/*-framing.md`
|
||||
|
|
@ -16,9 +17,50 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
|
||||
## 1. Where the project stands (2026-07-21)
|
||||
|
||||
- `main` @ `643d1e1` (Vterm Stage 1 #126), protocol **v18**
|
||||
- `main` @ `2e37c04` (config registry #127), protocol **v18**
|
||||
(`SUPPORTED=[6..18]`; v16 = `ThemeFacts`, v17 = `FontFacts`, v18 =
|
||||
`StatuslineSegments`).
|
||||
- **Config registry LANDED — #127** (`docs/config-registry-framing.md`
|
||||
rev 3; merge `2e37c04`; two review rounds). `pmacs.config` is the
|
||||
typed, introspectable options registry the backlog ranked first, and
|
||||
it closes the "config-registry-blocked" deferrals below. It was built
|
||||
as a PARALLEL LANE alongside vterm in a sibling worktree; the files
|
||||
were assigned per-lane up front and the rebase had zero conflicts.
|
||||
- **Third registry** beside `CommandRegistry`/`HookRegistry`
|
||||
(`src/config_registry.rs`), same R42/R50/duplicate-rejection/
|
||||
`SourceLocation` vocabulary; Lua surface in
|
||||
`src/lua_bindings/config.rs`. **No protocol change (still v18) and
|
||||
ZERO changes to `src/editor.rs`.**
|
||||
- **An override is ALWAYS stored**, even when equal to the value it
|
||||
shadows; only `value_epoch` and listener dispatch key on effective
|
||||
change. The "equal-value set is a no-op" reading silently voids a
|
||||
buffer-local pin: nothing is stored, and a later global `set` flips
|
||||
the very buffer the user pinned.
|
||||
- **Two scopes: global and buffer-local.** `get(name, buf)` resolves
|
||||
local → global → default; **`get(name)` resolves the GLOBAL CHAIN
|
||||
ONLY** and never consults an ambient buffer. Per-language and
|
||||
per-project are *patterns* (a hook calling `set_local`), not scopes
|
||||
the registry knows about. Mode scope is impossible until the mode
|
||||
system is wired — every editor `KeymapStack::resolve` passes `&[]`.
|
||||
- Buffer-locals live in a registry side table purged at
|
||||
`after_buffer_removed`, beside the keymap purge.
|
||||
- Listeners: commit → snapshot → **drop the borrow** → re-enter Lua;
|
||||
a raising listener is logged without blocking the rest or rolling
|
||||
back; a depth bound turns a cycle into a pointed error. **Explicit
|
||||
dispose only** — there is no `MetaMethod::Gc` anywhere in the
|
||||
codebase, and GC timing differs between the two Lua backends.
|
||||
- `StartupOnly` freezes off the existing `InitCompleteFlag` at write
|
||||
time (which is why no `editor.rs` call was needed). In `--lib`
|
||||
builds `set_init_complete` never runs, so a post-freeze test must
|
||||
flip the flag explicitly or it passes vacuously.
|
||||
- Adopters own their own `define`, so `SourceLocation` names the
|
||||
owning module: `editing.auto-pair` (pair.lua, read against the
|
||||
typed edit's SOURCE buffer), `editing.trim-on-save` (editops.lua,
|
||||
read against the buffer being saved), `autosave.interval-ms`
|
||||
(autosave.lua, re-read per tick). **The migration wrappers keep
|
||||
their legacy coercion** — the registry is strict, the legacy setters
|
||||
stay lenient (`trim_on_save("yes")`, `interval_ms(1500.7)`).
|
||||
- `M-x describe-setting` renders into `*help*`.
|
||||
- **Syntax-highlight / language-detection side-quest (#114–#118)
|
||||
LANDED** — a one-shot arc built in sibling worktrees off main while
|
||||
the user's themes lane (`theme-faces`) ran concurrently in the shared
|
||||
|
|
@ -207,6 +249,12 @@ commands, read `docs/active-work.md` immediately after this file.
|
|||
live GPU font preferences (#124), statusline providers (#125).
|
||||
- **Arc 5 terminal stage ACTIVE** — compile mode (#113) and Vterm terminal
|
||||
core (#126) landed; Vterm TUI is the next formal stage.
|
||||
- **Config registry COMPLETE (#127)** — not a numbered arc; it was the
|
||||
cross-cutting substrate ranked first on
|
||||
`docs/side-quest-backlog.md`'s north star, and it unblocks the
|
||||
editing/indent/comment items that were config-blocked.
|
||||
- Remaining ranked arcs: 6 folding, 7 DAP, 8 GPU splits, plus the
|
||||
`.ipynb` arc (its JSON-grammar prerequisite shipped in #123).
|
||||
|
||||
## 2. How we work (the part that must not drift)
|
||||
|
||||
|
|
@ -362,6 +410,28 @@ acceptance.
|
|||
in per-session baselines; and any daemon-side reset needs its
|
||||
frontend mirror audited in the same round (the GPU snapshot arm
|
||||
missed search/menu/status the first time).
|
||||
- **Tab width is a rendering-parity bug, NOT a config gap** (scouted at
|
||||
`7bc0c61` while framing #127; still true). There are FIVE tab-width
|
||||
sites across TWO crates with TWO different values: `TAB_WIDTH = 8` in
|
||||
`src/text_view.rs`, `src/highlight.rs`, `src/diag.rs` and
|
||||
`src/completion.rs`, versus `advance_minimap_col` in
|
||||
`pmacs-gpu/src/main.rs` expanding to **4** — and the GPU's main text
|
||||
path expands tabs *not at all* (buffer bytes reach the frontend raw,
|
||||
so a literal `\t` is shaped by the font). `editor.tab-width` is
|
||||
therefore the obvious-looking first config adopter and is not one:
|
||||
defining the setting cannot make the GPU honor it. Doing it properly
|
||||
needs frontend tab expansion plus a wire-or-frontend-local decision.
|
||||
Deferred from #127 on exactly these grounds; don't re-plan it as a
|
||||
config task.
|
||||
- **A test that never runs passes.** Two #127 review-round tests passed
|
||||
vacuously at first: `pmacs.editor.save()` is the RAW save, while
|
||||
`buffer.before-save` fires inside the `buffer.save` COMMAND
|
||||
(`builtin/commands/default.lua`), and `save()` no-ops on an
|
||||
unmodified buffer — so a fixture that opens a file and saves it
|
||||
asserts on bytes nothing rewrote. Dirty the buffer with a real edit
|
||||
and go through `pmacs.command.invoke("buffer.save")`. Caught only
|
||||
because the *other* case failed and the cause was chased instead of
|
||||
the assertion adjusted.
|
||||
|
||||
## 6. Named deferrals (the standing backlog, consolidated)
|
||||
|
||||
|
|
@ -372,8 +442,9 @@ mid-line comment spans, comment-dwim append-at-EOL, per-language
|
|||
comment padding. Pairing (framing "Deferred"): wrap-region on opener,
|
||||
pair-aware backspace, RET-inside-pair closer-on-own-line,
|
||||
in-string/in-comment inhibit (needs node-at-byte `pmacs.parse`),
|
||||
undo amalgamation (pair = one step), balance-aware quotes,
|
||||
per-buffer toggle (config-registry-blocked). Editops deferrals (full
|
||||
undo amalgamation (pair = one step), balance-aware quotes
|
||||
(the per-buffer toggle SHIPPED in #127 as `editing.auto-pair`).
|
||||
Editops deferrals (full
|
||||
list in its framing): recenter (blocked on viewport facts — the GPU
|
||||
never consumes daemon `view_top`), Unicode case/word classes,
|
||||
region-spanning move/duplicate, locale collation for sort-lines,
|
||||
|
|
@ -389,7 +460,20 @@ origin-pinned `buffer.after-edit` fan-out (a context-switching
|
|||
intercept changes what later callbacks — LSP, completion — observe).
|
||||
LSP/persistence: hidden-buffer LSP attach, daemon desktop-restore, the
|
||||
*warning* half of external-change detection (verify-visited-file-
|
||||
modtime), config registry (no unified config surface yet).
|
||||
modtime).
|
||||
Config registry (SHIPPED #127; these are its own named deferrals):
|
||||
persistence of settings and the `custom-file` split-brain question,
|
||||
`M-x list-settings` as a listview panel, a settings completion source
|
||||
for the minibuffer (`minibuffer.read`'s `source` is a fixed Rust-side
|
||||
vocabulary), table-valued settings (so `pmacs.lsp.config`,
|
||||
`pmacs.pair.sets`, `pmacs.comment.strings` and the `pmacs.parse.*`
|
||||
write-through proxies stay raw Lua), migrating the remaining scalar
|
||||
setters (`async_config` ×2, `killring.max`, the `enable` booleans) and
|
||||
`pmacs.gpu.set_font`, pending-set staging for names defined after
|
||||
`init.lua` runs, and a `scope = "global"` define flag — `set_local` is
|
||||
currently accepted for `autosave.interval-ms`, where a per-buffer
|
||||
value is meaningless.
|
||||
**Tab width is NOT a config gap** — see §5.
|
||||
Highlight/detection (from the #114–#118 side-quest + injections #122):
|
||||
locals-query processing (run each grammar's LOCALS_QUERY so
|
||||
`#is?`/`#is-not? local` is honored instead of the current fail-closed
|
||||
|
|
@ -415,7 +499,8 @@ popup/menu/dropdown bg + selected-row faces, `ui.background` /
|
|||
palette (+`ui.selection` for peer rects), `ui.inlay_hint` (needs the
|
||||
epoch treatment on its producer), wire alpha, `Indexed` palette
|
||||
unification, named-theme registry / light theme / persistence
|
||||
(config-registry-blocked), grid-vs-wire `default_style` asymmetry,
|
||||
(the registry exists now, #127; theme persistence still waits on
|
||||
settings persistence), grid-vs-wire `default_style` asymmetry,
|
||||
mask widening (gutter bg, wash glyph recolor, statusline bg echo
|
||||
surface, chrome bold/italic/underline re-shaping).
|
||||
Housekeeping: F-016 `lua_bindings/mod.rs` split paused mid-way
|
||||
|
|
|
|||
|
|
@ -114,10 +114,20 @@ The direct continuation of the #114–#118 grammar/detection stack.
|
|||
|
||||
## Cross-cutting substrate (unblocks whole clusters — high leverage)
|
||||
|
||||
- **Config/settings registry** (`pmacs.config` / defcustom) — blocks
|
||||
language-aware indent, the five hardcoded tab-width sites, per-buffer
|
||||
auto-pair toggle, per-language comment padding, per-project compile
|
||||
commands.
|
||||
- ~~**Config/settings registry**~~ — **SHIPPED as #127.** `pmacs.config`
|
||||
exists with global + buffer-local scopes. Unblocked: the per-buffer
|
||||
auto-pair toggle (shipped in the same PR as `editing.auto-pair`),
|
||||
language-aware indent, per-language comment padding, and per-project
|
||||
compile commands — the last three are now ordinary work, expressed as
|
||||
a `buffer.after-load` hook calling `set_local`, not blocked work.
|
||||
- **Tab-width rendering parity** — was listed above as a config
|
||||
consequence; it is not. `TAB_WIDTH = 8` appears four times in the
|
||||
daemon (`text_view`, `highlight`, `diag`, `completion`), the GPU
|
||||
minimap's `advance_minimap_col` uses **4**, and the GPU main text path
|
||||
expands tabs *not at all* — raw `\t` reaches glyphon and is shaped by
|
||||
the font. Defining `editor.tab-width` cannot make the GPU honor it;
|
||||
this needs frontend tab expansion plus a wire-or-frontend-local
|
||||
decision. Deferred from #127 on those grounds.
|
||||
- **Real `read_only` buffer flag** on both edit paths — true immutability
|
||||
for panels / REPL / generated buffers.
|
||||
- **Mode system wiring** — dispatch passes an empty mode list (`&[]`);
|
||||
|
|
@ -227,14 +237,20 @@ guides (visual, not color).
|
|||
|
||||
## North star (highest-leverage first)
|
||||
|
||||
**Multi-language injections shipped (#122)** — one of the two original
|
||||
north-star items is done, so the highest-leverage board is now:
|
||||
**Both original north-star items have now shipped** — multi-language
|
||||
injections (#122) and the config registry (#127) — and JSON + YAML
|
||||
(#123) merged too. The remaining board:
|
||||
|
||||
1. **Config registry** — frees ~5 editing/indent/comment features at once.
|
||||
2. **Finish JSON + YAML PR #123** — the one remaining gate on the
|
||||
Jupyter `.ipynb` path now that injections exist.
|
||||
3. **Locals-query processing** — restores `.builtin` styling for
|
||||
1. **Locals-query processing** — restores `.builtin` styling for
|
||||
non-shadowed builtins, the last rough edge of the highlight stack.
|
||||
2. **Mode-system wiring** — every editor `KeymapStack::resolve` still
|
||||
passes `&[]`, so mode-scoped keybindings and any mode-scoped setting
|
||||
remain unreachable. Promoted here because #127 made it the largest
|
||||
remaining scoping gap.
|
||||
3. **Tab-width rendering parity** — five constants across two crates
|
||||
with two different values, and no tab expansion at all on the GPU
|
||||
main text path. Explicitly NOT a config-registry task; see the entry
|
||||
under "Cross-cutting substrate".
|
||||
|
||||
Beyond those, the cleanest one-shots in the highlight family are
|
||||
**modeline detection** and the HTML/CSS grammars that light up more
|
||||
|
|
|
|||
Loading…
Reference in New Issue