docs/editor-behavior/markdown-parity-matrix.md
This is the major-release coverage gate for Plate's existing editor features.
Despite the filename, this file is no longer only about markdown-native constructs. The major can break any existing content-affecting feature, so the matrix needs to track:
Use this with:
This file is not the exhaustive scenario matrix. It answers:
Use the strongest external precedent available for each concrete surface.
This family table is routing guidance only. It does not pre-decide every row.
| Family | Common Parse / Serialize Candidates | Common UX Candidates | Common Cross-Checks / Adjacent Refs | Fallback |
|---|---|---|---|---|
| Markdown-native syntax | CommonMark / GFM / GitHub Docs for GFM-only constructs / LaTeX-style math / MDX when applicable | Typora when the concrete surface really matches markdown-first editing intent | Milkdown, GitHub Docs, or other stronger surface-specific refs | explicit repo decision only if refs disagree or are silent |
| Markdown mode architecture and note-linked navigation | current serialized shape or editor-only contract where needed | Obsidian when the concrete surface is truly dual-mode or note-linked | Google Docs, Typora, or other stronger navigation refs | fallback only when stronger navigation precedent runs out |
| Block-editor-native elements | feature's current serialized shape or explicit non-markdown contract | Notion when the concrete element actually matches block-editor-native behavior | Milkdown, then the strongest adjacent mainstream precedent | fallback only when no clear external standard exists |
| Tables and linear document editing | GFM / HTML table rules when applicable | Google Docs when the concrete surface is really document/table behavior | Obsidian, Notion, Milkdown, or another stronger row-level ref | fallback only after stronger table precedent runs out |
| Collaboration and reviewing | current serialized shape or editor-only contract | Google Docs when the concrete collaboration surface matches review-style behavior | Notion or the stronger collaboration precedent for the row | fallback only after stronger collaboration precedent runs out |
| Styling and layout | current serialized shape plus HTML / CSS expectations where relevant | Google Docs when the concrete styling surface matches document-style editing | Notion or the stronger adjacent precedent for the row | fallback only after stronger styling precedent runs out |
locked: strong enough to build on without blocking the majorpartial: existing feature works, but the contract or coverage is still thingap: existing feature is under-specified, lossy, or weakly coveredprofile-divergence: existing feature works, but it is outside the strict markdown-first profile and still needs explicit behavior policydeferred-minor: not part of this major even though the parser or docs mention itThis file tracks existing content-affecting surfaces only.
It does not try to gate:
Node Model / Affinity records whether the feature is void plus its inline
affinity class when one existsBehavior Scope is the user-facing behavior that must be spec'dCurrent Evidence lists representative seams, not every testNext Work is the concrete remaining work for the major laneEditing Spec IDs should point to concrete spec IDs or the pending family ID| Feature | Family | Node Model / Affinity | Parse Authority | Primary UX Ref | Secondary Ref | Behavior Scope | Editing Spec IDs | Current Evidence | Next Work | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| Paragraph | markdown-native | block non-void; n/a | CommonMark | Typora | Milkdown | ↵, ⌫, ⇥, ⇤, root-empty behavior | EDIT-P-* | packages/markdown/src/lib/deserializer/deserializeMd.spec.ts | ||
packages/indent/src/lib/withIndent.spec.tsx | ||||||||||
apps/www/src/__tests__/package-integration/markdown-rich/serializeMd.spec.tsx | finish explicit non-empty root ⌫ fallback | locked | ||||||||
| Heading | markdown-native | block non-void; n/a | CommonMark | Typora | Milkdown | split, reset, depth-specific behavior | EDIT-H-* | packages/markdown/src/lib/deserializer/deserializeMd.spec.ts | ||
packages/markdown/src/lib/serializer/convertNodesSerialize.spec.ts | ||||||||||
packages/core/src/lib/plugins/override/withBreakRules.spec.tsx | ||||||||||
packages/core/src/lib/plugins/override/withDeleteRules.spec.tsx | no active major blocker | locked | ||||||||
| Blockquote | markdown-native | block non-void container; n/a | CommonMark | Typora | Milkdown | nested blocks, empty exit, ⌫, ⇤, quoted list interaction | EDIT-BQ-* | packages/markdown/src/lib/deserializer/deserializeMd.spec.ts | ||
packages/markdown/src/lib/commonmarkSurface.spec.ts | ||||||||||
packages/core/src/lib/plugins/override/withBreakRules.spec.tsx | ||||||||||
packages/core/src/lib/plugins/override/withDeleteRules.spec.tsx | no active major blocker | locked | ||||||||
| Unordered list | markdown-native | block non-void container; n/a | CommonMark | Typora | Milkdown | split, exit, outdent, quoted-list interaction | EDIT-LIST-* | packages/markdown/src/lib/deserializer/deserializeMdList.spec.tsx | ||
packages/list/src/lib/withList.spec.tsx | ||||||||||
packages/core/src/lib/plugins/override/withDeleteRules.spec.tsx | richer mixed-document editing matrices | locked | ||||||||
| Ordered list | markdown-native | block non-void container; n/a | CommonMark | Typora | Milkdown | restart numbering, split, exit, outdent | EDIT-LIST-* | packages/markdown/src/lib/deserializer/deserializeMdList.spec.tsx | ||
packages/markdown/src/lib/serializer/standardList.spec.tsx | ||||||||||
packages/list/src/lib/withList.spec.tsx | no active major blocker | locked | ||||||||
| Link | markdown-native | inline non-void span; directional | CommonMark | Typora | Milkdown | round-trip, directional affinity, plain-link paragraphs, source-entry interaction | EDIT-AFF-LINK-001, EDIT-LINK-CLICK-*, EDIT-INTERACT-* | packages/markdown/src/lib/commonmarkSurface.spec.ts | ||
packages/markdown/src/lib/deserializer/deserializeMentionLink.spec.tsx | ||||||||||
packages/core/src/lib/plugins/affinity/AffinityPlugin.spec.tsx | ||||||||||
content/(plugins)/(elements)/link.mdx | current link law is covered; denser transform permutations still live in protocol rows instead of the backlog | locked | ||||||||
| Image | markdown-native | block void media atom; n/a | CommonMark | Typora | Milkdown | alt vs title, attribute precedence, plain-image paragraphs, source-entry interaction | EDIT-IMG-*, EDIT-INTERACT-* | packages/markdown/src/lib/commonmarkSurface.spec.ts | ||
packages/markdown/src/lib/defaultRules.spec.ts | ||||||||||
apps/www/src/__tests__/package-integration/markdown-rich/serializeMd.spec.tsx | plain markdown image output is limited to alt, src, and optional title; width/height remain HTML/MDX-only | locked | ||||||||
| HTML block | markdown-native | block non-void; n/a | CommonMark HTML block semantics | Typora | Milkdown | source-canonical editable HTML block source as a source-entry surface, with richer rendered edit chrome deferred | EDIT-INTERACT-* | docs/research/sources/typora/links-images-and-html-behavior.md | ||
docs/research/decisions/links-images-and-html-share-a-source-entry-surface.md | ||||||||||
docs/research/concepts/source-entry-surface.md | ||||||||||
packages/markdown/src/lib/deserializer/deserializeMd.spec.ts | ||||||||||
packages/markdown/src/lib/deserializer/utils/customMdxDeserialize.spec.ts | ||||||||||
docs/editor-behavior/editor-protocol-matrix.md | current Plate evidence now covers the source-canonical HTML-block surface honestly enough to lock it; richer rendered HTML-block chrome is deferred as a later product lane | locked | ||||||||
| Emphasis / italic | markdown-native | leaf mark; directional | CommonMark | Typora | Milkdown | round-trip and markdown-native parse/serialize behavior | EDIT-AFF-MARK-001 | packages/markdown/src/lib/commonmarkSurface.spec.ts | ||
packages/autoformat/src/lib/__tests__/withAutoformat/mark/basic-marks.spec.tsx | no active major blocker | locked | ||||||||
| Strong / bold | markdown-native | leaf mark; directional | CommonMark | Typora | Milkdown | round-trip and markdown-native parse/serialize behavior | EDIT-AFF-MARK-001 | packages/markdown/src/lib/commonmarkSurface.spec.ts | ||
packages/markdown/src/lib/serializer/convertNodesSerialize.spec.ts | no active major blocker | locked | ||||||||
| Inline code | markdown-native | leaf mark; hard | CommonMark | Typora | Milkdown | round-trip, hard-edge typing, mixed-mark behavior | EDIT-AFF-HARD-001 | packages/markdown/src/lib/commonmarkSurface.spec.ts | ||
packages/core/src/lib/plugins/affinity/AffinityPlugin.spec.tsx | ||||||||||
packages/markdown/src/lib/serializer/convertTextsSerialize.spec.ts | no active major blocker | locked | ||||||||
| Fenced code block | markdown-native | block non-void owner; n/a | CommonMark | Typora | Milkdown | direct raw markdown, ↵, ⌫, ⇥, ⇤, language preservation | EDIT-CB-* | packages/markdown/src/lib/deserializer/deserializeMd.spec.ts | ||
packages/code-block/src/lib/withCodeBlock.spec.tsx | ||||||||||
packages/code-block/src/react/CodeBlockPlugin.spec.tsx | no active major blocker | locked | ||||||||
| Thematic break | markdown-native | block void atom; n/a | CommonMark | Typora | Milkdown | creation and adjacent block behavior | EDIT-HR-* | packages/markdown/src/lib/serializer/convertNodesSerialize.spec.ts | ||
packages/markdown/src/lib/deserializer/convertNodesDeserialize.spec.ts | no active major blocker | locked | ||||||||
| Hard line break | markdown-native | text token; n/a | CommonMark + HTML fallback | Typora | Milkdown | paragraph and blockquote parity, html fallback, trailing breaks | EDIT-HARD-* | packages/markdown/src/lib/commonmarkSurface.spec.ts | ||
packages/markdown/src/lib/deserializer/splitLineBreaks.spec.tsx | ||||||||||
apps/www/src/__tests__/package-integration/markdown-rich/serializeMd.spec.tsx | no active major blocker | locked |
| Feature | Family | Node Model / Affinity | Parse Authority | Primary UX Ref | Secondary Ref | Behavior Scope | Editing Spec IDs | Current Evidence | Next Work | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| Task list | markdown extension | block non-void container; n/a | GFM / GitHub Docs | Typora | Milkdown | checked-state round-trip, list editing rules | EDIT-LIST-* | packages/markdown/src/lib/taskList.spec.ts | ||
packages/markdown/src/lib/deserializer/deserializeMdList.spec.tsx | ||||||||||
packages/markdown/src/lib/serializer/listToMdastTree.spec.ts | ||||||||||
packages/list/src/lib/normalizers/withInsertBreakList.spec.tsx | ||||||||||
packages/list/src/lib/withList.spec.tsx | no active major blocker | locked | ||||||||
| Table | markdown extension | block non-void grid owner; n/a | GFM | Google Docs | Notion, Milkdown | cell nav, ↵, ⇥/⇤, ⌫, multi-cell selection, copy/paste, merge/split, row/column insert/delete, deserialize/serialize, and intentional inline ` | ||||
| ` fallback for multi-paragraph cell content | EDIT-TABLE-* | packages/markdown/src/lib/table.spec.ts | ||||||||
packages/table/src/lib/withTable.spec.tsx | ||||||||||
packages/table/src/lib/withApplyTable.spec.tsx | ||||||||||
packages/table/src/lib/withDeleteTable.spec.tsx | ||||||||||
packages/table/src/lib/withTableCellSelection.spec.tsx | ||||||||||
packages/table/src/lib/withInsertFragmentTable.spec.tsx | ||||||||||
packages/table/src/lib/transforms/*.spec.tsx | ||||||||||
packages/table/src/lib/merge/*.spec.tsx | ||||||||||
apps/www/src/__tests__/package-integration/markdown-rich/serializeMd.spec.tsx | multi-paragraph cells intentionally degrade to inline ` | |||||||||
| ` fallback because plain markdown table syntax cannot carry nested block structure | locked | |||||||||
| Strikethrough | markdown extension | leaf mark; directional | GFM / GitHub Docs | Typora | Milkdown | round-trip as a markdown deletion mark | EDIT-AFF-MARK-001 | packages/basic-nodes/src/lib/BaseStrikethroughPlugin.ts | ||
packages/basic-nodes/src/lib/BaseMarkPlugins.spec.ts | ||||||||||
packages/markdown/src/lib/commonmarkSurface.spec.ts | ||||||||||
packages/markdown/src/lib/serializer/serializeInlineMd.spec.ts | no active major blocker | locked | ||||||||
| Highlight | markdown extension | leaf mark; directional | local MDX mark contract | Typora | Milkdown | <mark> round-trip and mark toggling | EDIT-MARK-MDX-*, EDIT-AFF-MARK-001 | packages/basic-nodes/src/lib/BaseHighlightPlugin.ts | ||
packages/markdown/src/lib/mdxMarks.spec.tsx | ||||||||||
content/(plugins)/(marks)/highlight.mdx | existing plugin and markdown surface are covered | locked | ||||||||
| Subscript | markdown extension | leaf mark; directional | local MDX mark contract | Typora | Milkdown | <sub> round-trip and mutual exclusion with superscript | EDIT-MARK-MDX-*, EDIT-AFF-MARK-001 | packages/basic-nodes/src/lib/BaseSubscriptPlugin.ts | ||
packages/markdown/src/lib/mdxMarks.spec.tsx | ||||||||||
content/(plugins)/(marks)/subscript.mdx | existing plugin and markdown surface are covered | locked | ||||||||
| Superscript | markdown extension | leaf mark; directional | local MDX mark contract | Typora | Milkdown | <sup> round-trip and mutual exclusion with subscript | EDIT-MARK-MDX-*, EDIT-AFF-MARK-001 | packages/basic-nodes/src/lib/BaseSuperscriptPlugin.ts | ||
packages/markdown/src/lib/mdxMarks.spec.tsx | ||||||||||
content/(plugins)/(marks)/superscript.mdx | existing plugin and markdown surface are covered | locked | ||||||||
| Emoji shortcode | markdown extension | text token after parse; n/a | local remark plugin contract | Typora | GitHub Docs | :shortcode: parse in the default markdown profile | EDIT-EMOJI-* | packages/markdown/src/lib/emojiSurface.spec.tsx | ||
packages/markdown/src/lib/__tests__/createTestEditor.tsx | ||||||||||
apps/www/src/registry/components/editor/plugins/markdown-kit.tsx | shortcode input is covered; the current contract normalizes to unicode text on serialize | locked | ||||||||
| Inline math | markdown extension | inline void atom; n/a | LaTeX-style math / KaTeX conventions | Typora | Milkdown | round-trip, boundary behavior, inline/table interaction | EDIT-MATH-* | packages/markdown/src/lib/mathSurface.spec.ts | ||
packages/math/src/lib/BaseInlineEquationPlugin.spec.ts | ||||||||||
packages/math/src/lib/transforms/insertInlineEquation.spec.ts | ||||||||||
packages/math/src/react/hooks/useEquationInput.spec.tsx | no active major blocker | locked | ||||||||
| Block math | markdown extension | block void atom; n/a | LaTeX-style math / KaTeX conventions | Typora | Milkdown | round-trip, empty exit, block selection behavior | EDIT-MATH-* | packages/markdown/src/lib/mathSurface.spec.ts | ||
packages/math/src/lib/BaseEquationPlugin.spec.ts | ||||||||||
packages/math/src/lib/transforms/insertEquation.spec.ts | ||||||||||
apps/www/src/__tests__/package-integration/ai-chat-streaming/streamSerializeMd.slow.tsx | no active major blocker | locked | ||||||||
| Autolink literal | markdown extension | inline non-void link span; directional | GFM / GitHub Docs | Typora | Milkdown | bare URL parse/serialize and editing | EDIT-AFF-LINK-001 | packages/link/src/lib/withLink.spec.tsx | ||
packages/markdown/src/lib/gfmSurface.spec.ts | no active major blocker | locked | ||||||||
| Footnote | markdown extension | inline void ref atom + block non-void definition; n/a | GFM / GitHub Docs | Typora | Milkdown | reference/definition round-trip, insert flow, registry-backed lookup helpers, duplicate-definition normalization and repair, navigation helpers, shared navigation feedback, and dedicated node model | EDIT-FOOTNOTE-*, EDIT-NAV-FEEDBACK-* | packages/markdown/src/lib/gfmSurface.spec.ts | ||
packages/footnote/src/lib/BaseFootnoteReferencePlugin.ts | ||||||||||
packages/footnote/src/lib/BaseFootnoteDefinitionPlugin.ts | ||||||||||
packages/footnote/src/lib/registry.ts | ||||||||||
packages/footnote/src/lib/queries/footnoteRegistry.spec.ts | ||||||||||
packages/footnote/src/lib/transforms/insertFootnote.spec.ts | ||||||||||
packages/footnote/src/lib/BaseFootnotePlugins.spec.ts | ||||||||||
packages/markdown/src/lib/rules/defaultRules.ts | ||||||||||
apps/www/src/registry/components/editor/transforms.ts | ||||||||||
apps/www/src/registry/ui/slash-node.tsx | ||||||||||
apps/www/src/registry/ui/footnote-node.spec.tsx | no active major blocker | locked |
| Feature | Family | Node Model / Affinity | Parse Authority | Primary UX Ref | Secondary Ref | Behavior Scope | Editing Spec IDs | Current Evidence | Next Work | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| Mention | block-editor-native | inline void atom; n/a | local mention markdown contract | Notion | Milkdown | inline insertion, spacing, keyboard access, markdown mention link round-trip | EDIT-MENTION-* | packages/mention/src/lib/BaseMentionPlugin.spec.tsx | ||
packages/mention/src/lib/getMentionOnSelectItem.spec.tsx | ||||||||||
packages/markdown/src/lib/deserializer/deserializeMentionLink.spec.tsx | ||||||||||
packages/markdown/src/lib/serializer/serializeMention.spec.ts | explicit local contract informed by mainstream mention-chip behavior | locked | ||||||||
| Callout | block-editor-native | block non-void container; n/a | local MDX callout contract | Notion | Milkdown | insert, nested content, keyboard behavior, markdown round-trip | EDIT-CALLOUT-* | packages/callout/src/lib/BaseCalloutPlugin.spec.ts | ||
packages/callout/src/lib/transforms/insertCallout.spec.ts | ||||||||||
packages/core/src/lib/plugins/override/withBreakRules.spec.tsx | ||||||||||
packages/core/src/lib/plugins/override/withDeleteRules.spec.tsx | ||||||||||
packages/markdown/src/lib/mdx.spec.tsx | explicit local contract; not claimed as a stronger external standard than the evidence supports | locked | ||||||||
| Toggle | block-editor-native | block non-void container; n/a | current toggle node contract | Notion | Milkdown | open/close, nested blocks, ↵, ⌫, ⇥, ⇤ | EDIT-TOGGLE-* | packages/toggle/src/lib/BaseTogglePlugin.spec.ts | ||
packages/toggle/src/lib/queries/someToggle.spec.ts | ||||||||||
packages/toggle/src/react/hooks/toggleHooks.spec.tsx | ||||||||||
packages/toggle/src/react/queries/toggleQueries.spec.ts | ||||||||||
packages/toggle/src/react/withToggle.spec.tsx | behavior is specified; implementation work stays in the planned toggle rewrite lane | deferred-minor | ||||||||
| Date | block-editor-native | inline void atom; n/a | local MDX date contract | Notion | Google Docs | inline insertion, adjacency checks, keyboard access, markdown round-trip | EDIT-DATE-* | packages/date/src/lib/BaseDatePlugin.spec.tsx | ||
packages/date/src/lib/transforms/insertDate.spec.tsx | ||||||||||
packages/date/src/lib/utils/dateValue.spec.ts | ||||||||||
packages/date/src/lib/queries/isPointNextToNode.spec.tsx | ||||||||||
packages/markdown/src/lib/dateElement.spec.ts | ||||||||||
apps/www/src/registry/ui/date-node.spec.tsx | ||||||||||
apps/www/src/registry/ui/date-node-static.spec.tsx | canonical YYYY-MM-DD node values are locked; markdown writes canonical dates as <date value=\"...\" />, dual-reads legacy child-text, and preserves non-normalizable legacy text on a raw fallback path | locked | ||||||||
| TOC | block-editor-native | block void atom shell + generated entry overlay controls; n/a | local MDX TOC contract | Notion | Typora, Google Docs | insert, atomic boundary behavior, navigation-only activation, keyboard activation, active-section tracking, shared navigation feedback, scrolling hooks, serialization policy | EDIT-TOC-*, EDIT-NAV-FEEDBACK-* | packages/toc/src/lib/BaseTocPlugin.spec.ts | ||
packages/toc/src/lib/transforms/insertToc.spec.ts | ||||||||||
packages/toc/src/react/hooks/*.spec.tsx | ||||||||||
apps/www/src/registry/ui/toc-node.spec.tsx | ||||||||||
packages/markdown/src/lib/mdx.spec.tsx | explicit local contract with split shell-vs-navigation authorities; not sold as a strong public standard | locked | ||||||||
| Column group / column item | block-editor-native | block non-void container; n/a | local MDX column contract | Notion | docs reference | insert, split, move, select-all, nested editing, serialization | EDIT-COLUMN-* | packages/layout/src/lib/withColumn.spec.ts | ||
packages/layout/src/lib/transforms/insertColumnGroup.spec.ts | ||||||||||
packages/layout/src/lib/transforms/insertColumn.spec.ts | ||||||||||
packages/layout/src/lib/transforms/toggleColumnGroup.spec.tsx | ||||||||||
packages/layout/src/lib/transforms/setColumns.spec.tsx | ||||||||||
packages/markdown/src/lib/columnSurface.spec.ts | explicit local contract; not sold as a strong public standard | locked | ||||||||
| Media embed | block-editor-native | block void atom; n/a | local media MDX contract | Notion | docs reference | embed insertion, editing, serialization | EDIT-MEDIA-* | packages/media/src/lib/media-embed/BaseMediaEmbedPlugin.spec.ts | ||
packages/media/src/lib/media-embed/transforms/insertMediaEmbed.spec.ts | ||||||||||
packages/media/src/lib/BaseMediaPluginContracts.spec.ts | ||||||||||
packages/media/src/lib/media/parseMediaUrl.spec.ts | ||||||||||
packages/media/src/lib/media-embed/parseIframeUrl.spec.ts | ||||||||||
packages/media/src/lib/media-embed/parseVideoUrl.spec.ts | ||||||||||
packages/media/src/lib/media-embed/parseTwitterUrl.spec.ts | ||||||||||
packages/media/src/react/media/FloatingMedia/submitFloatingMedia.spec.ts | ||||||||||
packages/media/src/react/media/useMediaState.spec.ts | ||||||||||
packages/markdown/src/lib/mediaSurface.spec.ts | ||||||||||
apps/www/src/registry/ui/media-video-node.spec.tsx | normalized embed metadata is locked for the current contract: canonical render url, current provider / id, optional sourceUrl for edit reversibility, and allowlisted Twitter/X snippet extraction; broader script/embed behavior and PDF remain outside the contract | locked | ||||||||
| Image / file / audio / video blocks | block-editor-native | block void media node + non-void caption helper; n/a | local media contracts | Notion | Google Docs for file-ish behavior | insert, caption/title, selection, serialization | EDIT-MEDIA-* | packages/media/src/lib/BaseMediaPluginContracts.spec.ts | ||
packages/media/src/lib/image/withImageEmbed.spec.tsx | ||||||||||
packages/media/src/lib/image/withImageUpload.spec.tsx | ||||||||||
packages/media/src/lib/media/insertMedia.spec.ts | ||||||||||
packages/media/src/lib/placeholder/BasePlaceholderPlugin.spec.ts | ||||||||||
packages/media/src/react/placeholder/utils/history.spec.ts | ||||||||||
packages/markdown/src/lib/commonmarkSurface.spec.ts | ||||||||||
packages/markdown/src/lib/mediaSurface.spec.ts | ||||||||||
packages/markdown/src/lib/rules/utils/parseAttributes.spec.ts | current media node, placeholder, and MDX attribute contract is locked; richer source-entry and file-system semantics stay deferred | locked | ||||||||
| Code drawing / Excalidraw | block-editor-native | block void atom; n/a | local non-markdown contract | Notion-like board tools | docs reference | insertion, selection, serialization policy | EDIT-DRAWING-* | packages/code-drawing/src/lib/transforms/insertCodeDrawing.spec.ts | ||
packages/code-drawing/src/lib/BaseCodeDrawingPlugin.spec.ts | ||||||||||
packages/excalidraw/src/lib/transforms/insertExcalidraw.spec.ts | ||||||||||
packages/excalidraw/src/lib/BaseExcalidrawPlugin.spec.ts | behavior is specified; richer product work still stays in a later release lane | deferred-minor | ||||||||
| Caption | block-editor-native helper | block non-void helper; n/a | local caption contract | Notion | Google Docs | movement into/out of captions, media integration | EDIT-CAPTION-* | packages/caption/src/lib/withCaption.spec.tsx | explicit local contract informed by media-caption behavior in block editors and docs tools | locked |
| Feature | Family | Node Model / Affinity | Parse Authority | Primary UX Ref | Secondary Ref | Behavior Scope | Editing Spec IDs | Current Evidence | Next Work | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| Indent | styling/layout | block non-void property; n/a | local block style contract | Google Docs | Notion | paragraph indent, interaction with quote/list owners | EDIT-INDENT-* | packages/indent/src/lib/withIndent.spec.tsx | ||
packages/indent/src/lib/transforms/setIndent.spec.ts | ||||||||||
packages/list/src/lib/withList.spec.tsx | ||||||||||
content/(plugins)/(styles)/indent.mdx | explicit local style contract informed by Docs-style paragraph indentation | locked | ||||||||
| Text align | styling/layout | block non-void property; n/a | local block style contract | Google Docs | Notion | align transform, affected blocks, serialization policy | EDIT-ALIGN-* | packages/basic-styles/src/lib/BaseTextAlignPlugin.spec.ts | ||
content/(plugins)/(styles)/text-align.mdx | explicit local style contract informed by Docs-style alignment controls | locked | ||||||||
| Text indent | styling/layout | block non-void property; n/a | local block style contract | Google Docs | Notion | indent transform, interaction with paragraph/list/quote | EDIT-TEXT-INDENT-* | packages/basic-styles/src/lib/BaseTextIndentPlugin.spec.ts | explicit local style contract informed by Docs-style indentation controls | locked |
| Line height | styling/layout | block non-void property; n/a | local style contract | Google Docs | Notion | application/removal, affected blocks, serialization policy | EDIT-LINE-HEIGHT-* | packages/basic-styles/src/lib/BaseLineHeightPlugin.spec.ts | explicit local style contract informed by document-style spacing controls | locked |
| Font family / size / weight / color / background | styling/layout | leaf style marks; directional | local style span contract | Google Docs | Notion | mark boundaries, serialization policy, mixed markdown behavior | EDIT-STYLE-*, EDIT-AFF-MARK-001 | packages/basic-styles/src/lib/BaseFontFamilyPlugin.spec.ts | ||
packages/basic-styles/src/lib/BaseFontSizePlugin.spec.ts | ||||||||||
packages/basic-styles/src/lib/BaseFontWeightPlugin.spec.ts | ||||||||||
packages/basic-styles/src/lib/BaseFontColorPlugin.spec.ts | ||||||||||
packages/basic-styles/src/lib/BaseFontBackgroundColorPlugin.spec.ts | ||||||||||
packages/markdown/src/lib/rules/fontRules.ts | explicit local style contract informed by document-style formatting controls | locked |
| Feature | Family | Node Model / Affinity | Parse Authority | Primary UX Ref | Secondary Ref | Behavior Scope | Editing Spec IDs | Current Evidence | Next Work | Status |
|---|---|---|---|---|---|---|---|---|---|---|
| Comment | collaboration | leaf metadata mark; outward | editor-only contract | Google Docs | Notion | mark boundaries, creation/removal, serialization exclusion | EDIT-COMMENT-* | packages/comment/src/lib/BaseCommentPlugin.spec.ts | ||
packages/comment/src/lib/utils/getCommentKeys.spec.ts | ||||||||||
packages/comment/src/lib/utils/getCommentCount.spec.ts | ||||||||||
packages/markdown/src/lib/rules/defaultRules.ts | behavior is specified; implementation hardening still belongs to the collaboration lane | deferred-minor | ||||||||
| Suggestion | collaboration | leaf metadata mark plus block suggestion wrapper; outward | editor-only contract | Google Docs | Notion | suggestion ranges, insertion/deletion behavior, serialization exclusion | EDIT-SUGGESTION-* | packages/suggestion/src/lib/BaseSuggestionPlugin.spec.ts | ||
packages/suggestion/src/lib/withSuggestion.spec.tsx | ||||||||||
packages/suggestion/src/lib/transforms/acceptSuggestion.spec.tsx | ||||||||||
packages/suggestion/src/lib/transforms/rejectSuggestion.spec.tsx | ||||||||||
packages/suggestion/src/lib/insertBreakSuggestion.spec.tsx | ||||||||||
packages/suggestion/src/lib/transforms/deleteSuggestion.spec.ts | ||||||||||
packages/markdown/src/lib/rules/defaultRules.ts | behavior is specified; implementation hardening still belongs to the collaboration lane | deferred-minor | ||||||||
| Discussion | collaboration | overlay / anchor surface; n/a | editor-only contract | Google Docs | Notion | anchor behavior, selection coupling, serialization exclusion | EDIT-DISCUSSION-* | docs surface only | behavior is specified; product implementation work still belongs to the collaboration lane | deferred-minor |
| Yjs cursor / collaboration overlays | collaboration | overlay / no node; n/a | editor-only contract | Google Docs | Figma/Notion | concurrent cursor and presence behavior | EDIT-COLLAB-* | docs and package surfaces | behavior is specified; implementation hardening still belongs to the collaboration lane | deferred-minor |
The active major-release gate is now closed.
Search / find-replace stays outside the active gate for now.
The behavior law and protocol rows exist, but the editor search surface is still intentionally deferred until that product lane is picked up for real.
What is considered closed for this major:
What remains outside this closed major but still belongs in the editor-behavior backlog:
$...$ converts to inline math on the closing delimiter$$ + Enter promotes to block mathYYYY-MM-DD node contract, canonical <date value=\"...\" /> write
output, and legacy child-text read compatibilityurl /
provider / id / optional sourceUrl contract is explicitly deferred;
it is too broad for the current markdown lane and should not be treated as
the next markdown-native follow-uptoggle rewrite laneUse master-roadmap.md for the actual implementation order.
This section only names the backlog families that still exist outside the closed major gate.