Markdown graph markers
The Markdown files own the documentation graph. The sidebar, overview map, JSON exports and search corpus are generated views. There is no separately authored graph database, JavaScript catalogue or layout registry. manifest.mjs is a read-only compatibility loader.
Graph declarations are YAML frontmatter under doc_catalog, reaktor_graph and, for worked system designs, reaktor_designs. Keep declarations with the prose they describe. The Markdown source is available to people, retrieval systems and agents; the exported common graph definition preserves named ports, roles and ordinals.
Catalogue and navigation
Every document declares its catalogue information:
doc_catalog:
region: theory-foundations
order: 3
owner: Reaktor
kind: design
summary: One sentence explaining the subject and evidence boundary.
use: When a reader should use this document.
title and sidebar_label use normal Docusaurus frontmatter. Each document declares its membership exactly once through region. docs/home.md owns the public reaktor_regions hierarchy; docs/private/home.md owns the private hierarchy. A region has id, title, optional parent, description and ordering. Root regions contain subsections; documents belong to a subsection. A subsection with title: null appears directly under its parent in navigation. A subsection with order: manual uses each document's numeric order; other subsections use the existing last-commit ordering.
Both the map and Docusaurus use this hierarchy. Unnamed subsections are compressed in the map presentation. This does not change a document's declared region. Generated sidebars and layout coordinates are disposable build output.
Named ports bound to anchors
reaktor_graph:
version: 1
ports:
- {id: page, anchor: '', profile: document}
- {id: lifecycle, anchor: lifecycle, profile: section}
relations: []
The empty anchor denotes the whole document. A nonempty anchor must exist in the rendered Markdown. Prefer an explicit heading ID, for example ## Lifecycle {#lifecycle}, when links should survive a heading rename. Port IDs are local and stable; the endpoint reaktor-core#lifecycle means the named graph port, while the port's anchor determines the actual web URL. A port label comes from its heading, unless an authored label is needed for an HTML anchor. Renaming a heading changes the map label automatically. Removing or changing its anchor fails the build until the port is repaired or removed.
Profiles describe the endpoint's subject (document, section, procedure, navigation, or a more specific concept). These are editorial ports. A docs wire does not activate a runtime, deliver an event, grant authority or establish implementation qualification.
Explicit relationships and hyperedges
A binary link has one owner and two named endpoints:
relations:
- id: lifecycle-guide
kind: explains
from: page
to: reaktor-core#lifecycle
from is a port in the owning document. to is document-id#port-id. The generated relation ID is namespaced as owner-document:local-id. The shortcut expands to source[0] and target[0]; it is never inferred from a prose hyperlink.
For a hyperedge, declare every participant and role position:
relations:
- id: qualification-boundary
kind: explains
participants:
- {port: page, role: explanation, ordinal: 0}
- {document: reaktor-graph-theory, port: page, role: subject, ordinal: 0}
- {document: reaktor-hyperedge-theory, port: page, role: subject, ordinal: 1}
Omitting document selects the owner. Repeated roles need distinct nonnegative ordinals. Every relation must include its owner and at least two participants. Do not repeat the same declaration in the other participants: incoming connections are computed from the owner. Reciprocal citations can be distinct relationships when both documents independently reference each other.
Allowed kinds are references, requires, explains, implements, supersedes and derived-from. Use references for citations. Stronger kinds require prose that supports their meaning; implements also remains subject to the document's verification receipt. The migration of existing prose citations records references only, except previously authored typed relationships. Ordinary Markdown links remain checked for broken targets and searchable, but adding a prose link alone does not create a graph edge.
The Atlas projects binary relations as port-to-port wires and hyperedges as junctions with every role intact. Junctions are presentation, not additional semantic documents. Relationship filters affect visibility, not stored topology. Frame, card, pin, camera and visual theme come from Manna Atlas's shared Blueprint components.
Worked system designs
Worked-design chapters and the five theory topic pages additionally own reaktor_designs. Each entry contains its ID, title, domain, tags, design question, complete graph definition, ordinary Kotlin logic explanation and failure limits. Its graph uses the common regions, nodes, ports, relations and role-preserving incidences schema explained in graph theory and the language chapter.
npm run theory reads those Markdown markers and regenerates their teaching prose, SVGs, interactive scenes, JSON definitions and compilable Kotlin test declarations. Edit the markers to change a worked design; the chapter body is generated. theory/examples.mjs only reads Markdown. A theory type entry also owns its presentation symbol/label, domains, concrete module mapping and limits. Visitor-view examples can declare a selection and selector explanation for an illustrative read-only projection; the complete graph remains canonical. The generated <div data-reaktor-diagram="…"></div> embeds the exact shared Overview Atlas view. The portable corpus replaces that embed with its generated diagram and preserves every contract, incidence, law and legend for RAG/Manna/PDF reading. Do not edit generated scenes, type legends or SVGs by hand.
Source importers preserve catalogue and graph declarations when replacing imported prose, and anchor validation catches a declaration made stale by the import.
Updating a document
- Edit its Markdown prose and declarations together. Add or remove a port when the represented section changes. Update each owned relation affected by an endpoint change.
- Find incoming uses before deleting a port or document: search Markdown for
document-id#port-idand for hyperedge participants naming the document and port. Preserve stable anchors where possible. - For a new document, declare its catalogue placement and graph ports. For a new reading area, add its regions to the appropriate Markdown home page.
- Run
npm run theory, thennpm run nav,npm run corpusandnpm run nav:check. Run the marker and corpus checks withnode --test scripts/markdown-graph.test.mjs scripts/corpus-model.test.mjs scripts/theory.test.mjs. - Review the generated map and sidebar. Never fix a generated JSON, scene, sidebar or declaration by hand; fix the Markdown source and regenerate.
The build rejects duplicate regions/ports/relations, cyclic or missing regions, stale anchors, unknown document/port endpoints and duplicate role positions. Public graph declarations cannot target private content. Private declarations and their combined graph are emitted under the authenticated corpus; they never enter the public map or exports. Content hashes change when markers or prose change, and the map/index revision check prevents mixing releases.