docs/plans/2026-05-07-slate-v2-multiblock-fragment-middle-insert-ralplan.md
Date: 2026-05-07
Ready for Ralph.
The next issue-backed owner should be #5089, not #5080.
#5089 is the remaining ready-now fragment-shape issue from the lane just
touched. It asks for multi-block fragment insertion in the middle of a
paragraph to preserve block separation instead of flattening all text into
the destination block.#5080 is a clean package-only query-order bug, but it is isolated and does
not finish the open fragment/clipboard cluster.#4542 and #3155 stay related. They are broader paste/wrapper and fragment
non-merging policy rows, not this exact middle-paragraph multi-block proof.Final score: 0.93.
The plan is strong enough to execute. The closure bar is narrow: prove #5089
through the public core fragment API and the DOM clipboard boundary before any
fixed claim. #4542 and #3155 stay related, not fixed.
Intent: finish the narrow fragment insertion shape claim that remains after the explicit-target and empty-block caret lane.
Desired outcome:
Editor.insertFragment / transaction fragment insertion preserve multi-block
structure when a multi-block fragment is inserted at a collapsed point inside
an existing text block.#5089 can move to Fixes only after exact package proof lands and the
paste-path proof bar is satisfied.In scope:
.tmp/slate-v2/packages/slate/src/transforms-text/insert-fragment.ts.tmp/slate-v2/packages/slate/test/clipboard-contract.ts.tmp/slate-v2/packages/slate-dom/test/clipboard-boundary.ts if the claim uses
clipboard/paste wording.Non-goals:
#4542 nested-wrapper paste closure without matching DOM/browser
proof;#3155;Editor.nodes({ reverse: true }) query-order fix for #5080;#5129;#3891.Decision boundaries:
#5089.insert-fragment.ts only if the exact package proof fails.Fixes #5089 only when the proof matches the original
middle-paragraph multi-block insertion report.#4542 and #3155 related unless their own repro shape is proven.Principles:
Top drivers:
#5089 is ready-now in
docs/slate-issues/test-candidate-map/5129-5066.md..tmp/slate-v2/packages/slate/src/transforms-text/insert-fragment.ts.before one / twoafter from a collapsed middle insertion.clipboard-contract.ts has no exact #5089 middle-paragraph
multi-block assertion.Viable options:
#5089 next.
#5080 next.
#4542 next.
Chosen: option 1, with #5080 deferred as the next separate query-order lane.
Consequences:
Fixes
or keep a narrower Improves line until DOM/browser paste proof lands.Current source owners:
.tmp/slate-v2/packages/slate/src/transforms-text/insert-fragment.ts owns
fragment fitting.insert-fragment.ts partitions fragment content into starts, middles,
and ends, with middle block preservation around the destination split..tmp/slate-v2/packages/slate/test/clipboard-contract.ts currently covers
explicit target insertion, empty-block selection placement, single-block
fitting, and target-block preservation, but not the exact #5089
middle-paragraph multi-block insertion shape.Live probe from /Users/zbeyens/git/slate-v2:
bun -e 'import { createEditor } from "./packages/slate/src"; import { Editor } from "./packages/slate/src/internal"; const editor=createEditor(); Editor.replace(editor,{children:[{type:"paragraph",children:[{text:"before after"}]}], selection:{anchor:{path:[0,0],offset:7}, focus:{path:[0,0],offset:7}}, marks:null}); Editor.insertFragment(editor,[{type:"paragraph",children:[{text:"one"}]},{type:"paragraph",children:[{text:"two"}]}]); console.log(JSON.stringify(Editor.getSnapshot(editor)));'
Observed model:
before onetwoafter[1,0]@3Verdict: current source likely already satisfies the core #5089 model shape.
The execution lane should prove it with a durable test before claiming anything.
Target:
| Issue | Cluster | Claim | Why | Proof route | Live ledger sync | PR line |
|---|---|---|---|---|---|---|
| #5089 | clipboard-fragment-insertion-shape | fixes-claimed | Ready-now middle-paragraph multi-block fragment insertion bug. | package proof plus DOM clipboard boundary proof landed | live gitcrawl row read; fork dossier/matrix synced | fixed line added after proof |
Related/non-target:
| Issue | Claim | Reason |
|---|---|---|
| #4542 | Related | Empty-block nested-wrapper paste policy is broader and needs DOM/browser proof. Dossier refreshed. |
| #3155 | Related | General non-merging policy is broader than one middle-paragraph multi-block insertion. Dossier section added. |
| #5151 | Improves stays | Target-block preservation already has proof; not the same repro. |
| #5429 | Fixes stays | Empty-block caret placement is already closed by the previous lane. |
| #5412 | Fixes stays | Explicit at insertion is already closed by the previous lane. |
| #5080 | Deferred | Query traversal order is a separate core query owner. |
| #3891 | Deferred | Multi-node remove helper semantics are separate API design. |
| #5129 | Deferred | Replace/rewrap transform API is separate API design. |
ClawSweeper pass status: complete for the current surface.
#5089: fixed claim backed by package proof and DOM clipboard boundary
proof.#4542: kept related because nested-wrapper empty-block paste is broader.#3155: added as related because fragment non-merging policy is broader than
one middle-paragraph insertion shape.docs/slate-issues/gitcrawl-live-open-ledger.md status: generated live fields
read; no row mutation because claim status is not final and current claim sync
lives in the fork dossier and coverage matrix.
docs/slate-v2/references/pr-description.md: unchanged in pass 2 because exact
fixed claim status is not final.
Issue-ledger proof-route verdict:
Fixes #5089 because the original issue
is paste-framed even though the root owner is core fragment insertion.Editor.insertFragment preserves multi-block shape
at a collapsed middle text point;Fixes #5089 is now claimed.| Dimension | Score | Evidence |
|---|---|---|
| React 19.2 runtime performance | 0.90 | React is out of scope unless browser paste proof becomes required. |
| Slate-close unopinionated DX | 0.91 | Uses existing insertFragment / tx.fragment.insert; no new API. |
| Plate/slate-yjs migration backbone | 0.86 | Deterministic model shape helps collaboration, but collab proof is not required unless operations change. |
| Regression-proof testing strategy | 0.93 | Exact proof route is package core plus DOM clipboard boundary; browser proof is conditional on touched surface. |
| Research evidence completeness | 0.91 | Live gitcrawl, candidate maps, dossier rows, coverage matrix, prior clipboard plan, and source were read; no new external ecosystem claim is needed. |
| shadcn-style composability | 0.90 | No UI/component surface. |
Total: 0.93.
| Lens | Status | Reason | Current delta |
|---|---|---|---|
tdd | applies | #5089 is a behavior regression with a public insertion surface. | Red package proof first. |
performance-oracle | applied lightly | Fragment insertion must not flatten by building broad post-hoc normalization work. | Keep proof focused; no benchmark unless implementation changes complexity. |
performance | skipped | No benchmark/perf claim. | Revisit only if implementation touches hot large-paste paths. |
vercel-react-best-practices | skipped | No React render/subscription surface. | Revisit only if browser/example proof changes React path. |
build-web-apps:shadcn | skipped | No UI. | No change. |
react-useeffect | skipped | No effects. | No change. |
| Pass | Status | Evidence added | Plan delta | Open issues | Next owner |
|---|---|---|---|---|---|
| current-state read and candidate selection | complete | Read previous execution state, full issue ledger row, gitcrawl for #5089/#4542/#3155/#5080, candidate map, live insert-fragment.ts, and current tests; ran one live source probe. | Selected #5089; deferred #5080. | Full claim-proof route still pending. | ClawSweeper related-issue pass |
| related issue discovery | complete | Read gitcrawl threads, candidate maps, open issue dossiers, existing fork dossier, and coverage matrix for #5089/#4542/#3155. | Refreshed #5089/#4542 dossier text, added #3155 dossier section, and added #3155 related matrix row. | exact package-vs-paste proof bar unresolved | Issue ledger pass |
| issue-ledger pass | complete | Reviewed proof route against #5089 issue wording, candidate map, DOM clipboard boundary owner, and coverage matrix rules. | Requires package plus DOM clipboard boundary proof before Fixes; package-only proof can only improve. | none | Intent/decision pass |
| intent/boundary and decision brief | complete | Hardened scope, non-goals, and claim boundary. | Kept #4542/#3155 related and #5080 deferred. | none | Research/source refresh |
| research/source refresh | complete | Re-read live source/test owners and prior clipboard plan/matrix rows. | No new external ecosystem strategy needed; this is a local core/DOM proof lane. | none | pressure passes |
| objection/high-risk pass | complete | Added proof gate that prevents auto-close from package-only evidence. | Browser proof is conditional; DOM boundary proof is required for fixed claim. | none | closure |
| closure score | complete | Score 0.93, all dimensions >= 0.90 except migration 0.86 acceptable because no collab surface changes. | Ready for Ralph execution. | none | user review |
| Ralph execution | complete | Added exact package and DOM clipboard boundary proof; focused tests, package typechecks, and lint passed. | Moved #5089 to Fixes; kept #4542 and #3155 related; no source patch needed. | none | next Slate Ralplan |
Ralph execution is complete.
.tmp/slate-v2/packages/slate/test/clipboard-contract.ts for a multi-block
fragment inserted at [0,0]@7 in before after..tmp/slate-v2/packages/slate-dom/test/clipboard-boundary.ts for a rich
multi-block Slate fragment paste into the same middle text point..tmp/slate-v2/packages/slate/src/transforms-text/insert-fragment.ts was not
patched.#5089 moved to Fixes; #4542 and #3155 stay related.Verification:
bun test ./packages/slate/test/clipboard-contract.ts -t "multi-block"
bun test ./packages/slate-dom/test/clipboard-boundary.ts -t "multi-block"
bun --filter slate typecheck
bun --filter slate-dom typecheck
bun lint:fix
bun run completion-check
All passed on 2026-05-07.
.tmp/slate-v2/packages/slate/test/clipboard-contract.ts:
multi-block fragment inserted at [0,0]@7 in before after produces
before one and twoafter..tmp/slate-v2/packages/slate/src/transforms-text/insert-fragment.ts.Fixes #5089.bun test ./packages/slate/test/clipboard-contract.ts -t "multi-block"
bun test ./packages/slate-dom/test/clipboard-boundary.ts -t "fragment"
bun --filter slate typecheck
bun lint:fix
If browser proof is required:
PLAYWRIGHT_RETRIES=0 bunx playwright test playwright/integration/examples/huge-document.test.ts --project=chromium --grep "paste"
The exact browser command is provisional until the next pass confirms the available route.
| Change | Objection | Answer | Verdict |
|---|---|---|---|
Claim #5089 from package proof only | The issue is paste-framed; package proof could miss clipboard import behavior. | Require DOM clipboard boundary proof before Fixes. | keep |
Fold #4542 into this lane | Empty-block nested-wrapper paste is broader than middle-paragraph multi-block insertion. | Keep related until exact DOM/browser repro proof exists. | keep |
Fold #3155 into this lane | General non-merging policy needs broader structural fragment proof. | Keep related; this lane proves one concrete bug. | keep |
Jump to #5080 instead | Query reverse order is clean but isolated. | Defer it after the fragment cluster proof. | keep |
Editor.insertFragment / tx.fragment.insert;
no new API.insert-fragment.ts.Fixes #5089
line.#5089 selected; #4542 and #3155 related; #5080
deferred.This Ralplan is ready for user review only when:
#5089, #4542, and #3155.Fixes / Improves / Related route.>= 0.92 and no dimension is below 0.85..tmp/completion-checks/slate-v2-multiblock-fragment-middle-insert-ralplan.md
is done.Status: complete.