Generated by kr0ki docgen. Pattern derived from b00t-cli/src/commands/docgen.rs.
pub enum McpTool { RenderDiagram , ListFormats , RenderKubeDiagram , RenderK8sTopology , RenderSysmlV2Snapshot , ListModelProjects , ListModelCommits , GetModelSnapshot , QueryModelElements , GetModelRoots , QueryModelRelationships , QueryModelGraph , }
One callable capability kr0ki-server exposes over both HTTP and MCP.
pub enum HttpMethod { Get , Post , }
pub enum ArgPlacement { Path , Query , Body , }
Where in the HTTP request a `tools/call` argument by this name lands.
pub enum SymbolKind { Function , Struct , Enum , Trait , Type , Macro , Mod , Const , Static , }
pub enum FlattenError { InvalidSvg (String) , ZeroSized , Encode (String) , }
pub enum RenderError { BadSource { status : u16 , body : String } , Unavailable (String) , Flatten (String) , }
pub enum ServiceError { Render ( RenderError) , CacheIo ( std :: io :: Error) , }
pub enum ProbeOutcome { CompanionFree , CompanionRequired , NoProbeSource , NeedsInvestigation { status : u16 , detail : String } , }
One candidate's probe result.
pub enum TurtleGraphError { Syntax ( TurtleSyntaxError) , }
pub enum QueryShape { TriplesAbout , RelatedVia , }
pub enum OutputKind { Svg , Png , }
Output artifact type. P0 renders SVG; PNG is a later Kroki capability (not all
formats support it — Kroki returns 400 when PNG is unavailable for a format).
pub enum CacheStatus { Hit , Miss , }
Whether a render served from cache or hit the backend.
pub enum RevisionStatus { Proposed , Accepted , Rejected , MergedReservedPhase4 , }
Canonical revision status. State-transition table (Plan 004 §7):
proposed -> accepted | rejected; accepted/rejected are terminal and
immutable. `merged` is reserved for Phase 4 two-parent revisions.
pub enum InputKind { DiagramSource , ProceduralModelReservedPhase4 , }
Canonical input lane (Plan 004 §2.1). Only `DiagramSource` is accepted in
Phase 0/1; `ProceduralModel` is named so the schema rejects unknown lanes
rather than silently widening.
pub enum Actor { Human { subject : String } , Agent { subject : String } , DevSession { subject : String } , }
Actor identity. Phase 0 has no production IdP: a signed dev session is a
`DevSubject`, and a bare thread ID is explicitly NOT a session (Plan 004
§6 Phase 0.4).
pub enum ApprovalDecision { Accept , Reject , }
pub enum SessionError { Malformed , BadSignature , Expired , CapabilityDenied { required : & 'static str , } , }
Errors a session check can produce. Typed so the HTTP layer maps each to
its own status and the audit log records exactly why a write was denied.
=`)"] via"] — pick the one the target server's"] pub enum PageParamStyle { Hyphenated , JsonApiBracket , }
Which query-parameter convention a target server uses for element paging.
Flexo and the OMG Java pilot use hyphenated params (`page-after=`); some
JSON:API-flavoured OMG-pilot deployments use bracket form (`page[after]=`)
instead. Configured once per [`crate::SysmlV2Client`] via
[`crate::SysmlV2Client::with_page_param_style`] — pick the one the target server's
own docs/`EVAL-*.md` say it expects.
pub enum Direction { In , Out , Both , }
Direction filter for `relationships(..)` → `?direction=in|out|both`.
pub enum ClientError { Http ( reqwest :: Error) , Status { code : u16 , body : String } , Json ( serde_json :: Error) , }
Anything that can go wrong talking to an OMG Systems Modeling API server.
pub mod format
pub mod harvest
pub mod b00t_graph
pub mod cache
pub mod catalog
pub mod docgen
pub mod examples
pub mod flatten
pub mod format
pub mod graph_store
pub mod k8s_recognizer
pub mod mcp_tool
pub mod probe
pub mod render
pub mod requirements_render
pub mod rust_recognizer
pub mod sysml_lift
pub mod sysml_render
pub mod ufo_graph
pub mod health
pub mod workspace_types
pub fn lift_edge (edge : & OntologicalEdge) -> LiftedRelation
Lift a single edge. Total over every current and future (`#[non_exhaustive]`)
[`UfoRelation`] variant — see the module docs for the mapping.
pub fn lift_edges (edges : & [OntologicalEdge]) -> Vec < LiftedRelation >
Lift every edge in a slice, preserving order.
pub fn walk_and_harvest (root : & Path) -> anyhow :: Result < Vec < Symbol > >
Walk `root` recursively, parse every `.rs` file, and collect public symbols.
pub fn harvest_crate < P : AsRef < Path > > (root : P) -> anyhow :: Result < Vec < Symbol > >
Harvest all symbols from a crate source tree.
pub fn harvest_kr0ki_workspace () -> anyhow :: Result < Vec < Symbol > >
Convenience: harvest kr0ki's own workspace crates.
pub fn export_static_mdb00k (output_dir : impl AsRef < Path >) -> anyhow :: Result < () >
Emit a self-contained static mdb00k/playb00k bundle from the current workspace.
The bundle contains an HTML symbol index plus the machine-readable docgen
exports used by b00t-aware consumers. It is backend-free so it can be
published by GitHub Pages without a running kr0ki renderer.
pub fn format_json (symbols : & [Symbol]) -> anyhow :: Result < String >
JSON — machine-readable, lossless.
pub fn format_tomllm (symbols : & [Symbol]) -> String
Tomllm — b00t docgen convention.
Each symbol becomes a `[[qualified_name]]` table. A `b00t:map v1`
trailer carries metadata so b00t datum parsers can classify the export.
pub fn format_rustdoc (symbols : & [Symbol]) -> String
Rustdoc — rustdoc-style comment blocks suitable for pasting into a .rs file
or for rendering by rustdoc viewers.
pub fn format_html (symbols : & [Symbol] , title : & str , diagram_example_d2 : & str) -> String
HTML — standalone page (MVP). No external CSS/JS frameworks.
Includes a diagram example rendered by kr0ki itself.
pub fn format_html_with_live_flow (symbols : & [Symbol] , title : & str , diagram_example_d2 : & str , live_flow_url : Option < & str > ,) -> String
HTML documentation with an optional service-rendered Rust flow image.
Static mdb00k exports deliberately pass `None`: GitHub Pages has no kr0ki
renderer behind it, so the portable structural SVG remains available. The
live server passes its same-origin endpoint, which exercises the complete
D2 -> kr0ki -> Kroki render path.
pub fn to_d2 (view : & ViewResult) -> String
Deterministically lower an induced requirement view to D2 source.
pub fn svg_to_png (svg : & [u8]) -> Result < Vec < u8 > , FlattenError >
Render `svg` to PNG bytes at the SVG's own intrinsic pixel size (no upscaling).
pub fn used_use_cases () -> Vec < & 'static str >
All use-case tags actually referenced by [`TYPES`], in [`USE_CASES`] order.
The gallery filter renders exactly these (no empty filters).
pub fn by_id (id : & str) -> Option < & 'static DiagramType >
pub fn by_use_case (tag : & str) -> Vec < & 'static DiagramType >
pub fn discovery_guide () -> String
The type-discovery series (Plan 005 §2.2) as agent-consumable text: the
intent vocabulary and one line per use case so the LLM asks grounded
questions instead of inventing categories.
pub async fn fetch_registered_converters (client : & reqwest :: Client , backend : & str ,) -> anyhow :: Result < BTreeMap < String , String > >
`GET {backend}/health`'s `version` map, minus the `"kroki"` server-info
entry — every converter Kroki has registered, *regardless* of whether a
companion is actually running for it (issue #18/#20's own caveat: this
alone is not the "does it need a companion" signal, just the candidate
list; probing each one is).
pub fn candidates (registered : & BTreeMap < String , String >) -> Vec < String >
Registered converters not already in [`DiagramFormat::ALL`].
pub async fn probe_one (client : & reqwest :: Client , backend : & str , slug : & str ,) -> anyhow :: Result < ProbeOutcome >
Probe one candidate slug against `backend`, using its vendored source if
one exists.
pub fn build_ufo_graph (snapshot : & ModelSnapshot) -> Vec < OntologicalEdge >
Build the canonical UFO semantic graph for one `ModelSnapshot`.
Walks every element, lifting the ones whose `@type` is a recognized raw
KerML relationship kind (see module docs) into an [`OntologicalEdge`].
Non-relationship elements (`PartUsage`, `PartDefinition`, `Package`, …)
and unrecognized/malformed relationship elements are silently excluded —
they stay representable at the `ModelSnapshot`/`iso_ir` layer for a later
pipeline stage, never dropped as an error.
pub fn walk_and_recognize (root : & Path) -> anyhow :: Result < (Vec < Node > , Vec < Edge >) >
Walk `root` recursively, parse every `.rs` file, and recognize module
containment + struct/enum field-type relationships across the whole tree.
pub fn recognize_source (source : & str) -> syn :: Result < (Vec < Node > , Vec < Edge >) >
Parse a single source string and recognize it in isolation (local-type
resolution only sees structs/enums declared in this same string). Mainly
for tests and single-file callers; [`walk_and_recognize`] is the
whole-tree entry point real callers want.
pub fn workspace_member_crate_names (workspace_root : & Path) -> anyhow :: Result < HashSet < String > >
Every crate name declared as a `[package] name` of a workspace member
listed in `workspace_root/Cargo.toml`'s `[workspace] members`, as the
Rust identifier form `use` paths need (hyphens replaced with
underscores — Cargo package names commonly use hyphens, `use` paths
never can).
Members are read as literal paths only, not glob patterns
(`kr0ki`'s own workspace lists every member explicitly; expanding a glob
pattern like `"crates/*"` is unimplemented — a member entry that isn't a
real directory with its own `Cargo.toml` is silently skipped, same
"never guess, never error on the unrecognized" posture as every other
heuristic in this module). Returns an empty set, not an error, for a
`Cargo.toml` with no `[workspace]` table (a single, non-workspace crate
has no siblings to distinguish from external dependencies).
pub fn cross_crate_requires (files : & [syn :: File] , this_crate : & str , workspace_crates : & HashSet < String > ,) -> Vec < Edge >
`use other_crate::Item` importing from a workspace-sibling crate becomes
a `requires` edge from `this_crate` to `other_crate`
(`PATTERNS-rust-source.md` §2 row 5). An import from a genuine external
dependency (anything not in `workspace_crates`) is not recognized — this
module has no source for it to place a meaningful node, and telling
"interesting to this workspace's own architecture" apart from "just a
library dependency" is exactly what `workspace_crates` (from
[`workspace_member_crate_names`]) answers. `self`/`super`/`crate` leading
segments and a `use` of `this_crate`'s own name are excluded — neither
denotes a *different* crate. One edge per distinct target crate, however
many `use` sites reference it.
pub fn relation_label (relation : & Relation) -> & str
The KerML/SysML-v2 relationship name for a relation's edges, or (for
[`Relation::Domain`]) its own free-form `kind` classifier.
pub fn to_d2 (relations : & [Relation]) -> String
Emit [D2](https://d2lang.com) text for `relations`: one node declaration
per distinct [`ElementId`], then one edge line per relation-edge (in
input order). Deterministic — same input always yields byte-identical
output.
pub fn to_mermaid (relations : & [Relation]) -> String
Emit a Mermaid flowchart for `relations`. Mermaid auto-declares a node
the first time an id appears in an edge statement, so (unlike [`to_d2`])
no separate node-declaration pass is needed.
Mermaid node ids may not contain most punctuation; [`ElementId`]s can
(content hashes, KerML qualified names with `::`). Each id is therefore
mapped to a synthetic `n0`, `n1`, … id (first-seen order, matching
[`distinct_nodes`]) with the real id as that node's `["label"]` text —
the same "opaque id, separate display label" split D2 gets for free from
its quoted-string ids.
pub fn triples_to_type_graph (triples : & [(String , String , Term)]) -> TypeRelationshipGraph
Build a [`TypeRelationshipGraph`] from parsed Turtle triples (see module docs
for the classification rules).
pub fn parse_turtle_to_type_graph (ttl : & [u8]) -> Result < TypeRelationshipGraph , TurtleGraphError >
Parse `ttl` and build its [`TypeRelationshipGraph`] in one step.
pub fn builtin_rules () -> Vec < SimpleFieldRule >
The built-in rule set, ported from `vendor/kubediagrams/bin/kube-diagrams.yaml`
(see module docs for the exact call sites).
pub fn cache_key (format : DiagramFormat , output : OutputKind , source : & str) -> String
The cache key for one render request.
`key = SHA256("kr0ki/v1" ‖ 0x1f ‖ format_slug ‖ 0x1f ‖ output_ext ‖ 0x1f ‖ source)`,
lowercase hex. The domain prefix and the `0x1f` (ASCII Unit Separator, cannot appear
in a slug/ext) field delimiters make the concatenation unambiguous — no length
prefixing needed, no `("a","bc")` vs `("ab","c")` collision.
NOTE: keyed on the *raw* diagram source as given. The PRD's real key folds in
"ledgrrr's per-commit serialized KerML" — that only applies to the SysML-model
ingestion path, which P0 does not have. For raw Kroki-family text, the text itself
is the whole input.
pub fn model_cache_key (view_kind : & str , notation : & str , content_hash : & str , rule_set_version : & str ,) -> String
The cache key for one SysML-model render (PLAN-KR0KI-002 §3).
`key = SHA256("kr0ki/v1" ‖ 0x1f ‖ view_kind ‖ 0x1f ‖ notation ‖ 0x1f ‖ content_hash
‖ 0x1f ‖ rule_set_version)`, lowercase hex. The `content_hash` is the
`ModelSnapshot.content_hash` from `kr0ki-sysmlv2-client` — deterministic and
order-independent, so a new commit yields a new key and invalidates derived
diagrams. `view_kind` is the string form of the view's `ufo_types::SysmlViewKind`
(accepted as `&str` here so this crate's cache module stays free of a `ufo-types`
dependency). `notation` is the diagram notation slug (`mermaid`, `d2`, …).
`rule_set_version` is a pattern recognizer's rule-set version hash (e.g.
[`crate::k8s_recognizer::KubernetesRecognizer::rule_set_version`]) — a rule-set
change (built-in or CRD extension) must invalidate every diagram derived through
it. Pass `""` for a source arm with no recognizer in its path yet (the SysML-v2
arm: box 2's `ModelSnapshot` already speaks near-box-4 vocabulary, per
PLAN-KR0KI-002 §2.2 — no recognizer needed).
pub fn router (state : AppState , auth_token : Option < String >) -> Router
If `auth_token` is Some, inject a `RequireAuth` layer that rejects requests
missing `Authorization: Bearer <token>`.
pub fn routes () -> Router < AppState >
pub async fn collect (state : & AppState) -> HealthReport
Build the full report. All network probes run concurrently; total latency
is bounded by CHECK_TIMEOUT, not the number of dependencies.
pub fn derive_next_after (link_header : Option < & str > , items : & [Element] , requested_size : Option < u32 > , style : PageParamStyle ,) -> Option < String >
Derive the cursor for the next page of elements.
Priority:
1. **`Link: rel="next"` header present** — parse that URL and return its
`page-after` query-parameter value. Authoritative when present.
2. **No `Link` header, but the caller requested an explicit `page-size` and got a
full page** (`items.len() >= size`) — assume more remain and use the last
element's `@id` as the next cursor. OMG PSM page cursors are element ids, so this
is the documented fallback for SysON-style servers.
3. **Otherwise** (short page, or no `Link` header and no size hint) — the collection
is exhausted → `None`.
Consequence for `all_elements`: against a spec-compliant server it follows `Link`
headers; against a `Link`-less server it only pages when the caller passed a
`page-size` (which `all_elements` itself does not — it takes whatever the server's
default page returns). This is deliberate: guessing a cursor without either a
`Link` header or an explicit size risks an infinite loop on a server that ignores
`page-after`.
pub fn parse_link_next (header : & str) -> Option < String >
Extract the URL of the `rel="next"` entry from an RFC 8288 `Link` header value.
Handles `<url>; rel="next"`, `rel=next`, `rel='next'`, and multiple comma-separated
entries. A URL containing a literal (non-encoded) comma would break the split —
acceptable, since the servers in scope percent-encode cursors.
pub fn extract_query_param (url : & str , key : & str) -> Option < String >
Return the (percent-decoded) value of query parameter `key` in `url`.
pub fn canonical_json (v : & Value) -> Vec < u8 >
Serialize `v` to bytes with **object keys sorted recursively**. Array element order
is preserved (it is semantically significant in JSON); only object member order is
normalized. Scalars use `serde_json`'s compact form.
Known limitation: numbers are emitted as `serde_json` parses them, so `1` and `1.0`
hash differently. OMG PSM element payloads do not rely on that distinction.
pub fn compute_content_hash (elements : & [Element] , roots : & [String]) -> String
Lowercase-hex SHA-256 over:
`b"kr0ki-sysmlv2/v1"`
then, for each element **sorted by `@id`**: `0x1f`, `@id`, `0x1f`, `canonical_json(fields + @type)`
then `0x1e`
then each root id **sorted**, joined by `0x1f`.
pub const USE_CASES : & [& str] = & ["process flow" , "interaction" , "data model" , "network" , "state machine" , "architecture" , "chart" , "sketch" , "timeline" , "hardware" ,] ;
Controlled vocabulary for intent tags. Gallery filter offers exactly these;
multi-select is OR.
pub const TYPES : & [DiagramType] = & [DiagramType { id : "flowchart" , syntax : "d2" , example_id : "d2-rust-flow" , name : "Flowchart" , use_cases : & ["process flow" , "sketch"] , blurb : "Steps and decision branches in a process, drawn as boxes and arrows." , sample_prompt : "Draw a flowchart of the process I'm about to describe. Ask me about the steps and decision points first." , } , DiagramType { id : "activity" , syntax : "plantuml" , example_id : "plantuml-activity" , name : "Activity diagram" , use_cases : & ["process flow"] , blurb : "A workflow with branches, merges, and swimlanes for who does what." , sample_prompt : "Draw an activity diagram (PlantUML) of the workflow I describe. Ask me about the steps, decisions, and who performs them first." , } , DiagramType { id : "use-case" , syntax : "plantuml" , example_id : "plantuml-use-case" , name : "Use case diagram" , use_cases : & ["process flow" , "interaction"] , blurb : "Actors outside a system boundary and the goals they can achieve." , sample_prompt : "Draw a use case diagram (PlantUML) for the system I describe. Ask me about the actors and their goals first." , } , DiagramType { id : "state" , syntax : "plantuml" , example_id : "plantuml-state" , name : "State machine" , use_cases : & ["state machine" , "process flow"] , blurb : "The states one thing can be in and the events that move it between them." , sample_prompt : "Draw a state machine diagram (PlantUML) for the thing I describe. Ask me about its states and transitions first." , } , DiagramType { id : "sequence" , syntax : "plantuml" , example_id : "plantuml-sequence" , name : "Sequence diagram" , use_cases : & ["interaction" , "process flow"] , blurb : "Who talks to whom, in what order, over time — request/response flows." , sample_prompt : "Draw a sequence diagram (PlantUML) of the interaction I describe. Ask me about the participants and the order of messages first." , } , DiagramType { id : "component" , syntax : "plantuml" , example_id : "plantuml-component" , name : "Component diagram" , use_cases : & ["architecture"] , blurb : "Software building blocks and the interfaces between them." , sample_prompt : "Draw a component diagram (PlantUML) of the system I describe. Ask me about the components and their interfaces first." , } , DiagramType { id : "c4-context" , syntax : "c4plantuml" , example_id : "c4-context" , name : "C4 context diagram" , use_cases : & ["architecture"] , blurb : "Your system as a box in the middle, surrounded by users and dependencies." , sample_prompt : "Draw a C4 context diagram (C4-PlantUML) for the system I describe. Ask me about the system, its users, and external dependencies first." , } , DiagramType { id : "class" , syntax : "plantuml" , example_id : "plantuml-class" , name : "Class diagram" , use_cases : & ["data model" , "architecture"] , blurb : "Types, their fields, and inheritance/association relationships." , sample_prompt : "Draw a class diagram (PlantUML) for the domain I describe. Ask me about the classes and their relationships first." , } , DiagramType { id : "erd" , syntax : "plantuml" , example_id : "plantuml-erd" , name : "Entity-relationship diagram" , use_cases : & ["data model"] , blurb : "Database entities and how they reference each other (1:N, M:N)." , sample_prompt : "Draw an entity-relationship diagram (PlantUML) for the data I describe. Ask me about the entities and their relationships first." , } , DiagramType { id : "dbml" , syntax : "dbml" , example_id : "dbml-cache-entry" , name : "Database schema (DBML)" , use_cases : & ["data model"] , blurb : "Tables, columns, and foreign keys in a database-flavoured notation." , sample_prompt : "Draw a DBML database schema for the data model I describe. Ask me about the tables, columns, and foreign keys first." , } , DiagramType { id : "chart" , syntax : "vegalite" , example_id : "vegalite-cache-outcomes" , name : "Data chart (Vega-Lite)" , use_cases : & ["chart"] , blurb : "Bars, lines, and points for quantitative data." , sample_prompt : "Draw a Vega-Lite chart for the data I describe. Ask me about the data shape and the comparison I want to show first." , } , DiagramType { id : "network" , syntax : "nwdiag" , example_id : "nwdiag-topology" , name : "Network diagram" , use_cases : & ["network"] , blurb : "Segments, nodes, and addresses — how machines connect." , sample_prompt : "Draw a network diagram (nwdiag) of the infrastructure I describe. Ask me about the segments, nodes, and addressing first." , } , DiagramType { id : "k8s-topology" , syntax : "k8s-topology" , example_id : "k8s-topology-web-service" , name : "Kubernetes topology" , use_cases : & ["network" , "architecture"] , blurb : "How workloads and services in a cluster relate, from a manifest." , sample_prompt : "Render the Kubernetes topology (k8s-topology) for the manifest I provide. Ask me for the manifest first if I haven't pasted one." , } , DiagramType { id : "rack" , syntax : "rackdiag" , example_id : "rackdiag-deployment" , name : "Rack diagram" , use_cases : & ["hardware" , "network"] , blurb : "Server racks with units stacked in order." , sample_prompt : "Draw a rack diagram (rackdiag) of the hardware I describe. Ask me about the rack units first." , } , DiagramType { id : "packet" , syntax : "packetdiag" , example_id : "packetdiag-cache-key" , name : "Packet structure" , use_cases : & ["hardware"] , blurb : "Byte-level packet or register layouts." , sample_prompt : "Draw a packet structure diagram (packetdiag) for the protocol I describe. Ask me about the fields and widths first." , } , DiagramType { id : "wiring" , syntax : "wireviz" , example_id : "wireviz-harness" , name : "Wiring diagram" , use_cases : & ["hardware"] , blurb : "Cables and pin-to-pin connections between connectors." , sample_prompt : "Draw a wiring diagram (WireViz) for the harness I describe. Ask me about the connectors and cables first." , } , DiagramType { id : "bytefield" , syntax : "bytefield" , example_id : "bytefield-cache-key" , name : "Bytefield" , use_cases : & ["hardware"] , blurb : "Memory and protocol layouts, byte by byte." , sample_prompt : "Draw a bytefield diagram for the layout I describe. Ask me about the fields and byte boundaries first." , } , DiagramType { id : "block" , syntax : "blockdiag" , example_id : "blockdiag-pipeline" , name : "Block diagram" , use_cases : & ["sketch" , "architecture"] , blurb : "Simple labelled blocks and arrows — the whiteboard classic." , sample_prompt : "Draw a block diagram (blockdiag) of what I describe. Ask me about the blocks and connections first." , } , DiagramType { id : "sketch" , syntax : "ditaa" , example_id : "ditaa-artifact-flow" , name : "ASCII sketch (ditaa)" , use_cases : & ["sketch"] , blurb : "Hand-drawn look from ASCII-art boxes." , sample_prompt : "Turn my ASCII sketch into a ditaa diagram. Ask me to paste the ASCII first." , } , DiagramType { id : "svgbob" , syntax : "svgbob" , example_id : "svgbob-ascii-pipeline" , name : "ASCII diagram (svgbob)" , use_cases : & ["sketch"] , blurb : "Crisp rendering of ASCII-art diagrams." , sample_prompt : "Render my ASCII art with svgbob. Ask me to paste the ASCII first." , } , DiagramType { id : "timing" , syntax : "plantuml" , example_id : "plantuml-timing" , name : "Timing diagram" , use_cases : & ["timeline" , "state machine"] , blurb : "Signal levels and state over a shared time axis." , sample_prompt : "Draw a timing diagram (PlantUML) for the signals I describe. Ask me about the signals and their timing first." , } , DiagramType { id : "wavedrom" , syntax : "wavedrom" , example_id : "wavedrom-cache-timing" , name : "Waveform (WaveDrom)" , use_cases : & ["timeline" , "hardware"] , blurb : "Digital signal waveforms with clock edges." , sample_prompt : "Draw a WaveDrom waveform for the signals I describe. Ask me about the signal names and clock cycles first." , } , DiagramType { id : "gantt" , syntax : "plantuml" , example_id : "plantuml-gantt" , name : "Gantt chart" , use_cases : & ["timeline" , "process flow"] , blurb : "Tasks on a calendar with dependencies and milestones." , sample_prompt : "Draw a Gantt chart (PlantUML) for the plan I describe. Ask me about the tasks, durations, and dependencies first." , } , DiagramType { id : "deployment" , syntax : "plantuml" , example_id : "plantuml-deployment" , name : "Deployment diagram" , use_cases : & ["architecture" , "network"] , blurb : "Artifacts placed on nodes — what runs where." , sample_prompt : "Draw a deployment diagram (PlantUML) for the system I describe. Ask me about the nodes and artifacts first." , } ,] ;
The full taxonomy. Order is the gallery's default (All) order: grouped by
use case family — flow, interaction, structure, data, sketch/hardware.
entry,"] pub const ALL : & [PlaybookExample] = & [PlaybookExample { id : "plantuml-request" , format : "plantuml" , title : "Operator render request" , input_kind : "procedural code" , description : "A request crosses kr0ki and its artifact cache." , source : "@startuml\nactor Operator\nrectangle kr0ki\ndatabase Cache\nOperator -> kr0ki : render source\nkr0ki -> Cache : read/write artifact\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-activity" , format : "plantuml" , title : "Release activity flow" , input_kind : "PlantUML activity diagram" , description : "Release decisions and hand-offs, including an approval branch." , source : "@startuml\nstart\n:Build release;\nif (Approved?) then (yes)\n :Deploy;\nelse (no)\n :Revise;\nendif\nstop\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-use-case" , format : "plantuml" , title : "Release use cases" , input_kind : "PlantUML use case diagram" , description : "An operator starts releases and an approver authorizes them." , source : "@startuml\nleft to right direction\nactor Operator\nactor Approver\nrectangle ReleaseService {\n usecase \"Start release\" as Start\n usecase \"Approve release\" as Approve\n}\nOperator --> Start\nApprover --> Approve\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-state" , format : "plantuml" , title : "Release state machine" , input_kind : "PlantUML state diagram" , description : "A release moves from draft through approval to deployment." , source : "@startuml\n[*] --> Draft\nDraft --> PendingApproval\nPendingApproval --> Approved\nPendingApproval --> Draft : revise\nApproved --> Deployed\nDeployed --> [*]\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-sequence" , format : "plantuml" , title : "Release approval sequence" , input_kind : "PlantUML sequence diagram" , description : "The operator, service, and approver exchange messages in time order." , source : "@startuml\nactor Operator\nparticipant ReleaseService\nparticipant Approver\nOperator -> ReleaseService : submit release\nReleaseService -> Approver : request approval\nApprover --> ReleaseService : approve\nReleaseService --> Operator : deployed\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-component" , format : "plantuml" , title : "Release components" , input_kind : "PlantUML component diagram" , description : "The release API delegates deployment and notification responsibilities." , source : "@startuml\n[Release API] --> [Deployment worker]\n[Release API] --> [Notification service]\n[Deployment worker] --> [Cluster]\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-class" , format : "plantuml" , title : "Release domain classes" , input_kind : "PlantUML class diagram" , description : "A release has artifacts and an approval decision." , source : "@startuml\nclass Release {\n version\n status\n}\nclass Artifact {\n digest\n}\nclass Approval {\n approvedBy\n}\nRelease \"1\" o-- \"*\" Artifact\nRelease \"1\" --> \"1\" Approval\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-erd" , format : "plantuml" , title : "Release data relationships" , input_kind : "PlantUML entity relationship diagram" , description : "Release records reference their artifacts and approval records." , source : "@startuml\nentity release {\n * id : uuid\n version : text\n}\nentity artifact {\n * digest : text\n}\nentity approval {\n * approver : text\n}\nrelease ||--o{ artifact\nrelease ||--|| approval\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-timing" , format : "plantuml" , title : "Release timing" , input_kind : "PlantUML timing diagram" , description : "Approval and deployment states share a time axis." , source : "@startuml\nrobust \"approval\" as A\nrobust \"deployment\" as D\n@0\nA is Pending\nD is Idle\n@5\nA is Approved\n@10\nD is Deploying\n@15\nD is Live\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-gantt" , format : "plantuml" , title : "Release Gantt plan" , input_kind : "PlantUML Gantt chart" , description : "Build, approval, and deployment scheduled as dependent tasks." , source : "@startgantt\nProject starts 2026-01-01\n[Build] lasts 2 days\n[Approve] starts at [Build]'s end and lasts 1 day\n[Deploy] starts at [Approve]'s end and lasts 1 day\n@endgantt\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "plantuml-deployment" , format : "plantuml" , title : "Release deployment" , input_kind : "PlantUML deployment diagram" , description : "A release artifact runs on the deployment worker in the cluster." , source : "@startuml\nnode Cluster {\n node \"Deployment worker\" {\n artifact \"release image\"\n }\n}\ncloud Registry\nRegistry --> \"release image\"\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "c4-context" , format : "c4plantuml" , title : "Renderer context" , input_kind : "architecture model" , description : "Operator, kr0ki, and the Kroki backend in a C4 context." , source : "@startuml\n!include <C4/C4_Context>\nPerson(operator, \"Operator\")\nSystem(kr0ki, \"kr0ki\", \"cached diagram renderer\")\nSystem_Ext(kroki, \"Kroki\", \"diagram backend\")\nRel(operator, kr0ki, \"submits source\")\nRel(kr0ki, kroki, \"renders\")\n@enduml\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "graphviz-pipeline" , format : "graphviz" , title : "IAC to artifact pipeline" , input_kind : "IAC / code" , description : "The shared IAC → procedural diagram → Kroki → artifact story." , source : "digraph kr0ki {\n rankdir=LR;\n input [label=\"IAC / code\"];\n diagram [label=\"procedural diagram\"];\n kroki [label=\"Kroki\"];\n artifact [label=\"SVG / PNG\"];\n input -> diagram -> kroki -> artifact;\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "d2-rust-flow" , format : "d2" , title : "Rust render flow" , input_kind : "Rust code flow" , description : "The Box-5 route, cache, backend, and artifact flow used by /docs." , source : "# kr0ki Box-5 Rust code-flow — executable playb00k view source.\ndirection: right\nclient: HTTP caller { shape: person }\nrouter: Axum router { shape: hexagon }\nservice: RenderService { shape: rectangle; style.fill: \"#d8eaff\" }\ncache: FsCache { shape: cylinder; style.fill: \"#e9f7df\" }\nbackend: HttpKrokiBackend { shape: rectangle; style.fill: \"#fff0cc\" }\nkroki: Kroki renderer { shape: cloud }\nartifact: SVG or PNG { shape: document; style.fill: \"#f7e6ff\" }\nclient -> router: POST /render/:format\nrouter -> service: route + auth\nservice -> cache: lookup\ncache -> service: hit or miss\nservice -> backend: miss only\nbackend -> kroki: render\nkroki -> backend: bytes\nbackend -> service: artifact\nservice -> cache: atomic write\nservice -> client: headers + bytes\nclient -> artifact: receives\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "vegalite-cache-outcomes" , format : "vegalite" , title : "Cache outcome metrics" , input_kind : "structured telemetry" , description : "A small declarative visualization of cache hit/miss outcomes." , source : "{\n \"$schema\": \"https://vega.github.io/schema/vega-lite/v5.json\",\n \"description\": \"kr0ki render cache outcomes\",\n \"data\": {\"values\": [{\"status\":\"miss\",\"count\":1},{\"status\":\"hit\",\"count\":3}]},\n \"mark\": \"bar\",\n \"encoding\": {\n \"x\": {\"field\":\"status\",\"type\":\"nominal\"},\n \"y\": {\"field\":\"count\",\"type\":\"quantitative\"},\n \"color\": {\"field\":\"status\",\"type\":\"nominal\"}\n }\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "ditaa-artifact-flow" , format : "ditaa" , title : "ASCII artifact flow" , input_kind : "ASCII IAC sketch" , description : "A text-only source converted to a procedural diagram." , source : "+---------+ +--------+ +---------+\n| IAC/code|----->| kr0ki |----->| SVG/PNG |\n+---------+ +--------+ +---------+\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "nomnoml-components" , format : "nomnoml" , title : "Renderer components" , input_kind : "component model" , description : "A concise component relation view of the render loop." , source : "[IAC / code]->[RenderService]\n[RenderService]->[FsCache]\n[RenderService]->[Kroki]\n[Kroki]->[SVG / PNG]\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "wavedrom-cache-timing" , format : "wavedrom" , title : "Cache timing" , input_kind : "procedural timing model" , description : "The request, cache, and backend sequence as a timing diagram." , source : "{ \"signal\": [\n { \"name\": \"render request\", \"wave\": \"01..\" },\n { \"name\": \"cache\", \"wave\": \"x3.4\", \"data\": [\"lookup\", \"hit\", \"artifact\"] },\n { \"name\": \"backend\", \"wave\": \"0.1.\" }\n]}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "vega-cache-outcomes-bar" , format : "vega" , title : "Cache outcomes, low-level grammar" , input_kind : "declarative visualization" , description : "The Vega grammar the vegalite fixture's spec compiles down to conceptually." , source : "{\n \"$schema\": \"https://vega.github.io/schema/vega/v5.json\",\n \"width\": 200, \"height\": 100, \"padding\": 5,\n \"data\": [{\"name\": \"table\", \"values\": [{\"category\":\"miss\",\"amount\":1},{\"category\":\"hit\",\"amount\":3}]}],\n \"scales\": [\n {\"name\":\"xscale\",\"type\":\"band\",\"domain\":{\"data\":\"table\",\"field\":\"category\"},\"range\":\"width\",\"padding\":0.2},\n {\"name\":\"yscale\",\"domain\":{\"data\":\"table\",\"field\":\"amount\"},\"nice\":true,\"range\":\"height\"}\n ],\n \"marks\": [{\"type\":\"rect\",\"from\":{\"data\":\"table\"},\"encode\":{\"enter\":{\"x\":{\"scale\":\"xscale\",\"field\":\"category\"},\"width\":{\"scale\":\"xscale\",\"band\":1},\"y\":{\"scale\":\"yscale\",\"field\":\"amount\"},\"y2\":{\"scale\":\"yscale\",\"value\":0}}}}]\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "blockdiag-pipeline" , format : "blockdiag" , title : "Render pipeline blocks" , input_kind : "block diagram" , description : "client -> router -> service -> cache as block-diag boxes." , source : "blockdiag {\n client -> router -> service -> cache;\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "actdiag-request-flow" , format : "actdiag" , title : "Request activity flow" , input_kind : "activity diagram" , description : "The request's path through the service and cache as an activity diagram." , source : "actdiag {\n client -> service -> cache;\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "seqdiag-request-sequence" , format : "seqdiag" , title : "Request sequence" , input_kind : "sequence diagram" , description : "client, service, cache, and backend as a seqdiag sequence." , source : "seqdiag {\n client -> service -> cache -> backend;\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "nwdiag-topology" , format : "nwdiag" , title : "kr0ki / kroki network topology" , input_kind : "network diagram" , description : "The two services on one local network segment." , source : "nwdiag {\n network kr0ki {\n kr0ki;\n kroki;\n }\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "packetdiag-cache-key" , format : "packetdiag" , title : "Cache key packet layout" , input_kind : "packet diagram" , description : "A packet-style field layout, reused here for the cache key." , source : "packetdiag {\n 0-15: Cache Key Hash\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "rackdiag-deployment" , format : "rackdiag" , title : "Local pod rack layout" , input_kind : "rack diagram" , description : "kr0ki-server and kroki as rack units in the local k0s pod." , source : "rackdiag {\n 1: kr0ki-server\n 2: kroki\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "erd-render-request" , format : "erd" , title : "Render request entity" , input_kind : "entity relationship" , description : "A minimal entity-relationship fixture." , source : "[render] {label: \"render request\"}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "umlet-class" , format : "umlet" , title : "kr0ki class sketch" , input_kind : "UML sketch" , description : "A single UMLet class element." , source : "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<diagram program=\"umlet\" version=\"15.1\">\n <help_text></help_text>\n <zoom_level>10</zoom_level>\n <element>\n <id>UMLClass</id>\n <coordinates><x>10</x><y>10</y><w>140</w><h>50</h></coordinates>\n <panel_attributes>kr0ki</panel_attributes>\n <additional_attributes/>\n </element>\n</diagram>\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "pikchr-pipeline" , format : "pikchr" , title : "kr0ki to kroki pipeline" , input_kind : "pic-family diagram" , description : "Two boxes and an arrow via pikchr's PIC-derived language." , source : "box \"kr0ki\"; arrow; box \"kroki\"\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "goat-ascii-pipeline" , format : "goat" , title : "ASCII pipeline (GoAT)" , input_kind : "ASCII art diagram" , description : "Hand-drawn ASCII boxes, rendered by GoAT." , source : "+-------+ +-------+\n| kr0ki | --> | kroki |\n+-------+ +-------+\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "bytefield-cache-key" , format : "bytefield" , title : "Cache key byte layout" , input_kind : "byte field diagram" , description : "A byte-field-style column header and box." , source : "(draw-column-headers)\n(draw-box \"cache key\")\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "dbml-cache-entry" , format : "dbml" , title : "Cache entry schema" , input_kind : "database schema (DBML)" , description : "The FsCache entry shape as a DBML table." , source : "Table cache_entry {\n key varchar [pk]\n bytes blob\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "tikz-line" , format : "tikz" , title : "Render pipeline (TikZ)" , input_kind : "LaTeX/TikZ figure" , description : "client -> service -> {cache, backend} as positioned TikZ nodes and arrows." , source : "\\begin{document}\n\\begin{tikzpicture}\n \\node[draw, rounded corners] (client) at (0,0) {client};\n \\node[draw, rounded corners] (service) at (3,0) {service};\n \\node[draw, rounded corners] (cache) at (6,0) {cache};\n \\node[draw, rounded corners] (backend) at (9,0) {backend};\n \\draw[->] (client) -- (service);\n \\draw[->] (service) -- (cache);\n \\draw[->] (service) -- (backend);\n\\end{tikzpicture}\n\\end{document}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "svgbob-ascii-pipeline" , format : "svgbob" , title : "ASCII pipeline (svgbob)" , input_kind : "ASCII art diagram" , description : "The same two-box pipeline, rendered by svgbob." , source : "[kr0ki] --> [kroki]\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "wireviz-harness" , format : "wireviz" , title : "Renderer connector harness" , input_kind : "wiring diagram (WireViz)" , description : "Two connectors joined by a cable, in WireViz's YAML wiring-diagram DSL." , source : "connectors:\n X1:\n type: Molex KK 254\n subtype: female\n pinlabels: [GND, VCC]\n X2:\n type: Molex KK 254\n subtype: male\n pinlabels: [GND, VCC]\n\ncables:\n W1:\n colors: [BK, RD]\n\nconnections:\n -\n - X1: [1-2]\n - W1: [1-2]\n - X2: [1-2]\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "structurizr-context" , format : "structurizr" , title : "kr0ki system context" , input_kind : "C4 model (Structurizr DSL)" , description : "Operator, kr0ki (with its RenderService/FsCache containers), and Kroki as a Structurizr workspace with system-context and container views." , source : "workspace {\n model {\n user = person \"Operator\"\n kr0ki = softwareSystem \"kr0ki\" {\n renderer = container \"RenderService\"\n cache = container \"FsCache\"\n }\n kroki = softwareSystem \"Kroki\"\n user -> kr0ki \"Submits diagram source\"\n kr0ki -> kroki \"Renders via\"\n renderer -> cache \"Reads/writes\"\n }\n views {\n systemContext kr0ki {\n include *\n autoLayout\n }\n container kr0ki {\n include *\n autoLayout\n }\n }\n}\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "symbolator-entity" , format : "symbolator" , title : "RenderService entity symbol" , input_kind : "VHDL entity (Symbolator)" , description : "RenderService's inputs and outputs as a VHDL entity black-box symbol." , source : "entity render_service is\n Port ( source : in STD_LOGIC;\n format_select : in STD_LOGIC;\n request_output : in STD_LOGIC;\n artifact : out STD_LOGIC;\n cache_hit : out STD_LOGIC);\nend render_service;\n" , outputs : & ["svg" , "png"] , route : None , } , PlaybookExample { id : "k8s-topology-web-service" , format : "k8s-topology" , title : "Kubernetes topology (native recognizer)" , input_kind : "Kubernetes manifests" , description : "A Deployment, the ConfigMap it consumes, and the Service that selects it — recognized, lifted to SysML v2, and rendered as D2, not proxied through the vendored KubeDiagrams tool (see /render/kubediagram's own example... there isn't one; this is the only k8s example in this catalog, on purpose, to keep the two pipelines from being conflated)." , source : "apiVersion: v1\nkind: ConfigMap\nmetadata:\n name: app-config\n namespace: demo\ndata:\n LOG_LEVEL: info\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n namespace: demo\n labels:\n app: web\nspec:\n replicas: 2\n selector:\n matchLabels:\n app: web\n template:\n metadata:\n labels:\n app: web\n spec:\n containers:\n - name: web\n image: web:latest\n envFrom:\n - configMapRef:\n name: app-config\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: web\n namespace: demo\nspec:\n selector:\n app: web\n ports:\n - port: 80\n" , outputs : & ["svg" , "png"] , route : Some ("/render/k8s-topology") , } ,] ;
The full catalog: at least one example per [`crate::format::DiagramFormat`] entry,
plus type-specific fixtures where several catalog types share a renderer.
pub const USER_AGENT : & str = concat ! ("kr0ki-sysmlv2-client/" , env ! ("CARGO_PKG_VERSION")) ;
`User-Agent` sent on every request.
pub trait RenderBackend { async fn render (& self , format : DiagramFormat , output : OutputKind , source : & str ,) -> Result < Vec < u8 > , RenderError > ; fn describe_endpoint (& self) -> Option < & str > { None } }
A thing that can turn diagram text into rendered bytes.
pub trait SessionIdentity : Send + Sync { fn verify (& self , token : & str) -> Result < SessionClaims , SessionError > ; }
The seam the workspace service uses. `issue` is dev-only; production
sessions arrive from the IdP via a future adapter of this trait.
pub type Service = RenderService < HttpKrokiBackend > ;
pub type DocCache = Arc < RwLock < Vec < kr0ki_core :: docgen :: Symbol > > > ;
Shared in-memory cache of harvested symbols.
pub struct ArgBinding { pub name : & 'static str , pub placement : ArgPlacement , }
pub struct HttpBinding { pub method : HttpMethod , pub path_template : & 'static str , pub args : & 'static [ArgBinding] , }
lifted into a KerML/SysML-v2 [`Relation`], paired"] a renderer should place it in."] pub struct LiftedRelation { pub relation : Relation , pub view_kind : SysmlViewKind , , preserved for traceability"] pub source_edge_id : String , }
One [`OntologicalEdge`] lifted into a KerML/SysML-v2 [`Relation`], paired
with the [`SysmlViewKind`] a renderer should place it in.
pub struct Symbol { pub name : String , pub qualified_name : String , pub file_path : String , pub kind : SymbolKind , pub signature : String , pub return_type : String , pub start_line : Option < u64 > , pub complexity : Option < u64 > , pub docstring : String , }
A harvested code symbol (function, struct, enum, trait, etc.).
Field names align with the schema consumed by `b00t-cli docgen` formatters
so downstream tools can interoperate without translation.
pub struct DiagramType { pub id : & 'static str , pub syntax : & 'static str , pub example_id : & 'static str , pub name : & 'static str , ."] pub use_cases : & 'static [& 'static str] , pub blurb : & 'static str , pub sample_prompt : & 'static str , }
pub struct HttpKrokiBackend { base_url : String , http : reqwest :: Client , }
Direct-HTTP Kroki client.
pub struct RenderService < B > { backend : B , cache : FsCache , }
The render service: a cache in front of a render backend.
pub struct Rendered { pub key : String , pub bytes : Vec < u8 > , pub output : OutputKind , pub status : CacheStatus , }
One completed render.
pub struct PlaybookExample { pub id : & 'static str , kroki slug (e.g. `\"d2\"`) when"] pub format : & 'static str , pub title : & 'static str , pub input_kind : & 'static str , pub description : & 'static str , pub source : & 'static str , `."] pub outputs : & 'static [& 'static str] , pub route : Option < & 'static str > , }
One renderable example: enough to drive a render call and describe it in the UI.
(https://d2lang.com) text from a [`CytoscapeGraph`] — the box-5 render"] pub struct D2Emitter ;
Emits [D2](https://d2lang.com) text from a [`CytoscapeGraph`] — the box-5 render
target for the b00t-graph route (kr0ki#13; D2 chosen over GraphViz, operator
decision). No emitter like this existed before (`holon_viz::emitter` only
targets SysML-v2 / OWL2-Turtle text, a different output format); D2 syntax is
simple enough (`node_id: label` / `node_id -> node_id2: edge_label`) that this
is a small, self-contained function, not a parser.
pub struct ShapeViolation { pub subject : String , pub rule : & 'static str , pub message : String , }
pub struct GraphStore { triples : Mutex < Vec < Triple > > , }
pub struct DiagramFormat (& 'static str) ;
A diagram source language kr0ki can hand to a Kroki backend.
pub struct UnsupportedFormat (pub String) ;
Unknown or companion-only format name.
pub struct SimpleFieldRule { pub kind : String , pub api_group : String , pub field_path : String , pub target_kind : String , pub target_api_version : String , pub relation : UfoRelation , }
A single-field, cluster-scoped-target reference rule: `(kind, api_group)`
at `field_path` names a target object of `target_kind`/`target_api_version`
by a bare `name` (no namespace — every built-in target kind here is
cluster-scoped: `RuntimeClass`, `Node`, `StorageClass`, `IngressClass`,
`GatewayClass`, `CSIDriver`, `PersistentVolume`,
`PriorityLevelConfiguration`). A namespaced-target rule would need this
struct extended; none of today's built-ins need it.
plus any"] pub struct KubernetesRecognizer { rules : Vec < SimpleFieldRule > , }
A Kubernetes-manifest → UFO-graph recognizer: [`builtin_rules`] plus any
caller-supplied extension rules (the CRD extension point).
>/<key>.<ext>` — the"] pub struct FsCache { root : PathBuf , }
Filesystem-backed origin cache. Layout: `<root>/<key[0..2]>/<key>.<ext>` — the
two-char shard keeps directory fan-out sane at volume.
pub struct AppState { pub service : Arc < Service > , pub playbook_dir : PathBuf , pub b00t_graph_artifacts_path : Option < PathBuf > , pub capabilities_path : Option < PathBuf > , pub kubediagram_worker_url : Option < String > , pub sysmlv2_client : Option < Arc < kr0ki_sysmlv2_client :: SysmlV2Client > > , pub model_graph : Arc < kr0ki_core :: graph_store :: GraphStore > , pub storyb00k_agent_url : Option < String > , pub llm_api_url : Option < String > , pub llm_api_key : Option < String > , pub started_at : std :: time :: Instant , pub boot_wall_clock : std :: time :: SystemTime , pub auth_token : Option < String > , }
pub struct Revision { pub id : String , pub workspace_id : String , pub branch_id : String , pub parent_ids : Vec < String > , pub status : RevisionStatus , pub author : Actor , pub intent : String , pub input_kind : InputKind , pub canonical_input : String , pub input_hash : String , pub renderer_recipe : String , pub artifact_hash : Option < String > , pub created_at : String , }
One attempted procedural state (Plan 004 §2 `Revision` record).
`canonical_input` is validated diagram-as-code or a typed model snapshot —
never a rendered artifact. `artifact_hash` is derived, server-computed.
pub struct RevisionOperation { pub revision_id : String , pub sequence : u64 , pub tool_name : String , pub tool_version : String , pub arguments : serde_json :: Value , pub result_digest : String , pub actor : Actor , }
A single ordered, validated tool operation inside a revision
(Plan 004 §2 `RevisionOperation`). This is the replay/audit trace.
pub struct Approval { pub revision_id : String , pub approver : Actor , pub decision : ApprovalDecision , pub reason : String , pub timestamp : String , }
The required human promotion decision (Plan 004 §2 `Approval`).
Only a user action may move a `proposed` revision to branch head.
pub struct Branch { pub id : String , pub workspace_id : String , pub name : String , pub head_revision_id : Option < String > , }
A mutable pointer to the current head revision. Revisions themselves are
immutable; only the branch pointer moves (Plan 004 §2 `Branch`).
pub struct ProjectGrant { pub project_id : String , pub project_root : String , ."] pub allowed_formats : Vec < String > , pub can_read : bool , pub can_write : bool , pub can_materialize : bool , }
Names the development project a session may see. Not a shell grant;
no filesystem/shell/network authority (Plan 004 invariant 6).
pub struct Workspace { pub id : String , pub owner_id : String , pub project_id : String , pub active_branch_id : String , pub grant : ProjectGrant , pub created_at : String , }
Bounded collaboration unit (Plan 004 §2 `Workspace`). Its project grant is
immutable except through an audited admin action.
pub struct WorkspaceSnapshot { pub workspace : WorkspaceView , pub branches : Vec < BranchView > , pub active_revision : Option < RevisionView > , pub revision_graph : RevisionGraph , pub selection : Selection , pub pending_approval : Option < PendingApproval > , }
Redacted browser snapshot projection (Plan 004 §2.2 wire state). This is
what AG-UI STATE_SNAPSHOT carries; project roots, credentials, raw tool
results, and policy fields never appear.
pub struct WorkspaceView { pub id : String , pub project : ProjectView , ."] pub capabilities : Vec < String > , }
pub struct ProjectView { pub id : String , pub name : String , }
pub struct BranchView { pub id : String , pub name : String , pub head_revision_id : Option < String > , }
pub struct RevisionView { pub id : String , pub status : RevisionStatus , pub input_kind : InputKind , pub source : String , pub artifact : Option < ArtifactRef > , }
pub struct ArtifactRef { pub url : String , pub hash : String , }
pub struct RevisionGraph { pub nodes : Vec < RevisionNode > , pub edges : Vec < RevisionEdge > , }
pub struct RevisionNode { pub id : String , pub status : RevisionStatus , pub author_kind : String , }
pub struct RevisionEdge { pub from : String , pub to : String , }
pub struct Selection { pub entity_id : Option < String > , pub revision_id : Option < String > , }
pub struct PendingApproval { pub revision_id : String , pub intent : String , pub proposed_by : Actor , }
pub struct Conflict { pub workspace_id : String , pub expected_revision_id : String , pub actual_head_revision_id : String , }
Stale-head write guard (Plan 004 invariant 4): every mutation carries
`workspace_id` + `expected_revision_id`; a mismatch is this typed conflict.
pub struct HealthReport { pub status : & 'static str , pub service : & 'static str , pub version : & 'static str , pub started_at : String , pub uptime_secs : u64 , pub checks : Checks , }
pub struct Checks { pub kroki_backend : Dependency , pub kubediagram_worker : Option < Dependency > , pub storyb00k_agent : Option < Dependency > , pub llm : LlmCheck , pub stores : StoresCheck , pub caller_auth : bool , }
pub struct Dependency { pub url : String , pub ok : bool , pub latency_ms : Option < u64 > , pub error : Option < String > , }
pub struct LlmCheck { pub configured : bool , pub base_url : Option < String > , pub api_key_set : bool , pub ok : bool , pub model_count : Option < u32 > , pub latency_ms : Option < u64 > , pub error : Option < String > , }
pub struct StoresCheck { pub cache_dir : CacheDirCheck , pub capabilities_file : Option < bool > , pub graph_store_triples : usize , }
pub struct CacheDirCheck { pub path : String , pub writable : bool , pub entries : usize , pub error : Option < String > , }
pub struct SessionClaims { pub subject : String , pub workspace_id : String , pub capabilities : Vec < String > , pub expires_at : u64 , }
What a session is allowed to do inside its one workspace. Derived from the
workspace's `ProjectGrant` at issue time; never supplied by the client.
pub struct DevSession { key : Vec < u8 > , }
HMAC-signed dev session. `KR0KI_DEV_SESSION_KEY` keys it; absent or empty
key = dev sessions disabled server-side (the gate must be on, not open).
pub struct SysmlV2Client { base_url : String , http : reqwest :: Client , token : Option < String > , page_param_style : PageParamStyle , }
Async client for one OMG Systems Modeling API server.
pub struct Ref { pub at_id : String , pub extra : Map < String , Value > , }
An `@id` reference object, e.g. `Commit.owningProject`. The OMG PSM serializes
cross-element references as `{ "@id": "<uuid>", ... }`.
pub struct Project { pub at_id : String , pub name : Option < String > , pub description : Option < String > , pub created : Option < String > , pub extra : Map < String , Value > , }
A project on the model server. `POST {base}/projects/{id}` addresses it.
pub struct Branch { pub at_id : String , pub name : Option < String > , pub description : Option < String > , pub created : Option < String > , pub extra : Map < String , Value > , }
A branch within a project.
pub struct Tag { pub at_id : String , pub name : Option < String > , pub description : Option < String > , pub created : Option < String > , pub extra : Map < String , Value > , }
A tag within a project (a named, immutable pointer at a commit).
pub struct Commit { pub at_id : String , pub description : Option < String > , pub created : Option < String > , pub owning_project : Option < Ref > , pub extra : Map < String , Value > , }
A commit: an immutable snapshot of a project's model. `(projectId, commitId)` is
the stable, forever-cacheable coordinate kr0ki keys on (see `EVAL-flexo.md`).
pub struct Element { pub at_id : String , pub at_type : String , pub fields : Map < String , Value > , }
A single model element. `@id` and `@type` are lifted out; everything else the
element carries stays in `fields`.
pub struct Page { pub after : Option < String > , pub before : Option < String > , pub size : Option < u32 > , }
Page request for `elements(..)`. Maps to the OMG PSM query params
`page-after` / `page-before` / `page-size`.
docs and"] pub struct ElementPage { pub items : Vec < Element > , pub next_after : Option < String > , }
One page of elements plus the cursor to fetch the next page, if any.
`next_after` is derived from a `Link: rel="next"` header when the server sends one,
otherwise from a full-vs-short page heuristic — see [`crate`] docs and
`paging::derive_next_after`.
pub struct ModelSnapshot { pub project_id : String , pub commit_id : String , pub elements : Vec < Element > , pub roots : Vec < String > , pub content_hash : String , }
A content-hashed snapshot of one project's model at one commit — the unit kr0ki's
model-ingestion path (PRD-KR0KI-001 FR1/FR4) consumes.
Flexo and SysON expose **no** server-side content hash or ETag, so `content_hash`
is derived client-side by `compute_content_hash` and becomes kr0ki's model-side
cache key (PRD FR5).
The following D2 diagram is part of kr0ki's template suite and can be rendered via POST /render/d2:
# b00t Stack Orchestration Pattern — Executable Diagram Template
# Render: POST /render/d2 with this file as body → SVG via kr0ki
# https://github.com/PromptExecution/kr0ki
direction: right
# ── Upstream Model Side (not kr0ki's; owned by systhread / ufo-types / ledgrrr) ──
model_side: {
shape: rectangle
style.fill: "#e8f4f8"
label: |md
**MODEL SIDE** (upstream)
Owned by `systhread` / `ufo-types` / `ledgrrr`
|
rust_types: Rust types { shape: circle; style.fill: "#c8e6c9" }
iso_ir: iso_ir Node/Edge { shape: circle; style.fill: "#c8e6c9" }
kerml: KerML snapshot { shape: circle; style.fill: "#c8e6c9" }
ufo_graph: UFO semantic graph { shape: circle; style.fill: "#c8e6c9" }
sysml_views: SysML v2 viewpoints { shape: circle; style.fill: "#c8e6c9" }
rust_types -> iso_ir: derive
iso_ir -> ufo_graph: lift
kerml -> ufo_graph: deserialize
ufo_graph -> sysml_views: expose
}
# ── The Cut-Node: kr0ki (rendering + CDN cache) ──
kr0ki: {
shape: rectangle
style.fill: "#fff3e0"
style.stroke: "#e65100"
style.stroke-width: 2
label: |md
**kr0ki** — cut-node
Render + Cache + Artifact Resolver
|
cache: Content-addressed cache { shape: cylinder; style.fill: "#ffe0b2" }
render_2d: 2D RenderBackend { shape: rectangle; style.fill: "#ffe0b2" }
render_iso: Isometric 3D RenderBackend { shape: rectangle; style.fill: "#ffe0b2" }
resolver: Artifact ref resolver { shape: rectangle; style.fill: "#ffe0b2" }
cache -> render_2d: miss
cache -> render_iso: miss
cache -> resolver: refs
}
# ── 2D / 3D Rendering Library as a Service ──
render_library: {
shape: rectangle
style.fill: "#f3e5f5"
label: |md
**Rendering Library as a Service**
(Kroki-family + systhread-core)
|
kroki_family: {
label: Kroki-family 2D
style.fill: "#e1bee7"
plantuml: PlantUML
graphviz: GraphViz
d2: D2
vegalite: Vega-Lite
c4: C4 PlantUML
}
systhread: {
label: systhread-core isometric
style.fill: "#e1bee7"
layout: Cassowary layout
svg_out: SVG output
}
}
# ── Downstream Consumers (leaves; not kr0ki's core) ──
consumers: {
shape: rectangle
style.fill: "#e8f5e9"
label: |md
**Downstream Consumers**
(leaves — attach to kr0ki surface)
|
docs: Docs site
comic: Comic engine
explorer: 3D explorer
cli: b00t CLI
}
# ── Crossings ──
model_side.sysml_views -> kr0ki.cache: validated model
kr0ki.render_2d -> render_library.kroki_family: POST slash slug slash svg
kr0ki.render_iso -> render_library.systhread.layout: layout JSON
render_library.systhread.svg_out -> kr0ki.cache: artifact
kr0ki.cache -> consumers.docs: SVG
kr0ki.cache -> consumers.comic: SVG
kr0ki.cache -> consumers.explorer: SVG refs
kr0ki.resolver -> consumers.cli: datum URLs
Render it live:
curl -X POST http://localhost:8787/render/d2 \
-H "Content-Type: text/plain" \
--data-binary @templates/b00t-stack-orchestration.d2 \
--output diagram.svg
This playb00k fixture models the implemented Box-5 path: Axum route → RenderService → cache/backend → artifact. It is not a substitute for the deferred upstream ModelSnapshot → UFO → recognizer → ViewDefinition pipeline.
HttpKrokiBackend; misses render and atomically write the artifact.# kr0ki Box-5 Rust code-flow — executable playb00k view source.
direction: right
client: HTTP caller { shape: person }
router: Axum router { shape: hexagon }
service: RenderService { shape: rectangle; style.fill: "#d8eaff" }
cache: FsCache { shape: cylinder; style.fill: "#e9f7df" }
backend: HttpKrokiBackend { shape: rectangle; style.fill: "#fff0cc" }
kroki: Kroki renderer { shape: cloud }
artifact: SVG or PNG { shape: document; style.fill: "#f7e6ff" }
client -> router: POST /render/:format
router -> service: route + auth
service -> cache: lookup
cache -> service: hit or miss
service -> backend: miss only
backend -> kroki: render
kroki -> backend: bytes
backend -> service: artifact
service -> cache: atomic write
service -> client: headers + bytes
client -> artifact: receives
// Playb00k fixture: KerML view of the implemented Box-5 Rust flow.
// It does not replace the upstream UFO/model pipeline.
package kr0ki_playbook {
classifier RenderRoute;
classifier RenderService;
classifier FsCache;
classifier HttpKrokiBackend;
classifier KrokiRenderer;
classifier RenderedArtifact;
dependency routeToService : RenderRoute -> RenderService;
dependency serviceToCache : RenderService -> FsCache;
dependency serviceToBackend : RenderService -> HttpKrokiBackend;
dependency backendToRenderer : HttpKrokiBackend -> KrokiRenderer;
dependency serviceToArtifact : RenderService -> RenderedArtifact;
}
// Playb00k fixture: SysML v2 structural view of kr0ki's implemented render path.
// Production ModelSnapshot -> UFO -> recognizer -> ViewDefinition remains upstream.
package kr0ki_playbook {
part def RenderRoute;
part def FsCache;
part def RenderBackend;
part def HttpKrokiBackend :> RenderBackend;
part def RenderedArtifact;
part def RenderService {
part cache : FsCache;
part backend : RenderBackend;
}
part render_flow {
part route : RenderRoute;
part service : RenderService;
part renderer : HttpKrokiBackend;
part artifact : RenderedArtifact;
}
}
LAN documentation: . Start with just run or just dev; both bind 0.0.0.0:8787 by default.
export KR0KI_URL=http://<LAN-host>:8787
curl "$KR0KI_URL/health"
curl "$KR0KI_URL/formats"
curl -X POST "$KR0KI_URL/render/graphviz?output=svg" --data-binary 'digraph {{ kr0ki -> cache }}' --output flow.svg
curl "$KR0KI_URL/docs/api.tomllm"
just test # unit + in-process HTTP
just check # formatting + clippy
just test-live # opt-in live render