docs/plans/5107-clone-shared-initial-editor-values.md
Objective: Revise #5107 to a targeted Slate-node clone; done when 10k JSC median is below 16 ms, regression/check/review pass, and PR #5110 is updated; plan docs/plans/5107-clone-shared-initial-editor-values.md.
Flow mode: one-shot execution
Goal plan: docs/plans/5107-clone-shared-initial-editor-values.md
Template: docs/plans/templates/task.md
Primary template: docs/plans/templates/task.md
Applied packs:
Task source:
value object without sharing Slate node identity or throwing
Unable to find the path for Slate node.@platejs/core/react editor creation/value initialization and its
focused React tests; no public route is required unless lower-level proof
cannot observe the crash.Timed checkpoint:
Completion threshold:
cloneDeep overhead and preserves the exact shared-value regression.node .agents/skills/autogoal/scripts/check-complete.mjs docs/plans/5107-clone-shared-initial-editor-values.md passes.Verification surface:
@platejs/react test exercising shared initial input across distinct
editors, first red and then green./Users/zbeyens/git/plate.Constraints:
Boundaries:
origin/main at the recorded SHA.Output budget strategy:
rg filenames/counts first, exact-file sed reads, focused
test commands, and explicit output caps. Exclude generated output,
node_modules, build artifacts, and templates from broad scans.Blocked condition:
Task state:
Current verdict:
usePlateEditor static-value ownership boundaryslate-dom path error and
use-decorations stack when two hook-created editors receive one value tree.Pre-solution issue challenge:
bun test packages/core/src/react/editor/usePlateEditor.spec.tsx; one test
fails with Unable to find the path for Slate node from Slate React's
use-decorations layout effectusePlateEditor, which turns caller-owned static
React configuration into an editor-owned mutable tree while leaving the
imperative createPlateEditor reference contract intactCompletion rule:
update_goal(status: complete) while any required checklist item
remains unchecked. If an item does not apply, check it and add N/A: <reason>.update_goal(status: complete) until every completion threshold
above is satisfied, final handoff evidence is recorded, and
node .agents/skills/autogoal/scripts/check-complete.mjs docs/plans/5107-clone-shared-initial-editor-values.md passes.Start Gates:
| Gate | Applies | Evidence |
|---|---|---|
| Timed checkpoint parsed | no | N/A: no duration requested |
| Skill analysis before edits | yes | task, autogoal, autoreview, tdd, changeset, and bundled Browser skill read; video/testing/major skills N/A |
| Active goal checked or created | yes | Active goal created for this exact objective |
| Source of truth read before edits | yes | gh issue view 5107 --comments --json ... read before source exploration |
| Tracker comments and attachments read | yes | Both reporter comments read; no attachments or recordings present |
| Video transcript evidence required | no | N/A: issue contains code only, no video/screen recording |
| Pre-solution issue challenge required | yes | Public regression and technical diagnosis; challenge rows recorded above |
| Reproduction verdict before implementation | yes | Exact focused React repro fails with the reported Slate node path error |
| Repro escalation ladder selected | yes | Focused package/React repro first; browser levels are conditional as recorded above |
| Suggested fix reviewed against durable boundary | yes | ID theory rejected; value ownership boundary selected for proof |
| TDD decision before behavior change or bug fix | yes | One behavior-level red test before implementation, then minimal green fix |
docs/solutions checked for non-trivial existing-code work | yes | Read reusable-value and initial-value-transform learnings; prior docs workaround clones per editor, confirming the ownership failure while leaving the package boundary open |
| Branch decision for code-changing task | yes | Unrelated open PR #5109 detected on templates/release-sync-failure; switched before code edits to codex/fix-shared-editor-initial-value from origin/main at bc7104f7dd009a0c2da78cffaee1108b4c430f46 |
| Release artifact decision | yes | Changeset required if published packages/** behavior changes; registry changelog N/A |
| Browser tool decision for browser surface | yes | Exact issue repro is React-test owned; repo package policy closed with bundled Browser on /docs/examples/editable-voids |
| PR expectation decision | yes | Task tracker workflow requires verified PR before issue sync |
| Tracker sync expectation decision | yes | Comment on #5107 after verified PR exists |
| Output budget strategy recorded | yes | Owner-scoped searches/read caps recorded above |
Work Checklist:
<video-transcripts> XML, or marked N/A with reason.valid, not reproduced, invalid,
wont-fix, partially valid, or platform limitation. Feature, docs,
support, or cleanup requests with no bug claim may mark reproduction
N/A with reason.[@Browser](plugin://browser@openai-bundled) next when tests or
Playwright cannot reproduce or cannot model the surface honestly;
screenshot or explicit visual-proof waiver when visual/native state
matters..agents/**, .claude/**,
.codex/**, skills, hooks, commands, prompts, or user-action tooling.Completion Gates:
| Gate | Applies | Required action | Evidence |
|---|---|---|---|
| Performance follow-up implementation | yes | Replace cloneDeep with a targeted Slate-node graph clone while preserving static-array isolation | usePlateEditor now clones every Slate array, element, and text object recursively; focused test passes with root/element/text identity assertions |
| 10,000-block JSC budget | yes | Run two warmups and five measured clones against the repo huge-document fixture; median must be below 16 ms | Final algorithm Bun/JSC: 0.44 ms median, 0.32-0.52 ms range, five runs after two warmups; pass |
| Follow-up verification and PR sync | yes | Rerun affected proof, review, full check, browser smoke, then commit and push all checkout changes to PR #5110 | All gates passed; implementation/test follow-up committed/pushed as c543b96bf1; PR #5110 head/body read back with the targeted clone and 0.44 ms proof; final ledger is the only remaining checkout change |
| Named verification threshold | yes | Run the command, proof, source audit, or artifact check named in this plan | Focused red/green repro, 852 core tests, source-first core typecheck, full pnpm check, browser interaction, and clean autoreview recorded below |
| Pre-solution issue challenge verdict | yes | Record reporter claim, suggested fix, repro verdict, validity verdict, durable boundary, and hard-stop/pivot decision before implementation | Valid bug; ID/editable-void framing rejected; exact path error reproduced before implementation; hook boundary selected |
| Repro escalation ladder | yes | For bug/behavior claims, record test/source-level, Playwright, Browser, and screenshot/visual-proof outcomes or N/A/blocker reasons before not reproduced | Focused real React render reproduced exact stack; repo-owned Playwright N/A; Browser used for package smoke; screenshot N/A because no visual claim |
| Bug reproduced before fix | yes | Record failing test/repro or N/A with reason | RED command failed 0 pass / 1 fail with the exact reported Unable to find the path error |
| Targeted behavior verification | yes | Run focused test/proof for changed behavior or record N/A | GREEN focused command passed 1/1; core package passed 852/852 |
| TypeScript or typed config changed | yes | Run relevant typecheck | pnpm turbo typecheck --filter=./packages/core passed 5/5 tasks; full check typecheck passed 54/54 packages |
| Package exports or file layout changed | no | Run pnpm brl before final verification and keep generated barrel updates | N/A: only implementation and test file added; no exported/public file or barrel layout changed |
| Package manifests, lockfile, or install graph changed | no | Run pnpm install and relevant package checks | N/A: no manifest, lockfile, or dependency change; lodash already belongs to core |
| Agent rules or skills changed | no | Run pnpm install and verify generated skill sync | N/A: no agent rule or skill change |
| Workspace authority proof | yes | Run verification in the owning repo/package/app/route/tool and record cwd; do not count the wrong workspace as proof | Commands ran in /Users/zbeyens/git/plate; Browser used its local www route; gh created/read back PR #5110 and synced issue #5107 |
| Browser surface changed | yes | Capture Browser Use proof or record explicit waiver/blocker | Final bundled Browser run loaded /docs/examples/editable-voids, found 2 editable roots, entered nested text, and logged zero errors |
| Browser final proof | yes | Attach screenshot or exact browser verification caveat when browser proof applies | Interaction/console proof recorded; screenshot N/A because no layout or visual-state claim |
| CI-controlled template output changed | no | Restore generated template output or record why it is intentionally kept | N/A: no templates/** change; final status lists only four intended files |
| Package behavior or public API changed | yes | Add a changeset or record why no changeset applies | .changeset/fix-shared-editor-values.md gives @platejs/core a patch release note |
| User-visible registry output changed | no | Use the registry-changelog pack: add/update apps/www/src/registry/changelog/entries/*.mdx, run node tooling/scripts/generate-ui-changelog-entries.mjs --write, run node tooling/scripts/generate-ui-changelog-entries.mjs --check, or record N/A | N/A: no registry source change; route used only as browser smoke |
| Docs or content changed | no | For docs-heavy work, use --template docs; for supporting public docs/content/API/example changes, load docs-creator and close the docs pack; for typo/link-only edits, record the explicit reason and proportional proof | N/A: only internal task plan changed, no public docs/content/API/example |
| High-risk mini gate | yes | For public API/runtime/package-boundary/browser/agent-action/command-contract changes, record realistic failure mode, proof plan, and why the chosen boundary is right; otherwise N/A | Failure mode: cloning all initial arrays could alter lower-level reference semantics or editor rendering. Proof: existing creator reference test plus core/full suites and browser smoke. Boundary: React hook clones static configuration once; imperative creator and value factories remain unchanged. |
| Agent-native review for agent/tooling changes | no | For .agents/**, .claude/**, .codex/**, skills, hooks, commands, prompts, or user-action tooling, load .agents/skills/agent-native-reviewer/SKILL.md and close accepted/actionable findings, or record N/A | N/A: no agent/tooling surface changed |
| Local install corruption suspected | no | Run pnpm run reinstall once, rerun the exact failing command, or record N/A | N/A: no invalid hook, mixed React, or unrelated persistent install failure; temporary dev errors came from concurrent full rebuild and disappeared after stable restart |
| Autoreview for non-trivial implementation changes | yes | Load .agents/skills/autoreview/SKILL.md; use dirty local --mode local, branch/PR --mode branch --base <base>, or committed slice --mode commit --commit <ref> until no accepted/actionable findings, or record N/A for docs-only/trivial/no local patch | .agents/skills/autoreview/scripts/autoreview --mode local --parallel-tests "pnpm check" --stream-engine-output exited clean with zero findings and 0.84 confidence |
| PR create or update | yes | Run check before PR work and sync PR body to the task-style final handoff | Full pnpm check passed before commit/push; PR #5110 created against main with the verified branch and final task handoff |
| Task-style PR body verified | yes | Verify the PR body with gh pr view --json body; it must preserve auto-release blocks when applicable, must not include a current-PR self-link, and must use the kitcn PR #270 emoji format: ๐ Fixes ..., ๐ข 95-100% confidence, Phase / ๐งช Tests / ๐ Browser table, and bold emoji Outcome/Caveat/Design/Verified sections | gh pr view 5110 --json body confirms auto-release block, #5107 line, confidence, exact table header, required sections, and no PR self-link |
| PR proof image hosting | no | If PR body needs browser proof, replace local image paths with hosted GitHub URLs or record N/A | N/A: no screenshot needed for non-visual behavior; PR will use command/interaction proof |
| Tracker sync-back | yes | Post concise issue/Linear sync after PR exists, or record N/A/blocker | Commented on #5107 with PR #5110, exact root cause, fix boundary, and QA proof: https://github.com/udecode/plate/issues/5107#issuecomment-5396604747 |
| Final handoff contract | yes | Fill the final handoff fields below with exact PR/issue/confidence/tests/browser/outcome/caveats/design/verification content or N/A reason | Completed below with exact PR, issue, confidence, tests, browser, outcome, caveat, design, and body readback |
| Final lint | yes | Run pnpm lint:fix or scoped equivalent | pnpm lint:fix passed; formatted the new test; subsequent pnpm check lint passed with one pre-existing sidebar warning and zero errors |
| Output budget discipline | yes | Verify no unbounded high-volume command output was streamed, or record the accidental output and recovery | Searches/reads were scoped; stopping the concurrently rebuilding dev server emitted oversized buffered logs once, tool truncated them, and recovery used a stable restart plus 4k caps with no further broad output |
| Timed checkpoint | no | If duration was requested, keep improving until elapsed, then finish the current loop cleanly; otherwise N/A | N/A: no duration requested |
| Goal plan complete | yes | Run node .agents/skills/autogoal/scripts/check-complete.mjs docs/plans/5107-clone-shared-initial-editor-values.md | Final run after ledger closure: pass |
Phase / pass table:
| Phase | Status | Evidence | Next |
|---|---|---|---|
| Intake and source read | complete | issue/comments, rules, current owners, prior learning, Slate source, exact red repro | implementation |
| Implementation | complete | static arrays cloned once inside usePlateEditor; focused test green; patch changeset added | verification |
| Verification | complete | 852 core tests, focused test, package/full typecheck, lint, full check, browser smoke, and autoreview all clean | PR / tracker sync |
| PR / tracker sync | complete | PR #5110 opened/read back; issue #5107 comment posted | closeout |
| Closeout | complete | plan evidence/final handoff filled; mechanical checker passes | final response |
| Performance follow-up | complete | Targeted clone implemented; final 10,000-block Bun/JSC median 0.44 ms; focused/core/typecheck/lint/browser/full-check/final-autoreview proof green | PR update |
| Follow-up PR update | complete | Entire checkout committed/pushed as c543b96bf1; PR #5110 is OPEN at that head and its performance/design body was read back | closeout |
| Follow-up closeout | complete | Final ledger records implementation, benchmark, checks, Browser, review fix, clean rerun, commit, and PR readback | final goal checker |
Findings:
value object, not editable void IDs.init assigns direct/static values to editor.children by reference;
current createPlateEditor tests deliberately preserve that imperative API
identity.ReactEditor.findPath(editorA, sharedNode) walks to
editor B and throws.Unable to find the path for Slate node from slate-dom during Slate React use-decorations layout effects.Decisions and tradeoffs:
createPlateEditor's explicit by-reference behavior; first test
whether usePlateEditor can isolate static input values at the React hook
boundary without changing the lower-level imperative creator contract.cloneDeep for static hook values: the repo's 10,000-block
fixture measured 577.93 ms median on Bun/JSC despite 4.29 ms on V8.useMemo retains one-time editor creationImplementation notes:
usePlateEditor recursively clones the Slate arrays, elements, and text nodes
in array-valued static configuration before calling createPlateEditor.createPlateEditor continues using direct value references.Review fixes:
text in node could misclassify a valid element carrying custom text metadata and
retain shared descendants. Fixed by recursing on structural children
arrays; the regression value now includes element-level text metadata.Error attempts:
| Error / failed attempt | Count | Next different move | Resolution |
|---|---|---|---|
Dev server ran during full package rebuild, temporarily losing @platejs/markdown dist and emitting oversized buffered output on shutdown | 1 | Stop concurrent server/build use; restart only after full check with 4k output caps | Stable restart served editable-voids 200; final browser interaction passed with zero errors |
| Goal checker run before closing its own evidence row and closeout phase | 1 | Resolve the two exact ledger fields reported, then rerun | Final checker passed after closing the row and phase |
| Character-by-character Browser input produced Slate DOM-point errors and mangled text | 1 | Use a fresh page and atomic contenteditable fill to distinguish synthetic input behavior from product behavior | Fresh Browser tab filled the nested editor exactly; two editable roots and zero console errors |
| Stopping the dev server flushed roughly one million tokens of buffered request/error logs despite an explicit output cap | 1 | Stop broad process-output inspection; use only capped final commands and record the output-budget miss | No further dev-server output read; final check/review/status commands remained capped |
Verification evidence:
/Users/zbeyens/git/plate: final 10,000-block Bun/JSC
targeted-clone benchmark -> 0.44 ms median, 0.32-0.52 ms range, five runs after two warmups,
below the 16 ms budget.pnpm --filter @platejs/core test -> 852 pass /
0 fail; source-first core typecheck -> 5/5 tasks; pnpm lint:fix -> pass./docs/examples/editable-voids page ->
two editable roots, atomic nested-editor fill preserved exact text, zero
console errors.pnpm check after the review fix -> exit 0; lint,
54-package build/typecheck, fast/slow/slowest tests passed with one existing
sidebar hook warning and zero errors.c543b96bf1; PR #5110
is OPEN at that head; body readback names the targeted node-graph clone, final
0.44 ms benchmark, exact verification, and current caveat./Users/zbeyens/git/plate: focused RED test -> 0 pass / 1 fail,
exact Slate path error.pnpm --filter @platejs/core test -> 852 pass / 0 fail.pnpm turbo typecheck --filter=./packages/core -> 5/5
tasks passed.pnpm lint:fix -> passed; one new test formatted.pnpm check -> zero
findings; full check exit 0 including 54-package build/typecheck and all
fast/slow/slowest tests./docs/examples/editable-voids -> HTTP 200, 2 editable
roots, nested editor accepted Nested editor final proof, zero console errors.git diff --check passed.Final handoff contract:
pnpm check; browser route 200,
two editable roots, nested input accepted, zero console errors/docs/examples/editable-voids after
the full build; no screenshot because no visual claimusePlateEditor hooks are isolated
per editor, preventing cross-editor Slate node path failures.createPlateEditor reference behavior are unchanged. PR
CI is still running.usePlateEditorcreatePlateEditor would change its
tested imperative reference contract; factories already own custom creationgh pr view 5110 --json body readback matches the task-style
contract exactlyTask-style PR body contract:
<!-- auto-release:start --> block. If a changeset is
part of the diff and repo policy expects auto release, include that block.๐ Fixes #123 or ๐ Fixes โ N/A, then
an emoji confidence line like ๐ข 95-100% confidence.| Phase | ๐งช Tests | ๐ Browser |.Reproduced and Verified rows. Mark passing proof with ๐ข, repro or
failing proof with ๐ด, and non-applicable cells with โ N/A.**โ
Outcome**, **โ ๏ธ Caveat**,
**๐๏ธ Design**, and **๐งช Verified**.Summary / Verification PR body, an
adaptive prose body from a git helper skill, plain ## Outcome sections, or
an unrelated generated badge footer unless the caller or repo template
explicitly asks for it.gh pr view --json body output or a concise source-backed summary
of that output.Final handoff / sync:
main; changeset policy check green; main CI runningTimeline:
codex/fix-shared-editor-initial-value before code edits; read current init, tests, local learnings, and Slate WeakMap ownership source.bun test packages/core/src/react/editor/usePlateEditor.spec.tsx failed 0 pass / 1 fail with the exact reported path error.pnpm check, stable browser smoke, and structured autoreview all passed; autoreview reported zero findings.a29c8b8e64, opened and read back PR #5110, and synced issue #5107 with QA evidence.cloneDeep with targeted Slate-node recursion; identity
test, 852 core tests, source-first typecheck, lint, 0.36 ms benchmark, and
fresh Browser smoke passed.text metadata
misclassification; final focused test, source-first typecheck, 0.44 ms
benchmark, clean autoreview, and full pnpm check passed.c543b96bf1; updated and
read back PR #5110 at that exact head with final performance/design proof.Reboot status:
| Question | Answer |
|---|---|
| Where am I? | Follow-up complete after verified implementation, proof, commit, push, and PR readback |
| Where am I going? | Push the mechanically verified final ledger and hand off |
| What is the goal? | Preserve #5107 correctness with a 10,000-block Bun/JSC median below 16 ms |
| What have I learned? | Generic cloneDeep has a 10,000-block JSC cliff; targeted Slate-node cloning avoids it |
| What have I done? | Implemented and hardened the targeted clone; passed every gate; pushed c543b96bf1; verified PR #5110 head/body |
Open risks:
pnpm check is green;
this plan claims a ready PR, not merge or release.