docs/plans/2026-05-28-add-prosemirror-runtime-adapter-to-evidence-kit.md
Objective: Add the first non-Slate runtime adapter to the Evidence Kit rich-text benchmark matrix by measuring ProseMirror headless model/state/history operations, wiring the adapter into the active registry, refreshing generated perf artifacts, and proving the adapter gap count decreases with real rows.
Goal plan: docs/plans/2026-05-28-add-prosemirror-runtime-adapter-to-evidence-kit.md
Template: docs/plans/templates/major-task.md
Primary template: docs/plans/templates/major-task.md
Applied packs:
Major source:
benchmarks/editor/research/benchmark-registry.jsonMajor lane:
benchmarks/editor, generated perf docs, goal
planCompletion threshold:
npm run bench:adapter:prosemirror writes at least seven ok rows.ok only for the covered
headless workload families.npm run evidence:refresh refreshes docs, health, and rich-text results.54 to 51; active artifacts rise from 23
to 24; rich-text rows rise from 904 to 911.node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-28-add-prosemirror-runtime-adapter-to-evidence-kit.md
passes.Verification surface:
/Users/zbeyens/git/plate-2/benchmarks/editornpm run bench:adapter:prosemirrornpm run evidence:refreshnpm run docs:perf:checkbenchmarks/results/benchmark-health-latest.jsonbenchmarks/results/rich-text-editors-latest.jsonConstraints:
Boundaries:
benchmarks/editor/research/benchmark-registry.json.../prosemirror source root exists.http://127.0.0.1:8765/index.html.Blocked condition:
Major state:
update_goal callCurrent verdict:
Completion rule:
update_goal(status: complete) until every completion threshold
above is satisfied, final evidence is recorded, and the autogoal
check-complete command passes.Start Gates:
| Gate | Applies | Evidence |
|---|---|---|
major-task loaded | yes | task classified as heavyweight benchmark adapter work |
| Active goal checked or created | yes | active goal created for the adapter threshold |
| Source of truth read before analysis | yes | registry, README, source map, and generated perf output inspected |
| Major lane selected | yes | editor benchmark infrastructure |
| Decision criteria stated | yes | source-backed target, active artifact, measured rows, refreshed docs/health |
| Existing repo patterns / prior decisions checked | yes | prior iterations 002, 003, and 004 pattern followed |
| Helper stack selected | yes | local Node script plus Evidence Kit registry |
| External research decision recorded | yes | no web research; local source/dependencies suffice |
| Implementation expectation recorded | yes | implementation required |
| Workspace authority selected | yes | /Users/zbeyens/git/plate-2/benchmarks/editor owns commands |
| Branch / PR expectation decided | yes | no PR requested |
Work Checklist:
Completion Gates:
| Gate | Applies | Required action | Evidence |
|---|---|---|---|
| Named verification threshold | yes | Run adapter and refresh commands | npm run bench:adapter:prosemirror; npm run evidence:refresh |
| Current-state source audit | yes | Map current owner, boundaries, constraints, and affected surfaces | registry, README, source map, iterations inspected |
| Decision criteria closure | yes | Mark each criterion satisfied, narrowed, rejected, or blocked with evidence | ProseMirror selected for headless runtime coverage only |
| Options / tradeoffs / rejection record | yes | Record viable options, chosen recommendation, and why alternatives lose | ProseMirror first; Lexical/Plate/Tiptap deferred due larger wrapper/runtime surfaces |
| Review / pressure pass | yes | Validate no overclaiming against workload coverage | browser/React/collab ProseMirror rows remain adapter-missing |
| Review findings closure | yes | Fix or explicitly reject accepted/actionable findings and record closure proof | source-map and README updated to stop saying ProseMirror is entirely missing |
| External-source audit | yes | Cite official/local clone/external sources when used, or record N/A | local ../prosemirror exists; npm ProseMirror packages imported |
| Implementation gates | yes | Close primary-template and touched-surface gates | adapter, registry, package scripts, generated docs/results updated |
| Final handoff contract | yes | Record recommendation, evidence, caveats, residual risk, and next owner | see Final handoff contract |
| Final lint | yes | Run scoped equivalent when files changed | scoped syntax/lint command recorded below |
| Goal plan complete | yes | Run node .agents/rules/autogoal/scripts/check-complete.mjs docs/plans/2026-05-28-add-prosemirror-runtime-adapter-to-evidence-kit.md | recorded below |
Phase / pass table:
| Phase | Status | Evidence | Next |
|---|---|---|---|
| Intake and source read | complete | registry/source-map/README/iterations inspected | current-state map |
| Current-state map | complete | ProseMirror had source target but no measured runtime rows | options |
| Options and recommendation | complete | ProseMirror chosen as headless runtime adapter; Lexical/Plate/Tiptap deferred | review |
| Review / pressure pass | complete | coverage limited to three headless workloads | implementation |
| Implementation or plan artifact | complete | adapter script, registry, package scripts, docs, generated artifacts updated | verification |
| Verification | complete | focused commands recorded below | closeout |
| Closeout | complete | final handoff prepared | final response |
Findings:
runtimeAdapters instead of hard-coding every target in the row generator.Decisions and tradeoffs:
prosemirror-model,
prosemirror-state, and prosemirror-history.ok; that would be fake
coverage.Implementation notes:
benchmarks/editor/benchmarks/prosemirror-runtime-adapter.mjs.bench:adapter:prosemirror and wired it into bench:evidence,
evidence:refresh, and check.runtimeAdapters metadata and required
prosemirror-runtime-adapter artifact.Review fixes:
adapter-missing.Error attempts:
| Error / failed attempt | Count | Next different move | Resolution |
|---|---|---|---|
| None | 0 | none | no repeated failure |
Verification evidence:
npm install --save-dev prosemirror-model prosemirror-state prosemirror-transform prosemirror-history from /Users/zbeyens/git/plate-2/benchmarks/editor: success.npm run bench:adapter:prosemirror from /Users/zbeyens/git/plate-2/benchmarks/editor: success; wrote 7 rows.node --check benchmarks/prosemirror-runtime-adapter.mjs && node --check src/index.mjs from /Users/zbeyens/git/plate-2/benchmarks/editor: success.npm run evidence:refresh from /Users/zbeyens/git/plate-2/benchmarks/editor: success; generated 911 rich-text rows and health active=24.npm run docs:perf:check from /Users/zbeyens/git/plate-2/benchmarks/editor: success; checked index, evidence, rich-text, and internals docs.pnpm exec biome check benchmarks/editor/benchmarks/prosemirror-runtime-adapter.mjs benchmarks/editor/src/index.mjs benchmarks/editor/package.json benchmarks/editor/research/benchmark-registry.json benchmarks/editor/README.md benchmarks/editor/research/evidence-source-map.md benchmarks/editor/iterations/005-prosemirror-runtime-adapter.md docs/plans/2026-05-28-add-prosemirror-runtime-adapter-to-evidence-kit.md --fix from /Users/zbeyens/git/plate-2: success; fixed one file./Users/zbeyens/git/plate-2: http://127.0.0.1:8765/index.html, rich-text.html, and rich-text-data.json all returned 200.ok=728, adapter-missing=51, coverage-gap=130,
optional-missing-artifact=2.ok for
core-rich-text-operations-compare, clipboard-large-payload, and
history-compare; adapter-missing remains for React, browser, collab,
core-current/core-compare, and issue #6038 workloads.Final handoff contract:
http://127.0.0.1:8765/index.html.Timeline:
Reboot status:
| Question | Answer |
|---|---|
| Where am I? | Closeout |
| Where am I going? | Final verification, goal completion, response |
| What is the goal? | Add the next non-Slate runtime adapter |
| What have I learned? | ProseMirror can close three headless workload gaps without overclaiming browser/product coverage |
| What have I done? | Added adapter, registry metadata, scripts, generated evidence, docs, and iteration note |
Open risks: