Menu

#118 site(concepts): phase 3 canonical diagram primitives

closed
nobody
None
2026-05-21
2026-05-21
Anonymous
No

Originally created by: TheoV823

Summary

Phase 3 of the Mneme HQ knowledge-graph roadmap. Ships four reusable HTML+CSS diagram primitives on their canonical concept pages, plus a contributor-facing visual-language spec. Establishes a recognizable Mneme visual language so future diagrams reuse a shared vocabulary instead of growing the inline-SVG count further.

  • New site/assets/css/diagrams.css — four self-contained primitives (--propagation, --checkpoints, --chain, --cascade), all scoped under .mneme-diagram.
  • New docs/contributing/diagram-conventions.md — durable visual-language rules: markup contract, color roles, typography, scoping invariant, no-invented-capabilities rule.
  • Four canonical concept pages updated to embed their primitive: /concepts/governance-propagation/, /concepts/governance-before-generation/, /concepts/enforcement-provenance/, /concepts/architectural-drift/.

The internal-planning design lives in the private mneme-growth-ops repo (commits 44c3442 design + e285832 implementation plan + 4527a76 path-rename). Public scope is exactly the six files in this PR. No insight, demo, or compare-page embeds in this PR; those are queued for a follow-up.

Replace / keep / add decisions

Applied the design's replacement rule strictly:

Replace an existing SVG only when the CSS primitive is clearly smaller or theme-token cleaner, more accessible, and at least semantically equivalent. If it is only prettier or more consistent, do not replace it in this PR.

Page Existing Action Per-criterion reasoning
/concepts/governance-propagation/ Inline SVG (65 lines): ADR → Compiler → Corpus → 5 consumers. Hardcoded hex, <text> labels. JetBrains sub-label said "plugin · inline" — contradicted /integrations/jetbrains/ ("No native JetBrains plugin yet"). REPLACE (a) theme-cleaner — var(--token) throughout, zero stray hex except #0c0c0d for gate dark text. (b) more accessible — real HTML > SVG <text>; clean ARIA. (c) semantically equivalent — same source / compiler / corpus / 5 consumers / equivalence statement; one capability-claim correction (JetBrains "plugin · inline" → "corpus context", matching the integration page).
/concepts/governance-before-generation/ Inline SVG: two-pipeline strategic argument. Figcaption: "The enforcement point is the strategic variable." KEEP BOTH The existing SVG argues why enforcement-point choice matters (strategic comparison of shape vs react). The new primitive argues what the concrete checkpoints are (operational map with the CI gate marked, two-vs-three split between pre- and post-generation). They answer different questions on the same page. A one-sentence connecting paragraph bridges them. Replacement rule does not apply: the two diagrams are not making the same argument.
/concepts/enforcement-provenance/ Inline SVG: six-link chain (01 Authoring → 06 Enforcement event) plus a "Citable chain" summary trailer. Hardcoded hex; fake identifiers (ADR-0017.md, d-17, verdict#9341, sha 9f3a, real personal name + date). REPLACE (a) theme-cleaner. (b) more accessible — real HTML; clean ARIA. (c) semantically equivalent — all 6 links preserved with type/id/meta; citable-chain trailer preserved as its own block within the wrapper; figcaption preserved verbatim. Fake identifiers genericized per the no-invented-capabilities rule, but the chain structure and argument are unchanged.
/concepts/architectural-drift/ No existing diagram. ADD Pure addition; replacement rule does not apply. Five schematic tier rows (S1–S5) with growing bar widths and qualitative labels. Schematic by design: no violation counts, benchmark rates, percentages in markup, or session numbers beyond S1–S5. S5 labeled "governance reset required," not "unrecoverable." Figcaption explicitly marks the diagram as schematic and links to /benchmark/ for measured drift rate.

The strategic SVG on /concepts/governance-before-generation/ also had its outer <figure aria-labelledby="…"> removed in d286d9d so both diagrams on that page announce consistently to assistive tech (the figure now derives its accessible name from <figcaption> natively; the SVG keeps its internal <title>/<desc> for the inner role="img").

Per-page diff sizes

 docs/contributing/diagram-conventions.md           | 149 ++++++ (new)
 site/assets/css/diagrams.css                       | 569 +++++++++++++++++++++ (new)
 site/concepts/architectural-drift/index.html       |  46 ++
 site/concepts/enforcement-provenance/index.html    | 119 ++---
 site/concepts/governance-before-generation/index.html |  42 +-
 site/concepts/governance-propagation/index.html    | 117 ++---
 6 files changed, 913 insertions(+), 129 deletions(-)

Commit log on this branch (8 commits)

31c18c2 site(concepts): drift-cascade primitive (HTML+CSS)
f4167cd fix(diagrams): chain primitive equal-width columns at desktop
20ebe83 site(concepts): provenance-chain primitive (HTML+CSS)
d286d9d site(concepts): governance-before-generation phase 3 cleanup
55d9047 site(concepts): enforcement-checkpoints primitive (HTML+CSS)
a1b355a fix(diagrams): propagation primitive mobile layout
db556bf site(concepts): governance-propagation primitive (HTML+CSS)
c6e504d site(diagrams): scaffold diagrams.css and conventions doc

Why diagrams.css is 569 LOC (over the 500 soft target)

The design doc set a 500 LOC soft budget for diagrams.css. Final size is 569. Per the design's own escape clause ("report the final size and why the added lines are necessary rather than compressing readability"), the breakdown:

  • ~45 lines: header comment + base wrapper + sr-only helper
  • ~165 lines: Primitive 1 (governance propagation) — three-row layout, fan-out bus, equivalence note, mobile collapse
  • ~85 lines: Primitive 2 (enforcement checkpoints) — bracketed row, 5 step variants (active / gate / muted), mobile collapse
  • ~150 lines: Primitive 3 (provenance chain) — 6-link grid, source/active variants, citation trailer (label + lines + summary), mobile collapse
  • ~85 lines: Primitive 4 (architectural drift cascade) — tier grid, 5 schematic bar-width variants, mobile collapse + documentation comment on the rgba derivation
  • ~39 lines: media-query bodies and inter-block comments

No compression would improve clarity. The four primitives together are now the canonical visual language; the 500 was a soft ceiling, not a hard limit. Future primitives, if any, are expected to extend rather than replace these — atomization (extracting shared __node / __arrow / __caption rules) is deferred to a follow-up cleanup PR per the design.

Verification

Theme + scoping discipline

  • Scoping invariant: every selector in diagrams.css is scoped under .mneme-diagram (or a class that only appears inside .mneme-diagram markup). Verified by grep -E '^[^/{}* @].*{' diagrams.css | grep -v '^\.mneme-diagram' returning no matches.
  • Hex literals in declarations: only #0c0c0d at lines 91 and 281 (both documented gate-text uses; #a8a8b8 appears only inside an explanatory CSS comment about the rgba derivation from --muted). All other colors use var(--token) or documented rgba() tints of token hex values.
  • No new :root variables introduced.

mneme check --mode warn

Baseline comparison on origin/main vs HEAD for the four pre-existing concept pages, plus the two new files:

File Origin/main HEAD Note
site/concepts/governance-propagation/index.html FAIL FAIL Identical noise; not introduced by this PR
site/concepts/governance-before-generation/index.html FAIL FAIL Identical noise; not introduced by this PR
site/concepts/enforcement-provenance/index.html FAIL FAIL Identical noise; not introduced by this PR
site/concepts/architectural-drift/index.html FAIL FAIL Identical noise; not introduced by this PR
site/assets/css/diagrams.css (new) FAIL Keyword-trigger noise: CSS comments contain words like "governance" and "enforcement"
docs/contributing/diagram-conventions.md (new) PASS Clean

These FAILs are pre-existing keyword-trigger noise on governance vocabulary, not real governance violations. mneme check runs in warn mode and never blocks merge (see .mneme/README.md rollout plan). The new files inherit the same shape of keyword noise; no actual governance regression has been introduced.

scripts/seo_check.py

Page Pass Warn Fail
/concepts/governance-propagation/ 20 1 0
/concepts/governance-before-generation/ 20 1 0
/concepts/enforcement-provenance/ 20 1 0
/concepts/architectural-drift/ 20 1 0

The single warn per page is style.classes: undefined CSS classes — the SEO scanner parses only inline <style> blocks and does not follow the external diagrams.css link. The classes are defined; the scanner is blind to the external sheet. No fails introduced.

Visual smoke (headless preview, three widths)

All four primitives verified at 1024 / 640 / 360 viewports via the local preview MCP. Shared chrome on every primitive:

  • Background rgb(20, 20, 22) (= --surface)
  • Border rgb(34, 34, 38) 1px (= --border)
  • Border-radius 10px
  • Padding 24px
  • Font-family Inter, color rgb(232, 232, 236) (= --text)

Mobile collapse (≤640px) verified for each: pipeline / row / chain all reduce to single-column grids; horizontal connectors hide where they no longer apply; no horizontal scroll; no overflow. Cascade primitive's tier grid (already vertical) reduces session-column width and label size for narrow viewports.

No collateral damage

  • Exactly 6 files touched (2 added, 4 modified).
  • schema.org / application/ld+json blocks: untouched on every page.
  • Breadcrumb / nav markup: untouched.
  • <head> meta tags: untouched (only the new <link rel="stylesheet" href="/assets/css/diagrams.css"> was added).
  • Phase 2 .concept-metadata blocks: untouched.
  • SVGs outside the four canonical pages: untouched. The strategic SVG on /concepts/governance-before-generation/ is the only legacy SVG kept on a touched page (keep-both decision); its internal <title> / <desc> / <g> are unmodified, only its outer-figure aria-labelledby was dropped to bring it in line with the new ARIA strategy.

Accessibility

Per-primitive ARIA convention applied uniformly:

  • Outer <figure> derives accessible name natively from <figcaption> (no redundant aria-labelledby on the figure).
  • Inner <div role="img"> carries aria-labelledby to both the visible title <p> id and a screen-reader-only description <p> id.
  • All visible text is real, selectable, indexable HTML.
  • DOM order matches visual reading order at all widths.
  • No motion, no keyboard interaction, no information conveyed by color alone.

What is NOT in this PR

  • Insight, demo, or compare-page embeds of the four primitives. Follow-up PR after the visual language is validated; the design lists the ~14 candidate embedding sites.
  • Atomization of primitives into shared __node / __arrow / __caption rules. Deferred until real reuse patterns emerge across embed sites.
  • Site-wide SVG cleanup. The ~30 SVGs on pages outside the four canonical homes stay as-is.
  • Full shared-stylesheet refactor (base.css + shared.css). Stays deferred per the existing memory note.
  • Schema.org / breadcrumb / head-meta changes.
  • The Phase 2 .concept-metadata block.

Test plan

  • [ ] Open each of the four canonical concept pages in a real browser and confirm the primitive renders at desktop, tablet, and mobile widths.
  • [ ] Verify the keep-both treatment on /concepts/governance-before-generation/ reads coherently (strategic SVG above the connecting paragraph; operational primitive below).
  • [ ] Confirm the cascade figcaption's /benchmark/ link resolves.
  • [ ] Inspect the page via DevTools Accessibility tab: outer <figure> accessible name from <figcaption>; inner role="img" aria-labelledby resolves to both title and sr-desc IDs.
  • [ ] Spot-check that PageSpeed Insights / Core Web Vitals are unchanged.

🤖 Generated with Claude Code

Related

Tickets: #119

Discussion

  • Anonymous

    Anonymous - 2026-05-21

    Originally posted by: github-actions[bot]

    mneme self-governance check

    Mode: warn - verdicts are visible but do not block merge. Rollout plan: .mneme/README.md.

    Summary: 0 pass, 0 warn, 0 fail, 5 unknown

    [!WARNING]
    Mneme returned one or more UNKNOWN verdicts. Governance output could not be trusted for those files. See the raw CLI output in the Details section below.

    verdict file
    ❔ UNKNOWN site/assets/css/diagrams.css
    ❔ UNKNOWN site/concepts/architectural-drift/index.html
    ❔ UNKNOWN site/concepts/enforcement-provenance/index.html
    ❔ UNKNOWN site/concepts/governance-before-generation/index.html
    ❔ UNKNOWN site/concepts/governance-propagation/index.html

    Details

    site/assets/css/diagrams.css — UNKNOWN Traceback (most recent call last): File "<frozen runpy="">", line 198, in _run_module_as_main File "<frozen runpy="">", line 88, in _run_code File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/cli.py", line 33, in <module> from mneme.adr_import import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_import.py", line 26, in <module> from mneme.adr_compiler import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_compiler.py", line 19, in <module> from mneme.adr_parser import parse_adr_directory File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_parser.py", line 16, in <module> import yaml ModuleNotFoundError: No module named 'yaml' </module></module></module></module></frozen></frozen>
    site/concepts/architectural-drift/index.html — UNKNOWN Traceback (most recent call last): File "<frozen runpy="">", line 198, in _run_module_as_main File "<frozen runpy="">", line 88, in _run_code File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/cli.py", line 33, in <module> from mneme.adr_import import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_import.py", line 26, in <module> from mneme.adr_compiler import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_compiler.py", line 19, in <module> from mneme.adr_parser import parse_adr_directory File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_parser.py", line 16, in <module> import yaml ModuleNotFoundError: No module named 'yaml' </module></module></module></module></frozen></frozen>
    site/concepts/enforcement-provenance/index.html — UNKNOWN Traceback (most recent call last): File "<frozen runpy="">", line 198, in _run_module_as_main File "<frozen runpy="">", line 88, in _run_code File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/cli.py", line 33, in <module> from mneme.adr_import import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_import.py", line 26, in <module> from mneme.adr_compiler import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_compiler.py", line 19, in <module> from mneme.adr_parser import parse_adr_directory File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_parser.py", line 16, in <module> import yaml ModuleNotFoundError: No module named 'yaml' </module></module></module></module></frozen></frozen>
    site/concepts/governance-before-generation/index.html — UNKNOWN Traceback (most recent call last): File "<frozen runpy="">", line 198, in _run_module_as_main File "<frozen runpy="">", line 88, in _run_code File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/cli.py", line 33, in <module> from mneme.adr_import import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_import.py", line 26, in <module> from mneme.adr_compiler import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_compiler.py", line 19, in <module> from mneme.adr_parser import parse_adr_directory File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_parser.py", line 16, in <module> import yaml ModuleNotFoundError: No module named 'yaml' </module></module></module></module></frozen></frozen>
    site/concepts/governance-propagation/index.html — UNKNOWN Traceback (most recent call last): File "<frozen runpy="">", line 198, in _run_module_as_main File "<frozen runpy="">", line 88, in _run_code File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/cli.py", line 33, in <module> from mneme.adr_import import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_import.py", line 26, in <module> from mneme.adr_compiler import ( File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_compiler.py", line 19, in <module> from mneme.adr_parser import parse_adr_directory File "/home/runner/work/mneme/mneme/mneme-project-memory/mneme/adr_parser.py", line 16, in <module> import yaml ModuleNotFoundError: No module named 'yaml' </module></module></module></module></frozen></frozen>

    Generated by .github/workflows/mneme-check.yml · query = PR title + file path · scope = repo-governance paths.

     
  • Anonymous

    Anonymous - 2026-05-21

    Ticket changed by: TheoV823

    • status: open --> closed
     

Log in to post a comment.

Auth0 Logo