Repository navigation
Epic: modules render their own content, starting with brain-kit-styled diagrams that theme and print #2079
Description
Outcome
A module can draw its own content — a markdown fence or a file type — in the chat, the file viewer and every export path, through a build-time-bundled renderer seam that Mermaid also uses. On that seam, @schlessera/brain-module-diagrams turns a versioned ```diagram spec into editorial figures that look like brain-kit: drawn with --bk-* tokens, switching with the app's light/dark theme, printing on white, with diagram-design's connector rules guaranteed by computed geometry rather than checked afterwards. The module carries a written procedure for reviewing upstream diagram-design for new types and rule changes.
Why now
The maintainer asked for diagram-design's visual quality inside brain-kit with light, dark and print support, and ruled (2026-10-16) for the full module-renderer approach in one epic, with no file-based interim. The measurements in docs/decisions/module-renderers.md showed why the module-only route cannot deliver it:
- An
<img>-embedded SVG never sees@media print, so browser print keeps the screen palette. - WebKit (all iOS browsers) does not reliably theme an
<img>SVG (WebKit bug 199134 still NEW). - An image cannot use the app's fonts under the raw-file CSP.
Inline rendering by a trusted, bundled renderer removes all three problems. The seam also retires Mermaid's three special cases and gives #905 (maps) and #1609 (charts) a path.
Shared context
- Design and ordering: docs/plans/module-renderers.md. Why: docs/decisions/module-renderers.md. Read both before picking up any task.
- Upstream: https://github.com/cathrynlavery/diagram-design (MIT). Reviewed at commit
b46c970(plugin 2.6.107). It is an agent skill, not a renderer: about 9.5k lines of reference prose, 45 type grammars, six connector rules and about 6.2k lines of Python checkers. - Mermaid now uses the renderer seam: ui-react: Mermaid renders as a content-renderer pack and exports in the print theme #2084/CONTRACT: route Mermaid through content renderers and print tokens #2168 removes its fence/file special cases. Generic fence dispatch is (
MarkdownPre,packages/ui-react/src/components/chat/brain-markdown-code.tsx:17-25), file dispatch is (ViewerBody,packages/ui-react/src/components/files/file-viewer.tsx:81-98), and the retained public share helper delegates generic rendering (inlineMermaidDiagrams,packages/ui-react/src/lib/mermaid.ts:282-284). The built-in pack supplies its print contract. - Precedent for build-time packs: tool renderers (
export function registerToolRenderers,packages/ui-sdk/src/client/renderers.ts:171;Runtime plugin loading,packages/ui-react/src/components/chat/renderers/index.ts:3). - Module contributions are
.strict()and now declare package-owned renderer exports (export interface ModuleContribution,packages/core/src/lib/module-types.ts:136-164;ModuleRenderer, same file:122-127). docs/decisions/module-mcp-tools.md is the precedent for adding a contribution kind under the shared compatibility policy. - Tokens:
--bk-diagram-*(--bk-diagram-bg: light-dark,packages/ui-kit/src/tokens.css:782-787) and the generated print theme ([data-theme="print"] {,packages/ui-kit/src/tokens.css:870). - Example world: Odysseus only (docs/decisions/example-corpus.md). Upstream's example HTML is never vendored.
Constraints and non-goals
- Markdown stays the source of truth. The fence spec is the diagram; any SVG file is derived.
- Packs are registered by the build, never loaded at runtime from config. No renderer receives raw content markup to inject; renderers build elements from data.
- brain-kit's design system wins over upstream's skin (fonts, the 9px floor, no alpha ink, never colour alone). Upstream contributes the method.
- Theme contract: every pack implements
light,darkandprint. Every artifact leaving the screen usesprint(decision ruling 6). - Contract: the manifest key, the fence spec and new
--jsonshapes are contract additions withCONTRACT:commits. - Non-goals:
- automatic whole-diagram layout (dagre or elk)
- data-chart types that ui-kit's chart components cover
- upstream's import/export tooling, icons, sketchy and terminal variants, and animation
- a
show_blockkind
Breakdown
The sub-issue list carries the work. Its order is this stack plan, under docs/process/github.md § Stacked pull requests. A stack is a linear chain, so the dependency tree is cut into three stacks and some ordinary PRs. Each layer is one issue and one reviewable slice.
Stack plan
| Stack | Layers, bottom → top | Starts from |
|---|---|---|
| A: renderers | #2081 seam ← #2082 manifest ← #2083 registry ← #2084 Mermaid ← #2085 static path ← #2087 bundling | main |
| B: diagrams core | #2088 scaffold ← #2089 spec ← #2090 geometry ← #2093 skin | main, in parallel with A |
| C: diagrams render | #2094 renderer pack ← #2099 export | main, once A and B have landed |
- The design/skin prerequisites are delivered. ui-kit: design brief for a free-layout diagram in the brain-kit style (architecture) #2091's revised eight-node desktop/narrow/fallback compositions were explicitly adopted by the maintainer; ui-kit: design brief for an axis diagram in the brain-kit style (sequence) #2092 and modules: diagrams paint with generated brain-kit tokens in light, dark and print #2093 are complete. Preserve their approved direction. The separate common-callout treatment modules: accepted diagram callouts disappear from client and static figures #2242 is delivered by CONTRACT: render readable common diagram callouts #2346 under its adopted N1/N2/N3 and revision 2 R1=A/R2=B rulings, including the fixed-canvas inline compatibility exception.
- Ordinary PRs on
main:- ui-server: an .svg file previews as an image, and SVG images print light #2086 (
.svgimage fix): at any time. - modules: node-link diagram types (architecture, flowchart, state, tree, ER, dependency) #2095, modules: axis diagram types (sequence, swimlane, timeline, Gantt) #2096, modules: positional diagram types (quadrant, layers, pyramid, loop, Venn) #2097 (type families): in parallel once modules: the diagrams renderer pack draws inline, interactive, accessible figures #2094 lands. They do not depend on each other, so stacking them would invent dependencies.
- modules: the diagram skill teaches selection, taste and the fence #2098 (skill): after the three families.
- ui-server: an .svg file previews as an image, and SVG images print light #2086 (
- Other repositories: shell: bundle the configured modules' renderer packs into the PWA build brain-hosting-template#33 now waits on that repository's extraction feat: pi backend parity with the Claude backend #15; delivered registration ui-react: a deployment bundles module renderer packs and flags declared-but-unbundled fences #2087 and diagrams pack modules: the diagrams renderer pack draws inline, interactive, accessible figures #2094 do not create its missing host foundation. A stack cannot cross repositories.
- Delivered foundations and module: the approved record, renderer seam/manifest/registry, Mermaid migration, shared static print path and bundling (docs: record the module-renderer decision and the diagrams plan #2080/modules: rule on reproducing upstream's MIT notice, which names a person, against the no-real-names rule #2109, ui-sdk: define the content-renderer seam and its light/dark/print conformance suite #2081–modules: scaffold the diagrams module with upstream provenance and a sync procedure #2088) are delivered. The common spec/geometry/skin/client-static pack (modules: diagrams v1 fence spec and
brain diagram check#2089/modules: the diagram geometry builder enforces the connector rules by construction #2090/modules: diagrams paint with generated brain-kit tokens in light, dark and print #2093/modules: the diagrams renderer pack draws inline, interactive, accessible figures #2094), axis/positional/node-link families (modules: node-link diagram types (architecture, flowchart, state, tree, ER, dependency) #2095–modules: positional diagram types (quadrant, layers, pyramid, loop, Venn) #2097), and authoring skill (modules: the diagram skill teaches selection, taste and the fence #2098) are also delivered. Their native child receipts record immutable merge identities and source-qualified proof. The module now checks and renders shipped types. Common callouts are delivered by CONTRACT: render readable common diagram callouts #2346 /99c67ceca1537b0fc5c6e62eca854546c9e50195: full annotations, shared per-target keys, responsive notes bands, summary indices and the approved fixed-canvas compatibility behavior. modules:brain diagram exportandbuild, plus hygiene for external viewers #2099 is now delivered by CONTRACT: export diagrams and audit external-viewer pairs #2258 /61c73e2037ae17e9bfe0c1d8bb4722978b2a2fc3: SVG/optional PNG/PDF export, identified GFM light/dark pairs and ownership/freshness hygiene with embedded painted fonts. The full epic definition of done and the generated-host foundation remain open; modules: accepted diagram callouts disappear from client and static figures #2242 is complete. - Selection: Under process: decide how an issue that depends only on an open lower stack layer becomes selectable #2137 option A, a blocked upper layer is selectable only after every remaining open blocker is verified as an open, non-draft lower PR in this epic's declared stack with complete passing selected proof for its current parent/head candidate. Verify actual membership and the immediate parent before claiming and again before checkout creation; start from that verified head. Any genuine
needs:label, non-stack blocker or unavailable/failed/cancelled/unexpectedly skipped proof rejects selection. Preserve canonicalBlocked bylines andblockedfor open dependencies; a merged parent uses ordinary reconciliation and fetchedmain. Each layer owner refreshes their own layer bottom-up after parent changes, with explicit ownership handoff when absent. The stack merger verifies each included issue's delivered identities, acceptance/proof and release milestones and closes only completed issues. Native-stack candidate qualification remains separately subject to ci: native stacked PR events do not match contract and candidate identity guards #2141. Its October 22 ruling parks frozen-prefix verification/integrator work until serial candidate confirmation returns as the merge workflow; the earlier B/A policies remain binding only if that work resumes. The declared stack order is delivery history for the now-merged layers, not an instruction to revive the parked native verifier. Remaining work follows its own current brief; ordinary PRs retain their declared dependencies and reconstruct only their own diff after predecessors land. - Branches and proof: each layer issue names its branch and parent, and its verification runs
check:pr --base <parent-ref>.
Current remaining native work — 2026-10-22
#2228 is delivered by #2369 (af0547c): fit frames include computed group/heading extents and fixed/narrow frames report clipped bounds. #2241 is delivered by #2368 (b7a0885): viewer proof selects the actual diagram and requires its expected text population before enforcing the font floor. Both merges are ancestors of inspected main a310317, and the corresponding geometry/viewer guards are present. Consume their original qualified closure receipts; this triage does not rerun or independently re-audit their historical hosted jobs.
The native open child list is now only schlessera/brain-hosting-template#33 (still waiting on that repository’s extraction #15) and #2469 (the existing identical-source free-layout raster-parity investigation, still needs: repro). The fully scoped generated-host work and the missing natural raster-failure evidence remain distinct. Closed foundations, export, bounds and proof fixes do not establish the complete integrated/host outcome below. Preserve the full definition of done and keep this epic open without agent-ready.
Definition of done
- A
```diagramfence written by the agent in chat renders inline in light and dark, follows the theme toggle on Chromium and WebKit, and prints white from the browser and from share → PDF. Each is shown with a capture in the closing comment. - Mermaid renders identically through the seam, and its old special cases are deleted.
- Every first-party pack (Mermaid, diagrams) passes
contentRendererConformance, and a share → PDF holding both a Mermaid chart and a diagram shows one white ground. docs/modules.md,docs/extending/README.mdand the integration contract describe the seam, the manifest key and the spec.packages/module-diagrams/UPSTREAM.mdexists, and one dry-run review against upstream HEAD has been recorded in a PR.
2026-10-16: the breakdown became a stack plan (stacked PRs, #1997). #2109 was added for the licence ruling and #2137 for stack selection.
2026-10-16 triage at main 8822aedeeac8b824bafe120c20a9b58c4cd1f4e6: replaced unavailable main links with the inspected immutable #2102 proposal and updated the resolved-versus-undelivered stack-policy distinction. The content-renderer decision is proposed documentation awaiting merge, not shipped renderer capability; preserve the existing stack plan, native membership and full definition of done.
2026-10-16 triage at main 80e028d84b7686d6cf864d8166029b1142de8756: replaced proposal-only links with the delivered decision identity and folded verified foundation deliveries into the current breakdown. Existing Mermaid fallback special cases remain until #2084; generic dispatch does not complete their migration. Preserved design revisions/final sign-off, ordinary delivery fallback, stack dependencies and the complete definition of done. Recorded focused/native receipts are not a new independent full-main CI audit.
2026-10-16 delivery reconciliation: #2089 delivered the common v1 spec, check command and contract in #2167. The next Stack B layer #2090 uses fetched main; the remaining definition of done and declared dependencies are unchanged.
2026-10-16 triage at main 4ba792473152c89eb74c286fc914e54ca1dae8fc: reconciled the active specification with closed child outputs and merged source, replacing obsolete Mermaid special-case and pending-foundation statements. The approved design/skin/families/skill are delivered; dedicated exports, common callout treatment, generated-host foundation and complete integrated proof remain separate. Local/source-qualified receipts are not an independent full current hosted audit; preserve the original definition of done and epic-not-ready status.
2026-10-17 triage at main ecb87487d714956b0fcef520debe9dfa885b234f: folded the closed export/build child into the active delivery summary after reading its closure, immutable delivery and qualified artifact/font receipts. #2242 retains its newly documented crowded/semantic-only fallback design gap and approved N1/N2/N3 rulings; no annotation approval or complete epic outcome is inferred. Existing source-qualified proof is not a new independent hosted audit.
2026-10-22 native-output reconciliation: folded the two delivered bounds/viewer-proof repairs and current native open-child scope into the active brief. Original failure and qualification receipts retain their actual source identities; no new renderer runtime, generated-host result or epic-completion proof is claimed.
2026-10-24 continued triage at main dc5d3c73282c29a3f0098306d398743ee18ec791: Reconciled the active #2141 reference with its later parked-workflow ruling. All renderer/diagram deliveries and the remaining generated-host #33 and raster-attribution #2469 outcomes remain distinct. No native candidate support, stack action, new renderer proof or epic completion is claimed.
Activity
brain diagram check#208926 remaining items
schlessera commentedon Oct 16, 2026
2026-10-16: #2096 is delivered through #2243, squash
c1e1de01f, with release 0.44.0. Sequence/swimlane/timeline/Gantt grammars, honest dated geometry, shipped Odysseus examples and on-demand references now use the shared renderer. Actual Chromium/WebKit type/theme baselines, responsive sequence/fallback, fragments, connector masks and name/keyboard navigation passed. Actual-squash smoke passed 142 module/citation tests; main CI remains queued. #2098 retains its other family blockers; the epic remains open for their remaining work and its complete definition of done.schlessera commentedon Oct 16, 2026
#2097 delivered through #2249, normal squash
52e672bcd60a14f88add003d027ef0ee0622a7b5, verified milestone0.44.0. All seven positional families now have strict additive content, deterministic shared geometry/paint, shipped Odysseus examples and light/dark/print baselines. Actual squash focused proof159tests/321386assertions passed; stable-head preflight525fast+110affected and final positional Chromium/WebKit18tests passed. Legacy positional assumptions are disclosed rather than fabricated. #2098 now waits only on #2095; the epic's complete definition of done remains open. Automatic squash CI is queued, not green; project-sync failed. Separate deferred P2 #2241 records an existing vacuous viewer-font proof without expanding this family scope.schlessera commentedon Oct 16, 2026
2026-10-16 public-template readiness: schlessera/brain-hosting-template#33 is dependency-blocked on that repository's #15. Public main
76cd61f6d5f2b97df5b61cdc836a86e05e9a36ddcontains no package/client/build/container foundation; its approved generated-host decision assigns those inputs to extraction #15 under retained evidence prerequisites. Delivered brain-kit registration #2087 and diagrams pack #2094 do not supply those host files. #33 now has the canonical dependency, exact source/resumption evidence and released assignment; its existing P1/0.44.0 commitment is preserved. No replacement scaffold, host build or browser proof is claimed. The renderer epic remains open.schlessera commentedon Oct 16, 2026
Delivered in #2252, normal matching-head squash
9b7e77a4b5df780b927ade2ebae53bcb4a2e3173; release milestone 0.44.0 is retained on the PR and closed issue.All six families and seven examples are shipped with additive schema/API documentation and a minor changeset. Frozen-head proof: 135 module tests, 102 actual Chromium/WebKit comparison tests, strict types/build, local preflight (932 fast +180 changed-feedback), installed Bun/Node/React18 package consumers, failing-first/mutation controls and approved final visual review. Hosted checks remain queued and are not represented as green.
The actual squash parent is
2f5ca4568646d846572ad237a8325e91775c0938; the qualified head wase2881673a06c18560a2bd6851792c2bd0ceca263on52e672bcd60a14f88add003d027ef0ee0622a7b5. Main advanced only an unrelated three-line policy-test correction. The squash differs from the qualified head only by that correction; focused module and decision-citation checks passed on the actual squash. #2098's final canonical blocker is reconciled. Common callout omission remains separately tracked in #2242 pending design, outside this family delivery.schlessera commentedon Oct 16, 2026
2026-10-16: #2098 delivered through #2256, normal squash
05d6c731b4794715006bdec0ba2cd6ff44c09f81, verified 0.44.0 on PR and issue. The diagram skill now teaches shipped-type selection, deletion/taste, authored YAML fences and the actual check command; generated module instructions distinguish deliberate figures, Mermaid sketches and pictorial image generation. Both worked fences and all 18 shipped family examples pass real keyless CLI checks. Actual squash focused proof: 58 tests / 225 assertions; full local preflight: 932 fast + 55 affected tests. Failing-first materialization and restored semantic mutation receipts are recorded in the PR.#2099 export work, public-template #33's extraction dependency, deferred annotation #2242 and the epic's full definition of done remain separate. This delivery does not promise unshipped export commands, painted callouts or generated-host availability. Automatic squash CI was queued at inspection, not green; project-sync failed. The epic remains open.
schlessera commentedon Oct 16, 2026
2026-10-16 delivery: #2099 is complete through #2258, normal squash
61c73e2037ae17e9bfe0c1d8bb4722978b2a2fc3, milestone 0.44.0. The diagram module now exports flattened SVG/optional PNG/PDF, builds owned light/dark pairs from identified GFM fences, and audits missing/dormant modules, invalid specs and stale/unsafe derived pairs. Markdown remains authoritative and unchanged.Whole-native-frame parity/font/artifact proof passed 76 Chromium/WebKit cases, with real keyless optional-renderer PNG/PDF and embedded painted-font receipts. Frozen packed source/default consumers and the actual squash's 134 scoped checks passed. Automatic main CI remains queued; the epic's independent complete definition of done retains its own evidence requirements.
schlessera commentedon Oct 17, 2026
2026-10-17 delivery reconciliation: #2242 closed through #2346 after actual Chromium/WebKit captures, strict types, focused preflight, packed consumers and restored collision/grouping/compatibility mutations. Actual squash
99c67ceca1537b0fc5c6e62eca854546c9e50195retained the expected combined tree and passed 15 focused callout tests. Main CI was queued, not claimed green. This does not close the epic or its remaining children/integrated definition of done.schlessera commentedon Oct 17, 2026
2026-10-17 priority correction: Required open children #2228 and #2241 are now P1, aligned with this epic and the blocker-priority ruling. The earlier P1 review excluded them because of their former P2 labels; that exclusion is superseded. Hosting-template #33 and its blocker #15 already have P1 priority. Existing scope, readiness and ownership rules still apply.
schlessera commentedon Oct 22, 2026
2026-10-22 native-output reconciliation at a310317: #2228/#2369 and #2241/#2368 are merged, ancestral and present in current geometry/viewer proof. Updated the active brief to consume those delivered outputs and name the remaining native open work: hosting-template#33 after its #15 foundation, and #2469’s unreproduced raster-parity observation. The full integrated/host definition of done remains. No new runtime, historical hosted audit, child priority change or epic readiness is claimed.
schlessera commentedon Oct 24, 2026
2026-10-24 triage at main
dc5d3c73282c29a3f0098306d398743ee18ec791: Reconciled the active #2141 reference with its later parked-workflow ruling. All renderer/diagram deliveries and the remaining generated-host #33 and raster-attribution #2469 outcomes remain distinct. No native candidate support, stack action, new renderer proof or epic completion is claimed.