BlockDoc Revibe

The **BlockDoc Canonical Revibe** is a strategy for rebuilding a Fedwiki-inspired system from scratch while preserving compatibility with existing JSON based sites and embracing modern agentic development. The core idea is to define a small canonical BlockDoc model and treat both Federated Wiki JSON and Markdown ecosystems as first class adapters around that model. We explicitly avoid supporting legacy `text` and `html` paragraph items going forward. Instead we normalise all narrative content into Markdown, while keeping non-text items as dedicated block types.

# BlockDoc As Canonical BlockDoc is the canonical representation for a page. A page is: - `id` or `slug`. - `title`. - `blocks[]` as an ordered list. - `meta` for page level metadata. Each block is: - `id` stable identifier. - `type` such as `markdown`, `image`, `audio`, `video`, `graphviz`, `frame`, `map`, `plugin`. - `props` block specific data. - optional `children[]` for nested structures. Agents, servers and clients all agree on this schema. Everything else (Fedwiki JSON, Markdown files, Obsidian views, React editors, web component SPAs) becomes an adapter on top of BlockDoc.

# Normalising Text To Markdown Going forward we do not support raw `text` or `html` paragraph items as first class block types. Narrative content lives only as `type: "markdown"` blocks: - `type: "markdown"` - `props.markdown` containing the Markdown source. When we import existing Fedwiki pages: - Legacy `paragraph` or `markdown` items become `markdown` blocks. - Legacy `html` items are passed through an HTML → Markdown converter wherever possible. - If conversion fails, we store the original HTML in `props.legacyHtml` and still expose a Markdown representation the user can clean up. This keeps the core model Markdown-centric and pushes HTML towards migration rather than new content.

# Non Text Block Types Non text story items become dedicated BlockDoc block types. Initial set: - `image` with `src`, `alt`, `caption`. - `audio` with `src`, `title`. - `video` with `src`, `poster`, `title`. - `graphviz` with `source` for the DOT text. - `frame` with `src`, `title`, `sandbox` flags. - `map` with coordinates, zoom, layers. When we encounter existing Fedwiki items we do not yet have a first class type for: - We map them to `type: "plugin"` with `props.item` holding the raw Fedwiki item. - The editor initially renders a generic “raw block” view showing the underlying JSON or text. - Later, when we add a native block type, we teach the adapter how to upgrade that `plugin` instance into a dedicated BlockDoc type. This allows incremental support for rich media without blocking on a complete catalogue of block types.

# Adapters To Fedwiki JSON Fedwiki JSON remains a compatibility layer. An adapter library provides two pure functions: - `fedwikiJsonToBlockDoc(page)` - `blockDocToFedwikiJson(page)` Conversion rules: - `title` passes through unchanged. - `story[]` items become `blocks[]`, mapping known types to `markdown`, `image`, `audio`, `video`, `graphviz`, `frame`, `map`. - Unsupported or custom `story` types become `type: "plugin"` blocks with `props.item` containing the original item JSON. - `journal[]` is preserved as `meta.journal` or a sibling structure, keeping provenance intact. Round trip tests ensure: - `pageJson -> BlockDoc -> pageJson` preserves semantics for existing sites. - Only a one way normalisation of `text` and `html` into Markdown is allowed; once converted we do not regenerate `html` items.

# Adapters To Markdown And Obsidian Markdown is the primary surface for writing and Obsidian style workflows. A second adapter provides: - `blockDocToMarkdownWithYam(page)` - `markdownWithYamToBlockDoc(file)` The Markdown view: - Renders `markdown` blocks as plain Markdown sections. - Renders non text blocks as short, readable stubs with fenced Yam back matter at the end describing block ids, types and key props. For example a page might end with: ```yam id: p1 => # Title p2: markdown => Paragraph one. b3: image => ./images/photo.jpg b4: graphviz => graphviz:digraph{A->B}