Skip to content

Architecture: How Flude Works

Audience: engine developers, and anyone who wants to understand what actually happens between "source code with Doxygen comments" and "a page on a documentation site" — beyond the one-paragraph summary in Getting Started.

Generation is two independent, sequential phases, connected through the file system rather than a direct function call. Understanding this split explains most of the "why does the site show stale content" and "why did nothing render" questions in Troubleshooting.


Phase A: content generation (ude.cli compile, per document)

Phase A runs once per document — one SDK, one language, one output format (e.g. bimnv_api_cpp for BimNv's C++ HTML reference, bimnv_api_cpp_hugo for the same content as Hugo Markdown). It is the pipeline described in Getting Started:

  • Collect: a *DoxygenCollector (engine/ude/collectors/doxygen.py) shells out to the real doxygen binary as an external subprocess and reads back its XML output.
  • Parse: a language-specific *DoxygenParser, dispatched by engine/ude/parsers/doxygen_router.py, normalizes the XML into a ProjectCatalog — the language-independent Intermediate Representation (IR) defined in engine/ude/models.py.
  • Render: one of 16 concrete renderer classes, named <Lang><Output><ID>Renderer with Lang ∈ {Cpp, Cs, Java, Py}, Output ∈ {Html, Hugo}, ID ∈ {Default, ODA} (engine/ude/renderers/static_html.py, hugo_markdown.py, oda.py), writes the final output.
  • Audit: every successful compile unconditionally prints a documentation coverage table — see CLI Reference.

UdeOrchestrator (engine/ude/orchestrator.py) drives Collect → Parse → Render for a single document; it does not know about, or participate in, Phase B below.

Where Phase A writes, in this repository

Real projects under ude_projects/ resolve output_base_dir (set once, in ude_projects/ude_global_config.json) against each document's own output_subdir. As configured today, that is ../.workdir/output/<output_subdir>/ — for example .workdir/output/bimnv_api_cpp/ for the static-HTML build of BimNv's C++ reference, and .workdir/output/bimnv_api_cpp_hugo/ for the Hugo-Markdown build of the same content (verified directly against ude_projects/ude_global_config.json and ude_projects/BimNv/bimnv_api_cpp/ude_doc_config.json on 2026-08-14). .workdir/ is a single gitignored root directory, not tracked in git.

For renderer.type values html / oda_html, this output is already a complete, self-contained static site for that one document — open it directly in a browser, nothing else needs to run. For hugo_markdown / oda_hugo_markdown, this output is Markdown only, and needs Phase B to become HTML.


Phase B: site build (ude_hugo_site/build_site.py)

Phase B runs separately and later, and does not invoke Doxygen or the parser at all. Each Hugo-variant document has a matching project under ude_hugo_site/projects/<doc>/, with its own hugo.toml. That file's [[module.mounts]] mounts the Phase-A Markdown output directly as that Hugo project's content/:

toml
# ude_hugo_site/projects/bimnv_api_cpp_hugo/hugo.toml (real file, abridged)
[[module.mounts]]
source = "../../../.workdir/output/bimnv_api_cpp_hugo"
target = "content"

ude_hugo_site/build_site.py runs hugo --destination for the shared portal (ude_hugo_site/portal/) and every such per-document project, producing the final combined HTML tree at .workdir/output/_hugo_site_dist/ — confirmed on 2026-08-14 to contain one subdirectory per SDK (bimnv/, kernel/, ifc/, ...) plus shared css//js/ and the portal's own index.html. No re-parsing of SDK source happens at this stage.

In other words: there is no direct call between orchestrator.render() and a finished site — these are two independent processes connected only via the file system. See Production Workflow for how to actually run both phases in this repository.

(Paths below are repository-root-relative.)

  • user-docs/docs/production-workflow.md — running Phase A and Phase B in this repository
  • user-docs/docs/target-settings.mdoutput_base_dir/output_subdir and the rest of the doc-config schema referenced above