Skip to content

Visualization

What It Is

Visualization turns the canonical DAG document into the surfaces people use to reason about a workflow: Mermaid for docs, JSON-LD for semantic graph tooling, and Cytoscape element data for interactive runtime views.

The input is always the same DAG object the dispatcher registers. Rendering never invents a second graph model.

How It Works

Each renderer consumes the same DAG document. MermaidRenderer emits flowchart source, JsonLdRenderer emits semantic JSON-LD, and CytoscapeRenderer emits element data for hosts that manage their own graph component and styling.

Three renderers ship in @studnicky/dagonizer/viz. Each consumes a DAG and emits a different surface: MermaidRenderer.render produces flowchart source for embedding in Markdown; JsonLdRenderer.render produces a JSON-LD document for graph databases and semantic tooling; CytoscapeRenderer.render produces a plain readonly CytoscapeElementType[] array for applications that manage their own cytoscape instance.

Diagrams, Examples, and Outputs

Guide and example pages show JSON-LD beside Mermaid so readers can correlate the document with the graph shape. Runnable demo pages use Cytoscape because they need interactive execution state.

The Archivist parent DAG

55 placements
DAG JSON-LD registered with the dispatcher
{
  "@context": {
    "@version": 1.1,
    "name": {
      "@id": "https://noocodec.dev/ontology/dag/name"
    },
    "version": {
      "@id": "https://noocodec.dev/ontology/dag/version"
    },
    "entrypoints": {
      "@id": "https://noocodec.dev/ontology/dag/entrypoints",
      "@container": "@index"
    },
    "nodes": {
      "@id": "https://noocodec.dev/ontology/dag/nodes",
      "@container": "@set"
    },
    "outputs": {
      "@id": "https://noocodec.dev/ontology/dag/outputs"
    },
    "node": {
      "@id": "https://noocodec.dev/ontology/dag/node"
    },
    "dag": {
      "@id": "https://noocodec.dev/ontology/dag/dag"
    },
    "body": {
      "@id": "https://noocodec.dev/ontology/dag/body"
    },
    "source": {
      "@id": "https://noocodec.dev/ontology/dag/source"
    },
    "sources": {
      "@id": "https://noocodec.dev/ontology/dag/sources",
      "@container": "@index"
    },
    "itemKey": {
      "@id": "https://noocodec.dev/ontology/dag/itemKey"
    },
    "execution": {
      "@id": "https://noocodec.dev/ontology/dag/execution"
    },
    "concurrency": {
      "@id": "https://noocodec.dev/ontology/dag/concurrency"
    },
    "throttle": {
      "@id": "https://noocodec.dev/ontology/dag/throttle"
    },
    "reservoir": {
      "@id": "https://noocodec.dev/ontology/dag/reservoir"
    },
    "gather": {
      "@id": "https://noocodec.dev/ontology/dag/gather"
    },
    "dagReference": {
      "@id": "https://noocodec.dev/ontology/dag/dagReference",
      "@type": "@id"
    },
    "DagReference": {
      "@id": "https://noocodec.dev/ontology/dag/DagReference"
    },
    "from": {
      "@id": "https://noocodec.dev/ontology/dag/from"
    },
    "path": {
      "@id": "https://noocodec.dev/ontology/dag/path"
    },
    "candidates": {
      "@id": "https://noocodec.dev/ontology/dag/candidates",
      "@container": "@set"
    },
    "candidateDag": {
      "@id": "https://noocodec.dev/ontology/dag/candidateDag",
      "@type": "@id"
    },
    "selectedDag": {
      "@id": "https://noocodec.dev/ontology/dag/selectedDag",
      "@type": "@id"
    },
    "resultField": {
      "@id": "https://noocodec.dev/ontology/dag/resultField"
    },
    "policy": {
      "@id": "https://noocodec.dev/ontology/dag/policy"
    },
    "reducer": {
      "@id": "https://noocodec.dev/ontology/dag/reducer"
    },
    "outcome": {
      "@id": "https://noocodec.dev/ontology/dag/outcome"
    },
    "phase": {
      "@id": "https://noocodec.dev/ontology/dag/phase"
    },
    "stateMapping": {
      "@id": "https://noocodec.dev/ontology/dag/stateMapping"
    },
    "container": {
      "@id": "https://noocodec.dev/ontology/dag/container"
    },
    "DAG": {
      "@id": "https://noocodec.dev/ontology/dag/DAG"
    },
    "Placement": {
      "@id": "https://noocodec.dev/ontology/dag/Placement"
    },
    "SingleNode": {
      "@id": "https://noocodec.dev/ontology/dag/SingleNode"
    },
    "ScatterNode": {
      "@id": "https://noocodec.dev/ontology/dag/ScatterNode"
    },
    "EmbeddedDAGNode": {
      "@id": "https://noocodec.dev/ontology/dag/EmbeddedDAGNode"
    },
    "GatherNode": {
      "@id": "https://noocodec.dev/ontology/dag/GatherNode"
    },
    "TerminalNode": {
      "@id": "https://noocodec.dev/ontology/dag/TerminalNode"
    },
    "PhaseNode": {
      "@id": "https://noocodec.dev/ontology/dag/PhaseNode"
    }
  },
  "@id": "urn:noocodec:dag:the-archivist",
  "@type": "DAG",
  "name": "the-archivist",
  "version": "6.0",
  "entrypoints": {
    "main": "urn:noocodec:dag:the-archivist/node/park-for-input"
  },
  "nodes": [
    {
      "@id": "urn:noocodec:dag:the-archivist/node/setup",
      "@type": "PhaseNode",
      "name": "setup",
      "node": "urn:noocodec:node:pre-run-setup",
      "phase": "pre"
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/park-for-input",
      "@type": "SingleNode",
      "name": "park-for-input",
      "node": "urn:noocodec:node:park-for-input",
      "outputs": {
        "parked": "urn:noocodec:dag:the-archivist/node/park-for-input",
        "resumed": "urn:noocodec:dag:the-archivist/node/recall-context"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recall-context",
      "@type": "SingleNode",
      "name": "recall-context",
      "node": "urn:noocodec:node:recall-context",
      "outputs": {
        "recalled": "urn:noocodec:dag:the-archivist/node/classify-intent"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/classify-intent",
      "@type": "SingleNode",
      "name": "classify-intent",
      "node": "urn:noocodec:node:classify-intent",
      "outputs": {
        "lookup-author": "urn:noocodec:dag:the-archivist/node/author-search",
        "find-reviews": "urn:noocodec:dag:the-archivist/node/reviews-extract",
        "describe-book": "urn:noocodec:dag:the-archivist/node/describe-extract",
        "recommend-similar": "urn:noocodec:dag:the-archivist/node/recommend-similar",
        "recall-memories": "urn:noocodec:dag:the-archivist/node/memory-recall",
        "on-topic": "urn:noocodec:dag:the-archivist/node/on-topic-search",
        "recommend-top-rated": "urn:noocodec:dag:the-archivist/node/recommend-extract",
        "off-topic": "urn:noocodec:dag:the-archivist/node/decline-off-topic",
        "retry": "urn:noocodec:dag:the-archivist/node/classify-intent",
        "salvage": "urn:noocodec:dag:the-archivist/node/classify-intent-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/classify-intent-salvage",
      "@type": "SingleNode",
      "name": "classify-intent-salvage",
      "node": "urn:noocodec:node:classify-intent-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/on-topic-search"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/on-topic-search",
      "@type": "EmbeddedDAGNode",
      "name": "on-topic-search",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/compose-loop",
        "error": "urn:noocodec:dag:the-archivist/node/compose-empty"
      },
      "dag": "urn:noocodec:dag:book-search-scatter",
      "stateMapping": {
        "output": {
          "terms": "terms",
          "toolPlan": "toolPlan",
          "candidates": "candidates",
          "shortlist": "shortlist",
          "priorContext": "priorContext",
          "failureCause": "failureCause"
        }
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/author-search",
      "@type": "EmbeddedDAGNode",
      "name": "author-search",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/group-by-year",
        "error": "urn:noocodec:dag:the-archivist/node/compose-empty"
      },
      "dag": "urn:noocodec:dag:book-search-scatter",
      "stateMapping": {
        "output": {
          "terms": "terms",
          "toolPlan": "toolPlan",
          "candidates": "candidates",
          "shortlist": "shortlist",
          "priorContext": "priorContext",
          "failureCause": "failureCause"
        }
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/group-by-year",
      "@type": "SingleNode",
      "name": "group-by-year",
      "node": "urn:noocodec:node:group-by-year",
      "outputs": {
        "ordered": "urn:noocodec:dag:the-archivist/node/compose-loop"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-extract",
      "@type": "SingleNode",
      "name": "reviews-extract",
      "node": "urn:noocodec:node:extract-query",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools",
        "retry": "urn:noocodec:dag:the-archivist/node/reviews-extract",
        "salvage": "urn:noocodec:dag:the-archivist/node/reviews-extract-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-extract-salvage",
      "@type": "SingleNode",
      "name": "reviews-extract-salvage",
      "node": "urn:noocodec:node:extract-query-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools",
      "@type": "SingleNode",
      "name": "reviews-decide-tools",
      "node": "urn:noocodec:node:decide-tools",
      "outputs": {
        "tools": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets",
        "no-tools": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets",
        "retry": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools",
        "salvage": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools-salvage",
      "@type": "SingleNode",
      "name": "reviews-decide-tools-salvage",
      "node": "urn:noocodec:node:decide-tools-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets",
      "@type": "SingleNode",
      "name": "reviews-build-worksets",
      "node": "urn:noocodec:node:build-book-worksets",
      "outputs": {
        "ready": "urn:noocodec:dag:the-archivist/node/reviews-scatter"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-scatter",
      "@type": "ScatterNode",
      "name": "reviews-scatter",
      "source": "bookWorksets",
      "body": {
        "dag": {
          "@type": "DagReference",
          "from": "item",
          "path": "dagIri",
          "candidates": [
            "urn:noocodec:tool:web_search_books",
            "urn:noocodec:tool:google_books_search",
            "urn:noocodec:tool:subject_search",
            "urn:noocodec:tool:wikipedia_summary"
          ]
        }
      },
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/reviews-gather",
        "error": "urn:noocodec:dag:the-archivist/node/reviews-gather",
        "empty": "urn:noocodec:dag:the-archivist/node/reviews-rank"
      },
      "itemKey": "currentItem",
      "reducer": "any-success",
      "execution": {
        "mode": "item",
        "concurrency": 4
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-gather",
      "@type": "GatherNode",
      "name": "reviews-gather",
      "sources": {
        "urn:noocodec:dag:the-archivist/node/reviews-scatter": {}
      },
      "gather": {
        "strategy": "tool-candidate-merge"
      },
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/reviews-rank",
        "error": "urn:noocodec:dag:the-archivist/node/reviews-rank",
        "empty": "urn:noocodec:dag:the-archivist/node/reviews-rank"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-rank",
      "@type": "SingleNode",
      "name": "reviews-rank",
      "node": "urn:noocodec:node:rank-by-rating",
      "outputs": {
        "ranked": "urn:noocodec:dag:the-archivist/node/reviews-merge"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-merge",
      "@type": "SingleNode",
      "name": "reviews-merge",
      "node": "urn:noocodec:node:merge-candidates",
      "outputs": {
        "ranked": "urn:noocodec:dag:the-archivist/node/reviews-record",
        "empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-record",
      "@type": "SingleNode",
      "name": "reviews-record",
      "node": "urn:noocodec:node:record-findings",
      "outputs": {
        "recorded": "urn:noocodec:dag:the-archivist/node/reviews-gate"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-gate",
      "@type": "SingleNode",
      "name": "reviews-gate",
      "node": "urn:noocodec:node:has-citations-gate",
      "outputs": {
        "pass": "urn:noocodec:dag:the-archivist/node/reviews-recall",
        "fail": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/reviews-recall",
      "@type": "SingleNode",
      "name": "reviews-recall",
      "node": "urn:noocodec:node:recall-past-visits",
      "outputs": {
        "recalled": "urn:noocodec:dag:the-archivist/node/compose-loop"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-extract",
      "@type": "SingleNode",
      "name": "recommend-extract",
      "node": "urn:noocodec:node:extract-query",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools",
        "retry": "urn:noocodec:dag:the-archivist/node/recommend-extract",
        "salvage": "urn:noocodec:dag:the-archivist/node/recommend-extract-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-extract-salvage",
      "@type": "SingleNode",
      "name": "recommend-extract-salvage",
      "node": "urn:noocodec:node:extract-query-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools",
      "@type": "SingleNode",
      "name": "recommend-decide-tools",
      "node": "urn:noocodec:node:decide-tools",
      "outputs": {
        "tools": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets",
        "no-tools": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets",
        "retry": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools",
        "salvage": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools-salvage",
      "@type": "SingleNode",
      "name": "recommend-decide-tools-salvage",
      "node": "urn:noocodec:node:decide-tools-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets",
      "@type": "SingleNode",
      "name": "recommend-build-worksets",
      "node": "urn:noocodec:node:build-book-worksets",
      "outputs": {
        "ready": "urn:noocodec:dag:the-archivist/node/recommend-scatter"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-scatter",
      "@type": "ScatterNode",
      "name": "recommend-scatter",
      "source": "bookWorksets",
      "body": {
        "dag": {
          "@type": "DagReference",
          "from": "item",
          "path": "dagIri",
          "candidates": [
            "urn:noocodec:tool:web_search_books",
            "urn:noocodec:tool:google_books_search",
            "urn:noocodec:tool:subject_search",
            "urn:noocodec:tool:wikipedia_summary"
          ]
        }
      },
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/recommend-gather",
        "error": "urn:noocodec:dag:the-archivist/node/recommend-gather",
        "empty": "urn:noocodec:dag:the-archivist/node/recommend-rank"
      },
      "itemKey": "currentItem",
      "reducer": "any-success",
      "execution": {
        "mode": "item",
        "concurrency": 4
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-gather",
      "@type": "GatherNode",
      "name": "recommend-gather",
      "sources": {
        "urn:noocodec:dag:the-archivist/node/recommend-scatter": {}
      },
      "gather": {
        "strategy": "tool-candidate-merge"
      },
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/recommend-rank",
        "error": "urn:noocodec:dag:the-archivist/node/recommend-rank",
        "empty": "urn:noocodec:dag:the-archivist/node/recommend-rank"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-rank",
      "@type": "SingleNode",
      "name": "recommend-rank",
      "node": "urn:noocodec:node:rank-by-rating",
      "outputs": {
        "ranked": "urn:noocodec:dag:the-archivist/node/recommend-merge"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-merge",
      "@type": "SingleNode",
      "name": "recommend-merge",
      "node": "urn:noocodec:node:merge-candidates",
      "outputs": {
        "ranked": "urn:noocodec:dag:the-archivist/node/recommend-record",
        "empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-record",
      "@type": "SingleNode",
      "name": "recommend-record",
      "node": "urn:noocodec:node:record-findings",
      "outputs": {
        "recorded": "urn:noocodec:dag:the-archivist/node/recommend-gate"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-gate",
      "@type": "SingleNode",
      "name": "recommend-gate",
      "node": "urn:noocodec:node:has-citations-gate",
      "outputs": {
        "pass": "urn:noocodec:dag:the-archivist/node/recommend-recall",
        "fail": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-recall",
      "@type": "SingleNode",
      "name": "recommend-recall",
      "node": "urn:noocodec:node:recall-past-visits",
      "outputs": {
        "recalled": "urn:noocodec:dag:the-archivist/node/compose-loop"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-extract",
      "@type": "SingleNode",
      "name": "describe-extract",
      "node": "urn:noocodec:node:extract-query",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/describe-decide-tools",
        "retry": "urn:noocodec:dag:the-archivist/node/describe-extract",
        "salvage": "urn:noocodec:dag:the-archivist/node/describe-extract-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-extract-salvage",
      "@type": "SingleNode",
      "name": "describe-extract-salvage",
      "node": "urn:noocodec:node:extract-query-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/describe-decide-tools"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-decide-tools",
      "@type": "SingleNode",
      "name": "describe-decide-tools",
      "node": "urn:noocodec:node:decide-tools",
      "outputs": {
        "tools": "urn:noocodec:dag:the-archivist/node/describe-build-worksets",
        "no-tools": "urn:noocodec:dag:the-archivist/node/describe-build-worksets",
        "retry": "urn:noocodec:dag:the-archivist/node/describe-decide-tools",
        "salvage": "urn:noocodec:dag:the-archivist/node/describe-decide-tools-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-decide-tools-salvage",
      "@type": "SingleNode",
      "name": "describe-decide-tools-salvage",
      "node": "urn:noocodec:node:decide-tools-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/describe-build-worksets"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-build-worksets",
      "@type": "SingleNode",
      "name": "describe-build-worksets",
      "node": "urn:noocodec:node:build-book-worksets",
      "outputs": {
        "ready": "urn:noocodec:dag:the-archivist/node/describe-scatter"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-scatter",
      "@type": "ScatterNode",
      "name": "describe-scatter",
      "source": "bookWorksets",
      "body": {
        "dag": {
          "@type": "DagReference",
          "from": "item",
          "path": "dagIri",
          "candidates": [
            "urn:noocodec:tool:web_search_books",
            "urn:noocodec:tool:google_books_search",
            "urn:noocodec:tool:subject_search",
            "urn:noocodec:tool:wikipedia_summary"
          ]
        }
      },
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/describe-gather",
        "error": "urn:noocodec:dag:the-archivist/node/compose-empty",
        "empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
      },
      "itemKey": "currentItem",
      "reducer": "any-success",
      "execution": {
        "mode": "item",
        "concurrency": 4
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-gather",
      "@type": "GatherNode",
      "name": "describe-gather",
      "sources": {
        "urn:noocodec:dag:the-archivist/node/describe-scatter": {}
      },
      "gather": {
        "strategy": "tool-candidate-merge"
      },
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/describe-pick",
        "error": "urn:noocodec:dag:the-archivist/node/compose-empty",
        "empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-pick",
      "@type": "SingleNode",
      "name": "describe-pick",
      "node": "urn:noocodec:node:pick-best-match",
      "outputs": {
        "picked": "urn:noocodec:dag:the-archivist/node/describe-merge"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-merge",
      "@type": "SingleNode",
      "name": "describe-merge",
      "node": "urn:noocodec:node:merge-candidates",
      "outputs": {
        "ranked": "urn:noocodec:dag:the-archivist/node/describe-record",
        "empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-record",
      "@type": "SingleNode",
      "name": "describe-record",
      "node": "urn:noocodec:node:record-findings",
      "outputs": {
        "recorded": "urn:noocodec:dag:the-archivist/node/describe-gate"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-gate",
      "@type": "SingleNode",
      "name": "describe-gate",
      "node": "urn:noocodec:node:has-citations-gate",
      "outputs": {
        "pass": "urn:noocodec:dag:the-archivist/node/describe-recall",
        "fail": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/describe-recall",
      "@type": "SingleNode",
      "name": "describe-recall",
      "node": "urn:noocodec:node:recall-past-visits",
      "outputs": {
        "recalled": "urn:noocodec:dag:the-archivist/node/compose-loop"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/recommend-similar",
      "@type": "SingleNode",
      "name": "recommend-similar",
      "node": "urn:noocodec:node:recommend-similar",
      "outputs": {
        "seeded": "urn:noocodec:dag:the-archivist/node/similar-search",
        "empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/similar-search",
      "@type": "EmbeddedDAGNode",
      "name": "similar-search",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/compose-loop",
        "error": "urn:noocodec:dag:the-archivist/node/compose-empty"
      },
      "dag": "urn:noocodec:dag:book-search-scatter",
      "stateMapping": {
        "output": {
          "terms": "terms",
          "toolPlan": "toolPlan",
          "candidates": "candidates",
          "shortlist": "shortlist",
          "priorContext": "priorContext",
          "failureCause": "failureCause"
        }
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/compose-loop",
      "@type": "EmbeddedDAGNode",
      "name": "compose-loop",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
        "error": "urn:noocodec:dag:the-archivist/node/compose-empty"
      },
      "dag": "urn:noocodec:dag:compose-retry-loop",
      "stateMapping": {
        "output": {
          "draft": "draft",
          "approvalState": "approvalState"
        }
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
      "@type": "SingleNode",
      "name": "respond-to-visitor",
      "node": "urn:noocodec:node:respond-to-visitor",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/end"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/memory-recall",
      "@type": "SingleNode",
      "name": "memory-recall",
      "node": "urn:noocodec:node:recall-memories",
      "outputs": {
        "recalled": "urn:noocodec:dag:the-archivist/node/compose-memory-recall"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/compose-memory-recall",
      "@type": "SingleNode",
      "name": "compose-memory-recall",
      "node": "urn:noocodec:node:compose-memory-response",
      "outputs": {
        "drafted": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
        "retry": "urn:noocodec:dag:the-archivist/node/compose-memory-recall",
        "salvage": "urn:noocodec:dag:the-archivist/node/compose-memory-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/compose-memory-salvage",
      "@type": "SingleNode",
      "name": "compose-memory-salvage",
      "node": "urn:noocodec:node:compose-memory-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/respond-to-visitor"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/decline-off-topic",
      "@type": "SingleNode",
      "name": "decline-off-topic",
      "node": "urn:noocodec:node:decline-off-topic",
      "outputs": {
        "success": "urn:noocodec:dag:the-archivist/node/end"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/compose-empty",
      "@type": "SingleNode",
      "name": "compose-empty",
      "node": "urn:noocodec:node:compose-empty",
      "outputs": {
        "drafted": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
        "retry": "urn:noocodec:dag:the-archivist/node/compose-empty",
        "salvage": "urn:noocodec:dag:the-archivist/node/compose-empty-salvage"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/compose-empty-salvage",
      "@type": "SingleNode",
      "name": "compose-empty-salvage",
      "node": "urn:noocodec:node:compose-empty-salvage",
      "outputs": {
        "done": "urn:noocodec:dag:the-archivist/node/respond-to-visitor"
      }
    },
    {
      "@id": "urn:noocodec:dag:the-archivist/node/end",
      "@type": "TerminalNode",
      "name": "end",
      "outcome": "completed"
    }
  ]
}
Mermaid generated from the same DAG
Mermaid source
%%{init: {"flowchart":{"nodeSpacing":92,"rankSpacing":104,"padding":28}}}%%
flowchart TB
  %% the-archivist (v6.0)
  entry_main(["main"])
  entry_main --> urn_noocodec_dag_the-archivist/node/park-for-input
  urn_noocodec_dag_the-archivist/node/setup(["setup (pre)"])
  urn_noocodec_dag_the-archivist/node/park-for-input["park-for-input"]
  urn_noocodec_dag_the-archivist/node/park-for-input -->|parked| urn_noocodec_dag_the-archivist/node/park-for-input
  urn_noocodec_dag_the-archivist/node/park-for-input -->|resumed| urn_noocodec_dag_the-archivist/node/recall-context
  urn_noocodec_dag_the-archivist/node/recall-context["recall-context"]
  urn_noocodec_dag_the-archivist/node/recall-context -->|recalled| urn_noocodec_dag_the-archivist/node/classify-intent
  urn_noocodec_dag_the-archivist/node/classify-intent["classify-intent"]
  urn_noocodec_dag_the-archivist/node/classify-intent -->|lookup-author| urn_noocodec_dag_the-archivist/node/author-search
  urn_noocodec_dag_the-archivist/node/classify-intent -->|find-reviews| urn_noocodec_dag_the-archivist/node/reviews-extract
  urn_noocodec_dag_the-archivist/node/classify-intent -->|describe-book| urn_noocodec_dag_the-archivist/node/describe-extract
  urn_noocodec_dag_the-archivist/node/classify-intent -->|recommend-similar| urn_noocodec_dag_the-archivist/node/recommend-similar
  urn_noocodec_dag_the-archivist/node/classify-intent -->|recall-memories| urn_noocodec_dag_the-archivist/node/memory-recall
  urn_noocodec_dag_the-archivist/node/classify-intent -->|on-topic| urn_noocodec_dag_the-archivist/node/on-topic-search
  urn_noocodec_dag_the-archivist/node/classify-intent -->|recommend-top-rated| urn_noocodec_dag_the-archivist/node/recommend-extract
  urn_noocodec_dag_the-archivist/node/classify-intent -->|off-topic| urn_noocodec_dag_the-archivist/node/decline-off-topic
  urn_noocodec_dag_the-archivist/node/classify-intent -->|retry| urn_noocodec_dag_the-archivist/node/classify-intent
  urn_noocodec_dag_the-archivist/node/classify-intent -->|salvage| urn_noocodec_dag_the-archivist/node/classify-intent-salvage
  urn_noocodec_dag_the-archivist/node/classify-intent-salvage["classify-intent-salvage"]
  urn_noocodec_dag_the-archivist/node/classify-intent-salvage -->|done| urn_noocodec_dag_the-archivist/node/on-topic-search
  urn_noocodec_dag_the-archivist/node/on-topic-search[["on-topic-search"]]
  urn_noocodec_dag_the-archivist/node/on-topic-search -->|success| urn_noocodec_dag_the-archivist/node/compose-loop
  urn_noocodec_dag_the-archivist/node/on-topic-search -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/author-search[["author-search"]]
  urn_noocodec_dag_the-archivist/node/author-search -->|success| urn_noocodec_dag_the-archivist/node/group-by-year
  urn_noocodec_dag_the-archivist/node/author-search -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/group-by-year["group-by-year"]
  urn_noocodec_dag_the-archivist/node/group-by-year -->|ordered| urn_noocodec_dag_the-archivist/node/compose-loop
  urn_noocodec_dag_the-archivist/node/reviews-extract["reviews-extract"]
  urn_noocodec_dag_the-archivist/node/reviews-extract -->|success| urn_noocodec_dag_the-archivist/node/reviews-decide-tools
  urn_noocodec_dag_the-archivist/node/reviews-extract -->|retry| urn_noocodec_dag_the-archivist/node/reviews-extract
  urn_noocodec_dag_the-archivist/node/reviews-extract -->|salvage| urn_noocodec_dag_the-archivist/node/reviews-extract-salvage
  urn_noocodec_dag_the-archivist/node/reviews-extract-salvage["reviews-extract-salvage"]
  urn_noocodec_dag_the-archivist/node/reviews-extract-salvage -->|done| urn_noocodec_dag_the-archivist/node/reviews-decide-tools
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools["reviews-decide-tools"]
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|tools| urn_noocodec_dag_the-archivist/node/reviews-build-worksets
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|no-tools| urn_noocodec_dag_the-archivist/node/reviews-build-worksets
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|retry| urn_noocodec_dag_the-archivist/node/reviews-decide-tools
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|salvage| urn_noocodec_dag_the-archivist/node/reviews-decide-tools-salvage
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools-salvage["reviews-decide-tools-salvage"]
  urn_noocodec_dag_the-archivist/node/reviews-decide-tools-salvage -->|done| urn_noocodec_dag_the-archivist/node/reviews-build-worksets
  urn_noocodec_dag_the-archivist/node/reviews-build-worksets["reviews-build-worksets"]
  urn_noocodec_dag_the-archivist/node/reviews-build-worksets -->|ready| urn_noocodec_dag_the-archivist/node/reviews-scatter
  urn_noocodec_dag_the-archivist/node/reviews-scatter[/"reviews-scatter"/]
  urn_noocodec_dag_the-archivist/node/reviews-scatter -->|success| urn_noocodec_dag_the-archivist/node/reviews-gather
  urn_noocodec_dag_the-archivist/node/reviews-scatter -->|error| urn_noocodec_dag_the-archivist/node/reviews-gather
  urn_noocodec_dag_the-archivist/node/reviews-scatter -->|empty| urn_noocodec_dag_the-archivist/node/reviews-rank
  urn_noocodec_dag_the-archivist/node/reviews-gather{"reviews-gather"}
  urn_noocodec_dag_the-archivist/node/reviews-gather -->|success| urn_noocodec_dag_the-archivist/node/reviews-rank
  urn_noocodec_dag_the-archivist/node/reviews-gather -->|error| urn_noocodec_dag_the-archivist/node/reviews-rank
  urn_noocodec_dag_the-archivist/node/reviews-gather -->|empty| urn_noocodec_dag_the-archivist/node/reviews-rank
  urn_noocodec_dag_the-archivist/node/reviews-rank["reviews-rank"]
  urn_noocodec_dag_the-archivist/node/reviews-rank -->|ranked| urn_noocodec_dag_the-archivist/node/reviews-merge
  urn_noocodec_dag_the-archivist/node/reviews-merge["reviews-merge"]
  urn_noocodec_dag_the-archivist/node/reviews-merge -->|ranked| urn_noocodec_dag_the-archivist/node/reviews-record
  urn_noocodec_dag_the-archivist/node/reviews-merge -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/reviews-record["reviews-record"]
  urn_noocodec_dag_the-archivist/node/reviews-record -->|recorded| urn_noocodec_dag_the-archivist/node/reviews-gate
  urn_noocodec_dag_the-archivist/node/reviews-gate["reviews-gate"]
  urn_noocodec_dag_the-archivist/node/reviews-gate -->|pass| urn_noocodec_dag_the-archivist/node/reviews-recall
  urn_noocodec_dag_the-archivist/node/reviews-gate -->|fail| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/reviews-recall["reviews-recall"]
  urn_noocodec_dag_the-archivist/node/reviews-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-loop
  urn_noocodec_dag_the-archivist/node/recommend-extract["recommend-extract"]
  urn_noocodec_dag_the-archivist/node/recommend-extract -->|success| urn_noocodec_dag_the-archivist/node/recommend-decide-tools
  urn_noocodec_dag_the-archivist/node/recommend-extract -->|retry| urn_noocodec_dag_the-archivist/node/recommend-extract
  urn_noocodec_dag_the-archivist/node/recommend-extract -->|salvage| urn_noocodec_dag_the-archivist/node/recommend-extract-salvage
  urn_noocodec_dag_the-archivist/node/recommend-extract-salvage["recommend-extract-salvage"]
  urn_noocodec_dag_the-archivist/node/recommend-extract-salvage -->|done| urn_noocodec_dag_the-archivist/node/recommend-decide-tools
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools["recommend-decide-tools"]
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|tools| urn_noocodec_dag_the-archivist/node/recommend-build-worksets
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|no-tools| urn_noocodec_dag_the-archivist/node/recommend-build-worksets
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|retry| urn_noocodec_dag_the-archivist/node/recommend-decide-tools
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|salvage| urn_noocodec_dag_the-archivist/node/recommend-decide-tools-salvage
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools-salvage["recommend-decide-tools-salvage"]
  urn_noocodec_dag_the-archivist/node/recommend-decide-tools-salvage -->|done| urn_noocodec_dag_the-archivist/node/recommend-build-worksets
  urn_noocodec_dag_the-archivist/node/recommend-build-worksets["recommend-build-worksets"]
  urn_noocodec_dag_the-archivist/node/recommend-build-worksets -->|ready| urn_noocodec_dag_the-archivist/node/recommend-scatter
  urn_noocodec_dag_the-archivist/node/recommend-scatter[/"recommend-scatter"/]
  urn_noocodec_dag_the-archivist/node/recommend-scatter -->|success| urn_noocodec_dag_the-archivist/node/recommend-gather
  urn_noocodec_dag_the-archivist/node/recommend-scatter -->|error| urn_noocodec_dag_the-archivist/node/recommend-gather
  urn_noocodec_dag_the-archivist/node/recommend-scatter -->|empty| urn_noocodec_dag_the-archivist/node/recommend-rank
  urn_noocodec_dag_the-archivist/node/recommend-gather{"recommend-gather"}
  urn_noocodec_dag_the-archivist/node/recommend-gather -->|success| urn_noocodec_dag_the-archivist/node/recommend-rank
  urn_noocodec_dag_the-archivist/node/recommend-gather -->|error| urn_noocodec_dag_the-archivist/node/recommend-rank
  urn_noocodec_dag_the-archivist/node/recommend-gather -->|empty| urn_noocodec_dag_the-archivist/node/recommend-rank
  urn_noocodec_dag_the-archivist/node/recommend-rank["recommend-rank"]
  urn_noocodec_dag_the-archivist/node/recommend-rank -->|ranked| urn_noocodec_dag_the-archivist/node/recommend-merge
  urn_noocodec_dag_the-archivist/node/recommend-merge["recommend-merge"]
  urn_noocodec_dag_the-archivist/node/recommend-merge -->|ranked| urn_noocodec_dag_the-archivist/node/recommend-record
  urn_noocodec_dag_the-archivist/node/recommend-merge -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/recommend-record["recommend-record"]
  urn_noocodec_dag_the-archivist/node/recommend-record -->|recorded| urn_noocodec_dag_the-archivist/node/recommend-gate
  urn_noocodec_dag_the-archivist/node/recommend-gate["recommend-gate"]
  urn_noocodec_dag_the-archivist/node/recommend-gate -->|pass| urn_noocodec_dag_the-archivist/node/recommend-recall
  urn_noocodec_dag_the-archivist/node/recommend-gate -->|fail| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/recommend-recall["recommend-recall"]
  urn_noocodec_dag_the-archivist/node/recommend-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-loop
  urn_noocodec_dag_the-archivist/node/describe-extract["describe-extract"]
  urn_noocodec_dag_the-archivist/node/describe-extract -->|success| urn_noocodec_dag_the-archivist/node/describe-decide-tools
  urn_noocodec_dag_the-archivist/node/describe-extract -->|retry| urn_noocodec_dag_the-archivist/node/describe-extract
  urn_noocodec_dag_the-archivist/node/describe-extract -->|salvage| urn_noocodec_dag_the-archivist/node/describe-extract-salvage
  urn_noocodec_dag_the-archivist/node/describe-extract-salvage["describe-extract-salvage"]
  urn_noocodec_dag_the-archivist/node/describe-extract-salvage -->|done| urn_noocodec_dag_the-archivist/node/describe-decide-tools
  urn_noocodec_dag_the-archivist/node/describe-decide-tools["describe-decide-tools"]
  urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|tools| urn_noocodec_dag_the-archivist/node/describe-build-worksets
  urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|no-tools| urn_noocodec_dag_the-archivist/node/describe-build-worksets
  urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|retry| urn_noocodec_dag_the-archivist/node/describe-decide-tools
  urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|salvage| urn_noocodec_dag_the-archivist/node/describe-decide-tools-salvage
  urn_noocodec_dag_the-archivist/node/describe-decide-tools-salvage["describe-decide-tools-salvage"]
  urn_noocodec_dag_the-archivist/node/describe-decide-tools-salvage -->|done| urn_noocodec_dag_the-archivist/node/describe-build-worksets
  urn_noocodec_dag_the-archivist/node/describe-build-worksets["describe-build-worksets"]
  urn_noocodec_dag_the-archivist/node/describe-build-worksets -->|ready| urn_noocodec_dag_the-archivist/node/describe-scatter
  urn_noocodec_dag_the-archivist/node/describe-scatter[/"describe-scatter"/]
  urn_noocodec_dag_the-archivist/node/describe-scatter -->|success| urn_noocodec_dag_the-archivist/node/describe-gather
  urn_noocodec_dag_the-archivist/node/describe-scatter -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/describe-scatter -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/describe-gather{"describe-gather"}
  urn_noocodec_dag_the-archivist/node/describe-gather -->|success| urn_noocodec_dag_the-archivist/node/describe-pick
  urn_noocodec_dag_the-archivist/node/describe-gather -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/describe-gather -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/describe-pick["describe-pick"]
  urn_noocodec_dag_the-archivist/node/describe-pick -->|picked| urn_noocodec_dag_the-archivist/node/describe-merge
  urn_noocodec_dag_the-archivist/node/describe-merge["describe-merge"]
  urn_noocodec_dag_the-archivist/node/describe-merge -->|ranked| urn_noocodec_dag_the-archivist/node/describe-record
  urn_noocodec_dag_the-archivist/node/describe-merge -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/describe-record["describe-record"]
  urn_noocodec_dag_the-archivist/node/describe-record -->|recorded| urn_noocodec_dag_the-archivist/node/describe-gate
  urn_noocodec_dag_the-archivist/node/describe-gate["describe-gate"]
  urn_noocodec_dag_the-archivist/node/describe-gate -->|pass| urn_noocodec_dag_the-archivist/node/describe-recall
  urn_noocodec_dag_the-archivist/node/describe-gate -->|fail| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/describe-recall["describe-recall"]
  urn_noocodec_dag_the-archivist/node/describe-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-loop
  urn_noocodec_dag_the-archivist/node/recommend-similar["recommend-similar"]
  urn_noocodec_dag_the-archivist/node/recommend-similar -->|seeded| urn_noocodec_dag_the-archivist/node/similar-search
  urn_noocodec_dag_the-archivist/node/recommend-similar -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/similar-search[["similar-search"]]
  urn_noocodec_dag_the-archivist/node/similar-search -->|success| urn_noocodec_dag_the-archivist/node/compose-loop
  urn_noocodec_dag_the-archivist/node/similar-search -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/compose-loop[["compose-loop"]]
  urn_noocodec_dag_the-archivist/node/compose-loop -->|success| urn_noocodec_dag_the-archivist/node/respond-to-visitor
  urn_noocodec_dag_the-archivist/node/compose-loop -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/respond-to-visitor["respond-to-visitor"]
  urn_noocodec_dag_the-archivist/node/respond-to-visitor -->|success| urn_noocodec_dag_the-archivist/node/end
  urn_noocodec_dag_the-archivist/node/memory-recall["memory-recall"]
  urn_noocodec_dag_the-archivist/node/memory-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-memory-recall
  urn_noocodec_dag_the-archivist/node/compose-memory-recall["compose-memory-recall"]
  urn_noocodec_dag_the-archivist/node/compose-memory-recall -->|drafted| urn_noocodec_dag_the-archivist/node/respond-to-visitor
  urn_noocodec_dag_the-archivist/node/compose-memory-recall -->|retry| urn_noocodec_dag_the-archivist/node/compose-memory-recall
  urn_noocodec_dag_the-archivist/node/compose-memory-recall -->|salvage| urn_noocodec_dag_the-archivist/node/compose-memory-salvage
  urn_noocodec_dag_the-archivist/node/compose-memory-salvage["compose-memory-salvage"]
  urn_noocodec_dag_the-archivist/node/compose-memory-salvage -->|done| urn_noocodec_dag_the-archivist/node/respond-to-visitor
  urn_noocodec_dag_the-archivist/node/decline-off-topic["decline-off-topic"]
  urn_noocodec_dag_the-archivist/node/decline-off-topic -->|success| urn_noocodec_dag_the-archivist/node/end
  urn_noocodec_dag_the-archivist/node/compose-empty["compose-empty"]
  urn_noocodec_dag_the-archivist/node/compose-empty -->|drafted| urn_noocodec_dag_the-archivist/node/respond-to-visitor
  urn_noocodec_dag_the-archivist/node/compose-empty -->|retry| urn_noocodec_dag_the-archivist/node/compose-empty
  urn_noocodec_dag_the-archivist/node/compose-empty -->|salvage| urn_noocodec_dag_the-archivist/node/compose-empty-salvage
  urn_noocodec_dag_the-archivist/node/compose-empty-salvage["compose-empty-salvage"]
  urn_noocodec_dag_the-archivist/node/compose-empty-salvage -->|done| urn_noocodec_dag_the-archivist/node/respond-to-visitor
  urn_noocodec_dag_the-archivist/node/end((("end")))

What It Lets You Do

Use when

Use visualization when applications need to correlate the canonical JSON-LD DAG with a human-readable graph. Docs and guide pages use Mermaid; runnable demos use Cytoscape for live execution state.

Code Samples

The snippets below show each renderer surface and the metadata they emit.

API surface

SymbolSourceRole
MermaidRenderer.render(dag)@studnicky/dagonizer/vizReturns Mermaid flowchart source
JsonLdRenderer.render(dag)@studnicky/dagonizer/vizReturns a DagJsonLdDocumentType
CytoscapeRenderer.render(dag, options?)@studnicky/dagonizer/vizReturns readonly CytoscapeElementType[] (elements only; no positions)
DAGONIZER_VOCAB@studnicky/dagonizer/vizVocabulary base URI string; classes appear as dag:ClassName in the @context

Details for Nerds

MermaidRenderer

ts
import { MermaidRenderer } from '@studnicky/dagonizer/viz';
import { Dagonizer }       from '@studnicky/dagonizer';

import { archivistDAG } from '../dag.ts';

const flowchartSource = MermaidRenderer.render(archivistDAG);

console.log(flowchartSource);

Shape vocabulary

PlacementMermaid shapeExample output
singlerectanglegreet["greet"]
scattertrapezoidscout[/"scout"/]
embedded-dagsubroutineinvoke[["invoke"]]
terminal (completed)double-circledone((("done")))
terminal (failed)asymmetric flagabort>"abort"]

Routes render as labeled directed edges.

MermaidRenderer.render(dag, { theme }) also accepts visual parameters. Use fontFamily, fontSize, nodeSpacing, rankSpacing, and padding to drive Mermaid layout, and use primaryColor, lineColor, textColor, background, and containerTints to control emitted colors.

Containment coloring

Placements bound to a container role (EmbeddedDAGNode or dag-body ScatterNode with a non-empty container field) each receive a per-role Mermaid class (contained-<role>) whose fill and stroke come from a deterministic palette keyed on the role string. A DAG with two distinct roles (e.g. cpu and io) emits two classDef contained-cpu … and classDef contained-io … rules with different colors, then assigns each placement to its role-specific class. The @type-specific shape is preserved — a contained EmbeddedDAGNode remains a subroutine shape; a contained ScatterNode remains a trapezoid. In-process placements are unstyled (Mermaid default). classDef rules are omitted entirely when no contained placement exists in the DAG.

TerminalNode rendering. A TerminalNode placement renders as a named shape with an outcome suffix ((completed) or (failed)). Completed terminals use a double-circle shape; failed terminals use an asymmetric flag. TerminalNode placements emit no outbound edges; they are leaf nodes by definition.

Embedding in Markdown

md
```mermaid
{output of MermaidRenderer.render(dag)}
```

The output is a complete Mermaid block ready to drop into a fenced code block.

CytoscapeRenderer

CytoscapeRenderer.render(dag, options?) returns a plain readonly CytoscapeElementType[] with NO positions. Positioning is performed separately by CompositeLayout.compute (async) or handled internally by the CytoscapeGraph factory. To use the cytoscape visualizer, install the optional peer dependencies:

sh
npm install cytoscape @dagrejs/dagre

The package injects cytoscape (applications pass the constructor to CytoscapeGraph) and lazy-loads @dagrejs/dagre internally. Neither peer is required for the non-cytoscape renderers.

ts
import { CytoscapeRenderer } from '@studnicky/dagonizer/viz';

import { archivistDAG } from '../dag.ts';
import { bookSearchScatterDAG } from '../embedded-dags/BookSearchScatterDAG.ts';
import { composeRetryLoopDAG } from '../embedded-dags/ComposeRetryLoopDAG.ts';

const embeddedDAGs = new Map([
  ['book-search-scatter', bookSearchScatterDAG],
  ['compose-retry-loop',  composeRetryLoopDAG],
]);

const elements = CytoscapeRenderer.render(archivistDAG, { embeddedDAGs });

const nodeCount = elements.filter((el) => el.group === 'nodes').length;
const edgeCount = elements.filter((el) => el.group === 'edges').length;

console.log(`elements: ${elements.length} (${nodeCount} nodes, ${edgeCount} edges)`);

Pass an embeddedDAGs map to inline-expand EmbeddedDAGNode placements and ScatterNode placements whose body is a sub-DAG as compound nodes. The example above shows the Archivist's full embedded-DAG map.

The options object accepts only embeddedDAGs and maxDepth. The computeLayout and layoutOptions options are not accepted; layout is performed by CompositeLayout.compute or CytoscapeGraph internally.

Cytoscape element metadata

Every node element carries a data.type field for stylesheet selectors.

data.typeSourceAdditional fields
'single'SingleNode placementdata.node
'scatter'ScatterNode placementdata.body, data.source, data.gather, etc.
'embedded-dag'EmbeddedDAGNode placementdata.dag, data.stateMapping
'terminal'TerminalNode placementdata.outcome: 'completed' | 'failed'
'terminal'synthetic END nodedata.synthetic: true
'phase'PhaseNode placementdata.phase: 'pre' | 'post', data.node

User-declared TerminalNode placements and the synthetic END node both use data.type === 'terminal'. Distinguish them via data.synthetic === true (only set on the synthetic node) or data.outcome (only set on user-declared terminals).

Containment metadata

Placements bound to a container role carry an additional data.container field (the role string, e.g. 'cpu') and the extra CSS class dag-contained alongside the type class (dag-scatter, dag-embedded-dag, etc.). In-process placements omit data.container entirely.

Select contained nodes in Cytoscape stylesheets via:

  • .dag-contained — class selector, matches any contained placement regardless of type
  • node[container] — data selector, matches any node with a container role set
  • node[container="cpu"] — data selector, matches a specific role

CytoscapeGraph's built-in stylesheet applies per-role colors to .dag-contained nodes via cytoscape data(...) mapping — background-color: data(containerColor), border-color: data(containerStroke), color: data(containerText) — so each distinct container role renders with its own palette. The colors are written to node data by CytoscapeRenderer and driven by the same RoleColorUtils.forRole palette as the Mermaid renderer. Subclasses that override stylesheet() should carry this rule forward or replace it with a custom containment style.

Live rendering in the doc site

The GitHub Pages docs use Mermaid for guide and example pages so the registered JSON-LD and rendered graph stay visible together. Cytoscape is reserved for the runnable demo pages, where users need interactive execution state, expansion, and richer runtime navigation in The Archivist, The Cartographer, and The Dispatcher.

JsonLdRenderer

ts
import { JsonLdRenderer, DAGONIZER_VOCAB } from '@studnicky/dagonizer/viz';

import { archivistDAG } from '../dag.ts';

const doc = JsonLdRenderer.render(archivistDAG);

// DAGONIZER_VOCAB is the stable @context prefix for all dag: terms.
console.log(`// vocab: ${DAGONIZER_VOCAB}`);
console.log(JSON.stringify(doc, null, 2));

The output is a DagJsonLdDocumentType: @context, @id, @type, @graph (one entry per placement). Useful when feeding to a triple store, an RDF reasoner, or a graph database that consumes JSON-LD natively. The vocabulary base URI is available as DAGONIZER_VOCAB and is printed by the example above.

Classes appear in the output as prefixed IRIs under the dag: prefix (e.g. dag:ScatterNode, dag:EmbeddedDAGNode), where dag resolves to DAGONIZER_VOCAB via the document's @context.

Combining with read accessors

ts
// Read-accessor pattern: pull every registered DAG and render each one.
// `dispatcher.listDAGs()` returns all DAGs registered with registerDAG().
const dispatcher = new Dagonizer();
dispatcher.registerDAG(archivistDAG);

const sources = dispatcher.listDAGs().map((dag) => ({
  name:    dag.name,
  mermaid: MermaidRenderer.render(dag),
}));
console.log(`rendered ${sources.length} DAG(s): ${sources.map((s) => s.name).join(', ')}`);

The dispatcher's read accessors (getDAG, listDAGs, getNode, listNodes) make documentation generation straightforward: pull every registered DAG, render it, write the markdown.

Watched over by the Order of Dagon.