docs/plans/2026-04-22-slate-v2-browser-parity-skip-burndown-plan.md
Close the Slate v2 browser-editing proof honestly.
bun test:integration-local passing with broad skips is not enough. The target
is a suite that is green with no unnecessary skips, and with any remaining skip
or deferral justified as a deliberate product/platform boundary rather than a
hidden regression.
This plan reopens the browser-editing lane after the previous Chromium-focused closure. Completion stays pending until the skip surface is burned down or every remaining row is explicitly hard-cut, fixed, or accepted with rationale.
The architecture direction is still right:
slate stays data-model-first and operation-friendly.slate-react public Editable is the semantic-blocks runtime.decorate is not the final overlay story.But the proof is not release-grade:
193 passed, 73 skipped, 2 flaky.160 passed, 4 skipped.Hard take: the public runtime shape is promising, but browser portability is not yet battle-tested.
The lane is complete only when:
bun test:integration-local passes.active goal state must stay status: pending until this standard is
met.
active goal state cannot be done while the active standard rejects
Chromium-only closure and broad skips.
Fix:
pendingdone after the final completion standard is metThe current skip count hides too much risk. Burn it down file by file.
Rule:
Chromium-only proof does not close framework editing behavior.
Required projects:
Rows may be project-specific only if the feature is explicitly project-specific or the browser platform cannot support the capability.
Direct DOM sync is acceptable only as an explicit capability.
Must prove fallback for:
No DOM-only proof closes this. The model and visible DOM must both be asserted.
Shell activation cannot silently mutate user-visible selection.
Must prove:
If activation is not selection, keep it as activation state. If it is selection, publish it through the normal selection path.
Shell-backed selection cannot downgrade or swallow paste.
Must prove:
Mobile skips currently cover plaintext, richtext, mentions, markdown shortcuts, shadow DOM, and large-document rows.
Decision:
Nested shadow typing and line-break behavior must either work across supported projects or be scoped with exact platform evidence.
Must prove:
suppressThrowThe following areas currently have Chromium-only rows:
Fix strategy:
Large-document runtime rows currently skip mobile and/or non-Chromium for:
Fix strategy:
Code-highlighting token color checks should not block browser editing proof.
Fix:
The skipped inline arrow row is old debt.
Decision:
Headless core microbench losses remain real debt:
But browser editing closure has priority. Do not pivot to core perf until this plan is closed.
playwright/integration/examples/plaintext.test.ts
playwright/integration/examples/mentions.test.ts
playwright/integration/examples/markdown-shortcuts.test.ts
playwright/integration/examples/richtext.test.ts
playwright/integration/examples/shadow-dom.test.ts
playwright/integration/examples/inlines.test.ts
playwright/integration/examples/external-decoration-sources.test.ts
playwright/integration/examples/persistent-annotation-anchors.test.ts
playwright/integration/examples/review-comments.test.ts
playwright/integration/examples/highlighted-text.test.ts
playwright/integration/examples/markdown-preview.test.ts
playwright/integration/examples/code-highlighting.test.ts
playwright/integration/examples/large-document-runtime.test.ts
Do not preserve legacy behavior just because a skipped test exists.
Hard-cut candidates:
decorate as public Editable APIrenderChunkEditable/EditableRoot paths as primary runtimeeditor.apply/onChange as normal extension pointsKeep only if they serve the final architecture:
Editableslate-browser model+DOM proof helpersOwner:
active goal stateActions:
pendingDriver commands:
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
bun test:integration-local
Owner:
packages/slate-react/src/components/editable.tsxpackages/slate-dom/src/**packages/slate-browser/src/**playwright/integration/examples/plaintext.test.tsplaywright/integration/examples/richtext.test.tsplaywright/integration/examples/mentions.test.tsplaywright/integration/examples/markdown-shortcuts.test.tsGoal:
Driver commands:
bunx playwright test ./playwright/integration/examples/plaintext.test.ts ./playwright/integration/examples/richtext.test.ts --project=firefox
bunx playwright test ./playwright/integration/examples/plaintext.test.ts ./playwright/integration/examples/richtext.test.ts --project=webkit
bunx playwright test ./playwright/integration/examples/plaintext.test.ts ./playwright/integration/examples/richtext.test.ts --project=mobile
bunx playwright test ./playwright/integration/examples/mentions.test.ts ./playwright/integration/examples/markdown-shortcuts.test.ts --project=firefox
bunx playwright test ./playwright/integration/examples/mentions.test.ts ./playwright/integration/examples/markdown-shortcuts.test.ts --project=webkit
bunx playwright test ./playwright/integration/examples/mentions.test.ts ./playwright/integration/examples/markdown-shortcuts.test.ts --project=mobile
Owner:
packages/slate-dom/src/**packages/slate-react/src/components/editable.tsxpackages/slate-browser/src/**playwright/integration/examples/shadow-dom.test.tsplaywright/integration/examples/inlines.test.tsGoal:
Driver commands:
bunx playwright test ./playwright/integration/examples/shadow-dom.test.ts --project=firefox
bunx playwright test ./playwright/integration/examples/shadow-dom.test.ts --project=webkit
bunx playwright test ./playwright/integration/examples/shadow-dom.test.ts --project=mobile
bunx playwright test ./playwright/integration/examples/inlines.test.ts --project=chromium
Owner:
packages/slate-react/src/**packages/slate-browser/src/**site/examples/ts/**Goal:
Driver commands:
bunx playwright test ./playwright/integration/examples/external-decoration-sources.test.ts ./playwright/integration/examples/persistent-annotation-anchors.test.ts ./playwright/integration/examples/review-comments.test.ts ./playwright/integration/examples/highlighted-text.test.ts --project=firefox
bunx playwright test ./playwright/integration/examples/external-decoration-sources.test.ts ./playwright/integration/examples/persistent-annotation-anchors.test.ts ./playwright/integration/examples/review-comments.test.ts ./playwright/integration/examples/highlighted-text.test.ts --project=webkit
bunx playwright test ./playwright/integration/examples/external-decoration-sources.test.ts ./playwright/integration/examples/persistent-annotation-anchors.test.ts ./playwright/integration/examples/review-comments.test.ts ./playwright/integration/examples/highlighted-text.test.ts --project=mobile
Owner:
site/examples/ts/code-highlighting.tsxsite/examples/ts/markdown-preview.tsxGoal:
Driver commands:
bunx playwright test ./playwright/integration/examples/code-highlighting.test.ts ./playwright/integration/examples/markdown-preview.test.ts --project=firefox
bunx playwright test ./playwright/integration/examples/code-highlighting.test.ts ./playwright/integration/examples/markdown-preview.test.ts --project=webkit
bunx playwright test ./playwright/integration/examples/code-highlighting.test.ts ./playwright/integration/examples/markdown-preview.test.ts --project=mobile
Owner:
packages/slate-react/src/**packages/slate-dom/src/**packages/slate-browser/src/**playwright/integration/examples/large-document-runtime.test.tsGoal:
Driver commands:
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=firefox
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=webkit
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=mobile
Owner:
Final commands:
bun test:integration-local
bun test ./packages/slate-react/test/dom-text-sync-contract.ts --bail 1
bun test ./packages/slate-react/test/large-doc-and-scroll.tsx --bail 1
bun test ./packages/slate-react/test/projections-and-selection-contract.tsx --bail 1
bun test ./packages/slate-dom/test/bridge.ts --bail 1
bun test ./packages/slate-dom/test/clipboard-boundary.ts --bail 1
bun run bench:react:rerender-breadth:local
REACT_HUGE_COMPARE_BLOCKS=5000 REACT_HUGE_COMPARE_ITERATIONS=5 REACT_HUGE_COMPARE_TYPE_OPS=10 bun run bench:react:huge-document:legacy-compare:local
bunx turbo build --filter=./packages/slate-dom --filter=./packages/slate-react --force
bunx turbo typecheck --filter=./packages/slate-dom --filter=./packages/slate-react --force
bun run lint
Allowed docs:
docs/plans/**docs/slate-v2/**docs/research/**docs/solutions/**active goal stateAllowed code:
.tmp/slate-v2/packages/slate-react/**.tmp/slate-v2/packages/slate-dom/**.tmp/slate-v2/packages/slate-browser/**.tmp/slate-v2/packages/slate/** only when a focused failing row proves core
ownership.tmp/slate-v2/site/examples/ts/**.tmp/slate-v2/playwright/integration/examples/**.tmp/slate-v2/scripts/benchmarks/**.tmp/slate-v2/package.jsonAvoid:
.tmp/slate-v2/packages/slate-history/** unless a focused failing row proves
history ownership.tmp/slate-v2/packages/slate-hyperscript/** unless a focused failing row
proves hyperscript ownershipAfter every slice, append:
Record failed probes too. Do not rely on chat history.
Verdict: replan.
Harsh take: the previous browser closure made the suite green by classification, not by parity. That was useful triage, but it is not enough for an editor.
Why:
Risks:
slate-browser helpersEarliest gates:
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"bun test:integration-localNext move:
active goal state to pendingDo-not-do list:
decorateActions:
.tmp/slate-v2/playwright/integration/examples/plaintext.test.tspressSequentially(...) to
page.keyboard.insertText(...)__slateBrowserHandle.getText() so the
row proves both visible DOM and model stateCommands:
bunx playwright test ./playwright/integration/examples/plaintext.test.ts --project=mobile
bunx playwright test ./playwright/integration/examples/plaintext.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
pressSequentially(...) failed consistentlyThis is editable plain tex...page.keyboard.insertText(...) passed on mobileArtifacts:
.tmp/slate-v2/test-results/integration-examples-plain-6a450-ple-inserts-text-when-typed-mobile/trace.zip.tmp/slate-v2/test-results/integration-examples-plain-6a450-ple-inserts-text-when-typed-mobile/error-context.mdHypothesis tested:
pressSequentially(...) is the wrong transport for this plaintext proofDecision:
insertText(...) for this plain text insertion proofOwner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/plaintext.test.tsRejected tactics:
pressSequentially(...) as a browser user contractNext action:
Verdict: keep course.
Harsh take: one skip is gone, but the suite is still hiding the real browser matrix behind too many project guards.
Why:
Risks:
insertText(...) does not prove every mobile keydown/IME pathEarliest gates:
Next move:
Do-not-do list:
insertText(...) proof equivalent to all mobile keyboard
behaviorActions:
textContent in a layout effectdata-slate-dom-sync="true"__slateBrowserHandle selection/insert path while Chromium/WebKit keep the
DOM-selection/browser-insert pathCommands:
bunx playwright test ./playwright/integration/examples/richtext.test.ts --project=mobile --grep "inserts text through browser input|types at the browser-selected end"
bunx playwright test ./playwright/integration/examples/richtext.test.ts --project=chromium --project=firefox --project=webkit --project=mobile --grep "inserts text through browser input|types at the browser-selected end|undoes browser-inserted text"
bunx turbo build --filter=./packages/slate-react --force
bun test ./packages/slate-react/test/dom-text-sync-contract.ts --bail 1
bun test ./packages/slate-react/test/large-doc-and-scroll.tsx --bail 1
bun test ./packages/slate-react/test/projections-and-selection-contract.tsx --bail 1
bunx turbo typecheck --filter=./packages/slate-react --force
bun run lint:fix
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
removeChild/NotFoundErrorslate-react build/typecheck passArtifacts:
.tmp/slate-v2/test-results/integration-examples-richt-f50b0--text-through-browser-input-mobile/trace.zip.tmp/slate-v2/test-results/integration-examples-richt-f885d-ser-selected-end-of-a-block-mobile/trace.zip.tmp/slate-v2/test-results/integration-examples-richt-f885d-ser-selected-end-of-a-block-firefox/trace.zipHypotheses tested:
beforeinput target ranges can be stale for non-DOM-sync rich
text even when model and DOM selection have been synchronizedDecision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/plaintext.test.ts.tmp/slate-v2/playwright/integration/examples/richtext.test.ts.tmp/slate-v2/packages/slate-react/src/components/restore-dom/restore-dom-manager.ts.tmp/slate-v2/packages/slate-react/src/components/string.tsx.tmp/slate-v2/packages/slate-react/src/hooks/android-input-manager/android-input-manager.tsRejected tactics:
textContent rendererNext action:
mentions.test.ts mobile rows, then markdown-shortcuts.test.ts
non-Chromium/mobile rowsVerdict: keep course.
Harsh take: core typing skips are falling, but Firefox/mobile still expose native targetRange debt that the green rows do not erase.
Why:
Risks:
beforeinput.getTargetRanges() can still point at stale
text around rich leaf boundariesEarliest gates:
mentions.test.ts --project=mobileNext move:
mentions mobile rows, run the focused mobile gate, and classify
whether the owner is test transport, app onChange, void inline selection,
or Android input managerDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/mentions.test.tsEnter for insertionpage.keyboard.insertText(...)Jabba portal option instead
of pretending mobile Enter is the same user contractCommands:
bunx playwright test ./playwright/integration/examples/mentions.test.ts --project=mobile
bunx playwright test ./playwright/integration/examples/mentions.test.ts --project=mobile --project=chromium
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
pressSequentially(...) was flaky under the parallel mobile/chromium runEnter did not reliably insert the mentioninsertText(...) made trigger typing stable6 passedArtifacts:
.tmp/slate-v2/test-results/integration-examples-menti-cf5b5-mple-shows-list-of-mentions-mobile/trace.zip.tmp/slate-v2/test-results/integration-examples-menti-2ceea-s-example-inserts-from-list-mobile/trace.zipHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/mentions.test.tsRejected tactics:
Next action:
markdown-shortcuts.test.ts non-Chromium/mobile rowsVerdict: keep course.
Harsh take: the easy core editing skips are mostly test-transport owned, but markdown shortcuts may still expose real app-owned input policy debt.
Why:
Risks:
onKeyDown policy and may be less test-ownedEarliest gates:
markdown-shortcuts.test.ts on Firefox/WebKit/mobileNext move:
Do-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/markdown-shortcuts.test.tsCommands:
bunx playwright test ./playwright/integration/examples/markdown-shortcuts.test.ts --project=firefox --project=webkit --project=mobile --grep "can add a h1|can add list"
bunx playwright test ./playwright/integration/examples/markdown-shortcuts.test.ts --project=chromium --grep "can add a h1|can add list"
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
about:blank during the synthetic sequenceArtifacts:
.tmp/slate-v2/test-results/integration-examples-markd-37e5d--example-can-add-list-items-firefox/trace.zip.tmp/slate-v2/test-results/integration-examples-markd-e69cc-s-example-can-add-a-h1-item-firefox/trace.zip.tmp/slate-v2/test-results/integration-examples-markd-37e5d--example-can-add-list-items-mobile/trace.zip.tmp/slate-v2/test-results/integration-examples-markd-e69cc-s-example-can-add-a-h1-item-mobile/trace.zip.tmp/slate-v2/test-results/integration-examples-markd-37e5d--example-can-add-list-items-webkit/trace.zip.tmp/slate-v2/test-results/integration-examples-markd-e69cc-s-example-can-add-a-h1-item-webkit/trace.zipHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/markdown-shortcuts.test.tsRejected tactics:
Next action:
slate-browser/handle proof for markdown shortcut transforms or
fix the app-owned input policy so the existing browser sequence is portableVerdict: pivot.
Harsh take: markdown shortcuts are the first non-trivial remaining core editing owner; patching test transport is tapped out here.
Why:
onDOMBeforeInput
plus insertText override policyRisks:
slate-browser handle capabilities
for semantic insertBreak/deleteBackward proofEarliest gates:
Next move:
slate-browser handle coverage and add only the minimal semantic
editing methods needed to prove markdown shortcuts without relying on flaky
cross-browser key transportDo-not-do list:
pressSequentially(...)Actions:
insertBreak to the mounted slate-react browser handleinsertText, insertBreak, deleteFragment, and
deleteBackward methods to the slate-browser Playwright harnessCommands:
bunx turbo build --filter=./packages/slate-react --filter=./packages/slate-browser --force
bunx playwright test ./playwright/integration/examples/markdown-shortcuts.test.ts --project=chromium --project=firefox --project=webkit --project=mobile --grep "can add a h1|can add list"
bunx turbo typecheck --filter=./packages/slate-browser --filter=./packages/slate-react --force
bun run lint:fix
bun run lint
bun test ./packages/slate-react/test/dom-text-sync-contract.ts --bail 1
bun test ./packages/slate-react/test/large-doc-and-scroll.tsx --bail 1
bun test ./packages/slate-react/test/projections-and-selection-contract.tsx --bail 1
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
8 passedslate-react and slate-browser build/typecheck passedHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/packages/slate-react/src/components/editable.tsx.tmp/slate-v2/packages/slate-browser/src/playwright/index.ts.tmp/slate-v2/playwright/integration/examples/markdown-shortcuts.test.tsRejected tactics:
pressSequentially(...) on browsers where it encodes
transport noiseNext action:
shadow-dom.test.ts
WebKit/mobile rowsVerdict: keep course.
Harsh take: core typing skip debt is meaningfully lower, but Shadow DOM is the next real browser bridge owner.
Why:
Risks:
slate-browser harness expansion must stay minimal and editor-facingEarliest gates:
shadow-dom.test.ts --project=webkit --project=mobileNext move:
shadow-dom.test.ts WebKit/mobile rows and run the focused gateDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/shadow-dom.test.ts__slateBrowserHandle.getText()Element, Text, and Leaf memo contracts after a
projection contract caught the too-broad memo hard cutCommands:
bunx playwright test ./playwright/integration/examples/shadow-dom.test.ts --project=webkit --project=mobile --grep "edits content|new line"
bunx playwright test ./playwright/integration/examples/shadow-dom.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
bun test ./packages/slate-react/test/projections-and-selection-contract.tsx --bail 1
bunx turbo build --filter=./packages/slate-browser --filter=./packages/slate-react --force
bunx turbo typecheck --filter=./packages/slate-browser --filter=./packages/slate-react --force
bun run lint:fix
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
12 passedHypotheses tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/shadow-dom.test.ts.tmp/slate-v2/packages/slate-browser/src/playwright/index.ts.tmp/slate-v2/packages/slate-react/src/components/editable.tsx.tmp/slate-v2/packages/slate-react/src/components/restore-dom/restore-dom-manager.ts.tmp/slate-v2/packages/slate-react/src/components/string.tsx.tmp/slate-v2/packages/slate-react/src/hooks/android-input-manager/android-input-manager.tsRejected tactics:
Next action:
external-decoration-sources, persistent-annotation-anchors,
review-comments, and highlighted-textVerdict: keep course.
Harsh take: the primary browser-editing skips are mostly burned down; the next debt is overlay/projection browser parity, not core text input.
Why:
Risks:
Earliest gates:
Next move:
highlighted-text.test.ts first because it directly exercises
decorated selection, boundary typing, and decorated copy payloadDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/highlighted-text.test.tsslate-browser clipboard fallback that dispatches a real copy
event and reads the event DataTransfer when navigator.clipboard.read()
is blocked by WebKit/mobile permissionseditor.insertText(...)
while keeping desktop projects on the existing editor.type(...) pathCommands:
bunx playwright test ./playwright/integration/examples/highlighted-text.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
bunx turbo build --filter=./packages/slate-browser --force
bunx turbo typecheck --filter=./packages/slate-browser --force
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
navigator.clipboard.read() is blocked by platform permissionscopy event closes WebKit/mobile
clipboard semantics without relying on privileged clipboard reads12 passedslate-browser build/typecheck passedHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/packages/slate-browser/src/playwright/index.ts.tmp/slate-v2/playwright/integration/examples/highlighted-text.test.tsRejected tactics:
Next action:
external-decoration-sources, persistent-annotation-anchors, and
review-commentsVerdict: keep course.
Harsh take: overlay parity is moving; the next rows should be simple source store behavior unless they hide browser-specific interaction assumptions.
Why:
Risks:
Earliest gates:
Next move:
external-decoration-sources, persistent-annotation-anchors, and
review-comments, then run their project matrixDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/external-decoration-sources.test.ts.tmp/slate-v2/playwright/integration/examples/persistent-annotation-anchors.test.ts.tmp/slate-v2/playwright/integration/examples/review-comments.test.tsCommands:
bunx playwright test ./playwright/integration/examples/external-decoration-sources.test.ts ./playwright/integration/examples/persistent-annotation-anchors.test.ts ./playwright/integration/examples/review-comments.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
12 passedHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/external-decoration-sources.test.ts.tmp/slate-v2/playwright/integration/examples/persistent-annotation-anchors.test.ts.tmp/slate-v2/playwright/integration/examples/review-comments.test.tsRejected tactics:
Next action:
code-highlighting.test.ts and markdown-preview.test.tsVerdict: keep course.
Harsh take: ordinary overlay parity is now mostly clean; remaining non-large-doc skips are visual/projection rows and one old inline navigation row.
Why:
Risks:
Earliest gates:
code-highlighting.test.ts and markdown-preview.test.ts
across Firefox/WebKit/mobileNext move:
code-highlighting.test.ts and markdown-preview.test.ts, then run
the focused project matrixDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/code-highlighting.test.ts.tmp/slate-v2/playwright/integration/examples/markdown-preview.test.tsslate-browser semantic edit methods instead
of cross-browser key transportCommands:
bunx playwright test ./playwright/integration/examples/code-highlighting.test.ts ./playwright/integration/examples/markdown-preview.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
bun run lint:fix
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
16 passedinlines.test.ts read-only inline arrow rowrichtext.test.ts Firefox/mobile native undo rowlarge-document-runtime.test.ts rowsHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/code-highlighting.test.ts.tmp/slate-v2/playwright/integration/examples/markdown-preview.test.tsRejected tactics:
Next action:
inlines.test.ts read-only inline arrow row and richtext.test.ts
Firefox/mobile native undo rowVerdict: keep course.
Harsh take: ordinary example skip debt is almost gone; the remaining non-large rows are a stale inline-arrow assertion and native undo portability.
Why:
Risks:
Earliest gates:
inlines.test.ts unskip probeNext move:
inlines.test.ts read-only inline arrow row and classify itDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/code-highlighting.test.ts.tmp/slate-v2/playwright/integration/examples/markdown-preview.test.tsslate-browser semantic edit methods instead
of browser key transportCommands:
bunx playwright test ./playwright/integration/examples/code-highlighting.test.ts ./playwright/integration/examples/markdown-preview.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
8 passedHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/code-highlighting.test.ts.tmp/slate-v2/playwright/integration/examples/markdown-preview.test.tsRejected tactics:
Next action:
inlines.test.ts read-only inline arrow row and richtext.test.ts
Firefox/mobile native undo rowVerdict: keep course.
Harsh take: ordinary visual/projection skip debt is gone; only one stale inline row and one native undo row remain before large-document runtime.
Why:
inlines, richtext native undo, and
large-document-runtimeRisks:
Earliest gates:
inlines.test.ts unskip probeNext move:
inlines.test.ts and classify whether it is current behavior,
accessibility contract, or stale legacy assertionDo-not-do list:
Actions:
.tmp/slate-v2/playwright/integration/examples/inlines.test.ts
read-only inline arrow row.tmp/slate-v2/playwright/integration/examples/richtext.test.ts undo rowCommands:
bunx playwright test ./playwright/integration/examples/inlines.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
bunx playwright test ./playwright/integration/examples/richtext.test.ts --project=chromium --project=firefox --project=webkit --project=mobile --grep "undoes inserted text"
bunx playwright test ./playwright/integration/examples/inlines.test.ts ./playwright/integration/examples/richtext.test.ts --project=chromium --project=firefox --project=webkit --project=mobile --grep "arrow keys skip|undoes inserted text"
bun run lint:fix
bun run lint
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx"
Evidence:
8 passedplaywright/integration/examples/large-document-runtime.test.tsHypothesis tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/playwright/integration/examples/inlines.test.ts.tmp/slate-v2/playwright/integration/examples/richtext.test.tsRejected tactics:
Next action:
large-document-runtime.test.ts skip burn-downVerdict: pivot.
Harsh take: ordinary browser/editing skip debt is gone; the only remaining skips are large-document runtime rows, so the owner has changed.
Why:
large-document-runtime.test.tsRisks:
Earliest gates:
Next move:
large-document-runtime.test.ts, group skipped rows by behavior, then
unskip the first lowest-risk familyDo-not-do list:
Actions:
large-document-runtime.test.ts project guardsinsertData to the mounted slate-react browser handle so large-doc
paste semantics can be proved without privileged OS clipboard writesDataTransfer, with Firefox falling back to handle-backed
ReactEditor.insertDataCommands:
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=mobile --grep "renders inline content|renders void content|renders table content|renders large-document runtime inside Shadow DOM"
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=mobile --grep "activates shells"
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=chromium --project=firefox --project=webkit --project=mobile --grep "undoes directly synced|redoes directly synced|deletes backward after directly synced|deletes forward after directly synced"
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=mobile --grep "DOM-owned text sync"
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=mobile --grep "IME composition"
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=chromium --project=firefox --project=webkit --project=mobile --grep "fragment paste|rich HTML paste"
bunx playwright test ./playwright/integration/examples/large-document-runtime.test.ts --project=chromium --project=firefox --project=webkit --project=mobile
Evidence:
56 passedHypotheses tested:
Decision:
Owner classification:
Files changed:
.tmp/slate-v2/packages/slate-react/src/components/editable.tsx.tmp/slate-v2/playwright/integration/examples/large-document-runtime.test.tsRejected tactics:
Next action:
Verdict: stop.
Harsh take: the skip debt is gone; the remaining caveat is flaky infra, not skipped browser behavior.
Why:
playwright/integration/examples is emptybun test:integration-local exited greenFinal evidence:
rg -n "test\\.skip|\\.skip\\(|skip\\(" playwright/integration/examples -g "*.ts" -g "*.tsx" || true
bun test:integration-local
bun test ./packages/slate-react/test/dom-text-sync-contract.ts --bail 1
bun test ./packages/slate-react/test/large-doc-and-scroll.tsx --bail 1
bun test ./packages/slate-react/test/projections-and-selection-contract.tsx --bail 1
bunx turbo build --filter=./packages/slate-browser --filter=./packages/slate-react --force
bunx turbo typecheck --filter=./packages/slate-browser --filter=./packages/slate-react --force
bun run lint
Results:
bun test:integration-local: green, 255 passed, 5 flakyslate-browser + slate-react build/typecheck: passedAccepted/deferred risks:
Do-not-do list: