docs(lean4): reconcile peer edits with pending ownership
Advance the Stage 4 framing to revision 8. Keep pending abbreviation state frontend-owned while conservatively invalidating it after any intervening shared-buffer edit, make the revision token explicit, and rewrite acceptance 45i around that contract. Correct the active-work multi-codepoint count and the stale coherence revision label.
This commit is contained in:
parent
c4fad0731c
commit
174e36fce3
|
|
@ -64,17 +64,17 @@ If it does not, stop and repair the remote/fetch configuration.
|
||||||
histories were pruned from this ledger in round 6, per this file's own
|
histories were pruned from this ledger in round 6, per this file's own
|
||||||
instruction to remove entries when their PR merges; the durable facts
|
instruction to remove entries when their PR merges; the durable facts
|
||||||
now live in `docs/agent-handoff.md` §1's Lean 4 bullet, which is where
|
now live in `docs/agent-handoff.md` §1's Lean 4 bullet, which is where
|
||||||
a fresh machine should read them. `docs/lean4-mode-framing.md` rev 7
|
a fresh machine should read them. `docs/lean4-mode-framing.md` rev 8
|
||||||
carries the decisions.
|
carries the decisions.
|
||||||
|
|
||||||
### Stage 4 — framing rev 7, split into 4a/4b (branch `lean4-stage4a-typed-edit-chain`)
|
### Stage 4 — framing rev 8, split into 4a/4b (branch `lean4-stage4a-typed-edit-chain`)
|
||||||
|
|
||||||
- Stages 3a and 3b **merged as #167** (`main` @ `6f348c9`) and **#170**
|
- Stages 3a and 3b **merged as #167** (`main` @ `6f348c9`) and **#170**
|
||||||
(`main` @ `d400f30`), 2026-07-26. Both were integrated against a main
|
(`main` @ `d400f30`), 2026-07-26. Both were integrated against a main
|
||||||
that had advanced 50 commits mid-review; the only conflict either time
|
that had advanced 50 commits mid-review; the only conflict either time
|
||||||
was this ledger's own lane headings, resolved by keeping both sides.
|
was this ledger's own lane headings, resolved by keeping both sides.
|
||||||
- Worktree `../pmacs-lean-stage4`, branched off `main` @ `d400f30`.
|
- Worktree `../pmacs-lean-stage4`, branched off `main` @ `d400f30`.
|
||||||
Framing-only so far: `docs/lean4-mode-framing.md` **revision 7**. No
|
Framing-only so far: `docs/lean4-mode-framing.md` **revision 8**. No
|
||||||
code. Awaiting user approval before implementation, per the workflow.
|
code. Awaiting user approval before implementation, per the workflow.
|
||||||
- **Round 6 review found five P1s, four of them internal to rev 6** —
|
- **Round 6 review found five P1s, four of them internal to rev 6** —
|
||||||
facts about pmacs the revision asserted without checking, while its
|
facts about pmacs the revision asserted without checking, while its
|
||||||
|
|
@ -93,6 +93,15 @@ If it does not, stop and repair the remote/fetch configuration.
|
||||||
the upstream package ships no README after fetching the package root,
|
the upstream package ships no README after fetching the package root,
|
||||||
with the directory listing showing `src/README.md` already in hand.
|
with the directory listing showing `src/README.md` already in hand.
|
||||||
The README states the tie rule in one sentence.
|
The README states the tie rule in one sentence.
|
||||||
|
- **Round 7 review found one remaining P1 in acceptance 45i.** Rev 7
|
||||||
|
required A's pending abbreviation to survive B editing the same
|
||||||
|
buffer, while Q#LN22 also required an exact buffer-revision advance.
|
||||||
|
Those cannot both hold: revisions are buffer-global and every edit
|
||||||
|
bumps them. Rev 8 keeps the conservative guard and separates
|
||||||
|
ownership from survival — B cannot consume A's record, but B editing
|
||||||
|
the shared buffer invalidates A lazily; B switching buffers or
|
||||||
|
detaching remains frontend-scoped when no shared-buffer edit
|
||||||
|
intervenes.
|
||||||
- **Round 5 re-scout split Stage 4 into 4a (substrate) and 4b (Lean).**
|
- **Round 5 re-scout split Stage 4 into 4a (substrate) and 4b (Lean).**
|
||||||
4a is the typed-edit consumer chain — `builtin/runtime/typed_edit.lua`
|
4a is the typed-edit consumer chain — `builtin/runtime/typed_edit.lua`
|
||||||
plus `pair.lua` re-expressed as one registered consumer, no behavior
|
plus `pair.lua` re-expressed as one registered consumer, no behavior
|
||||||
|
|
@ -130,7 +139,8 @@ If it does not, stop and repair the remote/fetch configuration.
|
||||||
- Table facts re-derived at `17d1d08`: 1,855 entries, 36,861 bytes, all
|
- Table facts re-derived at `17d1d08`: 1,855 entries, 36,861 bytes, all
|
||||||
keys ASCII, **64** keys carry a `lean4` pair-set char, **305** keys are
|
keys ASCII, **64** keys carry a `lean4` pair-set char, **305** keys are
|
||||||
proper prefixes of another (so 1,550 expand eagerly), **26** values
|
proper prefixes of another (so 1,550 expand eagerly), **26** values
|
||||||
carry `$CURSOR`, **93** are multi-codepoint.
|
carry `$CURSOR`, and **119** are multi-codepoint — the 26
|
||||||
|
`$CURSOR`-bearing values plus 93 others.
|
||||||
- Citation sweep per COHERENCE §25: five live citations moved in the 50
|
- Citation sweep per COHERENCE §25: five live citations moved in the 50
|
||||||
commits since rev 5 — `take_typed_edit` 12827→12990,
|
commits since rev 5 — `take_typed_edit` 12827→12990,
|
||||||
`handle_server_requests` 1549→1815, `fs.stat` 93→133,
|
`handle_server_requests` 1549→1815, `fs.stat` 93→133,
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ during a rebase.
|
||||||
|
|
||||||
## 0.1 Revision history
|
## 0.1 Revision history
|
||||||
|
|
||||||
Revision 1 — initial. Current revision: **7**.
|
Revision 1 — initial. Current revision: **8**.
|
||||||
|
|
||||||
### Round 1 (rev 1 → rev 2)
|
### Round 1 (rev 1 → rev 2)
|
||||||
|
|
||||||
|
|
@ -480,6 +480,29 @@ section cites golden-journey **step 5** ("Edit immediately"), not step
|
||||||
4; and §8's config-registry prior art points at Q#LN22, where the gate
|
4; and §8's config-registry prior art points at Q#LN22, where the gate
|
||||||
now lives.
|
now lives.
|
||||||
|
|
||||||
|
### Round 7 (rev 7 → rev 8)
|
||||||
|
|
||||||
|
One P1 remained in the new multi-frontend acceptance, plus two
|
||||||
|
documentation cleanups.
|
||||||
|
|
||||||
|
1. **Acceptance 45i contradicted Q#LN22's conservative abandonment
|
||||||
|
rule.** It required frontend A's pending abbreviation to survive
|
||||||
|
frontend B editing the same buffer, but `buffer:revision()` is
|
||||||
|
buffer-global and advances on every edit. B's first edit therefore
|
||||||
|
invalidates A's record under the exact-revision guard. The criterion
|
||||||
|
now separates the two contracts: another frontend cannot consume A's
|
||||||
|
record, but any intervening edit to their shared buffer invalidates
|
||||||
|
it lazily; navigation and detachment remain frontend-scoped when no
|
||||||
|
shared-buffer edit intervenes. The pending record now names its
|
||||||
|
`expected_revision` explicitly so the validation rule is buildable.
|
||||||
|
Preserving A's record through peer edits would require translating
|
||||||
|
and validating its span across arbitrary edits, a substantially
|
||||||
|
larger substrate change that Stage 4b does not take on.
|
||||||
|
2. **The volatile ledger retained rev 6's undercount.** Its table facts
|
||||||
|
now say 119 multi-codepoint symbols — 26 `$CURSOR`-bearing and 93
|
||||||
|
others — matching §2.11 and Q#LN11.
|
||||||
|
3. **§9.1's revision label was stale.** It now names rev 8.
|
||||||
|
|
||||||
## 1. What ships
|
## 1. What ships
|
||||||
|
|
||||||
Nine stages, after round 4 split Stage 3 and round 5 split Stage 4. The
|
Nine stages, after round 4 split Stage 3 and round 5 split Stage 4. The
|
||||||
|
|
@ -1640,8 +1663,9 @@ that an edit was made.
|
||||||
reconstruction of it:
|
reconstruction of it:
|
||||||
|
|
||||||
- `\` typed in a `lean4` buffer opens a pending abbreviation: `{ buffer,
|
- `\` typed in a `lean4` buffer opens a pending abbreviation: `{ buffer,
|
||||||
window, start_offset, text = "" }`, keyed on **`(frontend, buffer)`** —
|
window, start_offset, text = "", expected_revision }`, keyed on
|
||||||
see below.
|
**`(frontend, buffer)`** — see below. `expected_revision` is the
|
||||||
|
buffer's revision after that leader edit.
|
||||||
- A subsequent self-insert `c` is claimed iff at least one key has
|
- A subsequent self-insert `c` is claimed iff at least one key has
|
||||||
`text .. c` as a prefix; then `text = text .. c`. If it is also
|
`text .. c` as a prefix; then `text = text .. c`. If it is also
|
||||||
uniquely-and-completely matching (one of the 1,550), expand now.
|
uniquely-and-completely matching (one of the 1,550), expand now.
|
||||||
|
|
@ -1685,7 +1709,14 @@ finding 3). Pending state is validated at the next typed edit and
|
||||||
discarded when any of these no longer holds: the record's buffer and
|
discarded when any of these no longer holds: the record's buffer and
|
||||||
window are the pending ones; `rec.effective_start` equals `start_offset
|
window are the pending ones; `rec.effective_start` equals `start_offset
|
||||||
+ 1 + #text` (the point is still at the end of the pending span); and
|
+ 1 + #text` (the point is still at the end of the pending span); and
|
||||||
the buffer's `revision()` advanced by exactly the pending edit.
|
the buffer's `revision()` equals `expected_revision + 1`, meaning the
|
||||||
|
current typed edit is the only edit since this frontend last extended
|
||||||
|
the pending abbreviation. A claimed extension stores the current
|
||||||
|
revision as the new `expected_revision`. This is deliberately
|
||||||
|
conservative across frontends: any intervening edit to the shared
|
||||||
|
buffer invalidates the pending record even if it occurred elsewhere.
|
||||||
|
Keeping the record alive would require translating and validating its
|
||||||
|
span through arbitrary peer edits, substrate Stage 4b does not add.
|
||||||
`buffer.after-switch` clears the acting frontend's entries eagerly,
|
`buffer.after-switch` clears the acting frontend's entries eagerly,
|
||||||
since that hook *does* exist. The
|
since that hook *does* exist. The
|
||||||
practical difference from upstream: a user who clicks away mid-`\alp`
|
practical difference from upstream: a user who clicks away mid-`\alp`
|
||||||
|
|
@ -2425,14 +2456,19 @@ criterion 46 requires to stay byte-identical.
|
||||||
because the expansion is a programmatic replace that arms no record.
|
because the expansion is a programmatic replace that arms no record.
|
||||||
Bites against a future consumer that infers pending state from
|
Bites against a future consumer that infers pending state from
|
||||||
buffer text instead of provenance.
|
buffer text instead of provenance.
|
||||||
45i. **Pending state is per frontend (Q#LN22).** Two frontends attached
|
45i. **Pending state is per frontend, with conservative shared-buffer
|
||||||
to the same `lean4` buffer: A types `\al`, B types `\to` + space in
|
invalidation (Q#LN22).** Two frontends share a `lean4` buffer at
|
||||||
the same buffer. B's expansion yields `→` and leaves A's `\al`
|
distinct points. A types `\al`; B types `p`. B's `p` lands normally
|
||||||
pending and intact; A then typing `l` + space still yields `∀`.
|
at B's point rather than extending A's record. Because that edit
|
||||||
Plus: B switching buffers does not clear A's pending state, and a
|
advances the shared buffer's revision, A then typing `l` + space
|
||||||
`frontend.detached` for B purges B's entries only. Bites against the
|
leaves literal `\all ` rather than expanding: A's stale record is
|
||||||
buffer-keyed design rev 6 specified — which passes every
|
abandoned lazily. In a fresh setup, A types `\al`, B switches
|
||||||
single-frontend criterion above.
|
buffers **without editing the shared buffer**, and A typing `l` +
|
||||||
|
space still yields `∀`; B's switch clears only B's entries. Finally,
|
||||||
|
`frontend.detached` for B purges B's entries only and does not clear
|
||||||
|
a still-valid A record. Bites both against the buffer-keyed design
|
||||||
|
rev 6 specified and against the impossible rev-7 promise that
|
||||||
|
pending state survives arbitrary peer edits.
|
||||||
45f. **Both producers, and the CI-darkness stated.** The dispatch path
|
45f. **Both producers, and the CI-darkness stated.** The dispatch path
|
||||||
is pinned by the criteria above. The optimistic CRDT producer
|
is pinned by the criteria above. The optimistic CRDT producer
|
||||||
(round-5 finding 4) is pinned by a separate criterion driving
|
(round-5 finding 4) is pinned by a separate criterion driving
|
||||||
|
|
@ -2615,7 +2651,7 @@ uncapped event queue, the dropped `cfg.restart`, and — unchanged from
|
||||||
languages other than Lean, and §4's rule is what keeps them out of a Lean
|
languages other than Lean, and §4's rule is what keeps them out of a Lean
|
||||||
PR.
|
PR.
|
||||||
|
|
||||||
### 9.1 Coherence impact — stages 4a and 4b (rev 6)
|
### 9.1 Coherence impact — stages 4a and 4b (rev 8)
|
||||||
|
|
||||||
**Sections served.** §6 (interaction islands) primarily, and in the
|
**Sections served.** §6 (interaction islands) primarily, and in the
|
||||||
*preventing* direction rather than the fixing one — see below. §11
|
*preventing* direction rather than the fixing one — see below. §11
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue