---
title: A Source's Journey Through PathMX
description: A worked, browser-readable tour from authored Markdown to a live, cacheable PathMX page.
theme:
  color:
    accent: oklch(0.6 0.15 245)
    link: oklch(0.54 0.16 245)
  measure: 76ch
---

# A Source's Journey Through PathMX

PathMX starts with a deliberately ordinary object: a Markdown Source that a
person can read, edit, diff, and keep. Everything else—the indexed graph,
compiled HTML, theme assets, live page, and cached representation—is derived
from that Source. This guide follows one Source through the complete pipeline
and uses the pipeline itself as a substantial rendering exercise.

The governing constraint is simple: authored truth should stay legible even
when every renderer is absent. A Source may gain diagrams, executable Actions,
math, highlighted examples, and live behavior, but none of those projections
should become the only copy of the learner's or author's work.

Use the [lifecycle map](#the-complete-lifecycle) for the whole route, the
[performance model](#a-small-performance-model) for the cost vocabulary, and
the [operational checklist](#operational-checklist) when diagnosing a slow or
stale page.

---

## 1. The durable unit is a Source

A Source is UTF-8 Markdown plus optional frontmatter. Its path gives it a
stable place in the repository; its parsed identity gives the rest of PathMX a
canonical way to refer to it. Headings, links, fenced code, and authored Block
boundaries remain visible in the file instead of being hidden in an opaque
database row.

This small example carries metadata, prose, a relative link, inline math, and
a code fence without requiring a proprietary editor:

````markdown
---
title: Conservation of energy
access:
  visibility: public
---

# Conservation of energy

For an isolated system, $E_{before}=E_{after}$.

Read the [worked example](./worked-example.path), then explain which
quantities moved between kinetic, gravitational, and thermal stores.

```ts
const total = kinetic + gravitational + thermal
```
````

The outer fence is intentionally highlighted Markdown. The nested TypeScript
is content inside that example rather than another live fence, demonstrating
that syntax can be discussed without accidentally activating it.

---

## 2. Identity comes from the repository boundary

The repository discovers Markdown files and normalizes filenames into Source
identifiers. `/notes/energy.path.md` becomes `/notes/energy.path`; route logic
can later decide which Source types are pages without changing the underlying
identity. Extensions such as `path`, `log`, `issue`, `demo`, and `components`
are semantic vocabulary, not an invitation to invent separate storage systems.

Let $S$ be the set of loaded Sources and $B(s)$ the Blocks parsed from Source
$s$. The total indexed Block population is

$$
|B| = \sum_{s \in S} |B(s)|.
$$

This matters operationally because a plugin can run once per Source, once per
Block, or once per page. A page with one hundred Blocks may therefore be more
expensive than a similarly sized page with one Block even when both contain
the same number of characters.

---

## 3. Parsing creates evidence, not a second authority

Loading extracts frontmatter, headings, links, fences, and Blocks. The parsed
records are indexes over the file: they make queries cheap, but they do not
replace the Markdown as the durable authority. If a cache disappears, PathMX
can reconstruct it from Sources. If the Source disappears, a cache is not a
safe substitute for authorship or provenance.

For a Source with $h$ headings, $l$ links, $f$ fences, and $b$ Blocks, a useful
structural summary is the tuple $I(s)=(h,l,f,b)$. That tuple is not a complete
performance model, but a sudden change from $I(s)=(8,12,2,4)$ to
$I(s)=(800,1200,200,400)$ is a strong signal that per-node plugin work deserves
inspection.

Parsing also establishes the boundary at which real bytes matter. A file that
claims to be an image but contains another format should be classified by its
bytes at the media workflow boundary; a Markdown Source should not need to
carry that normalization logic in every downstream plugin.

---

## 4. Indexing is incremental by Source

Indexing turns parsed evidence into lookup structures: Source identity,
headings, outgoing links, backlinks, actor profiles, access facts, and plugin
specific indexes. The desirable unit of invalidation is the changed Source and
the proven consumers of facts derived from it.

The following sketch shows the shape of an index plugin. It derives a compact
heading catalog and replaces exactly one Source's old contribution when that
Source changes:

```ts
import type { Plugin } from "@pathmx/core"

type HeadingFact = {
  source: string
  id: string
  depth: number
  text: string
}

export function HeadingCatalogPlugin(): Plugin {
  const bySource = new Map<string, HeadingFact[]>()

  return {
    index(source) {
      bySource.set(
        source.id,
        source.headings.map((heading) => ({
          source: source.id,
          id: heading.id,
          depth: heading.depth,
          text: heading.text,
        })),
      )
    },

    remove(source) {
      bySource.delete(source.id)
    },
  }
}
```

The important abstraction is ownership. The plugin owns its derived map; the
repository owns Sources; neither reaches into the other's representation to
mutate it indirectly.

---

## 5. The graph is rebuilt from explicit relationships

Links become graph edges after their targets are resolved. The graph can
answer questions such as “what refers here?”, “what is reachable from this
Root?”, and “which pages depend on this component?” without repeatedly
scanning Markdown. A missing target stays observable as a diagnostic rather
than being silently rewritten into a successful edge.

If $V$ is the Source set and $E$ the resolved-link set, the repository graph is
$G=(V,E)$. A full rebuild should be near $O(|V|+|E|)$; an edit that changes only
the prose of one Source should not require every Source to be reparsed. The
graph is a projection of authored relationships, so its persistence is an
optimization rather than a new source of truth.

The graph also keeps navigation honest. Breadcrumbs, tables of contents, and
related-page lists are consumers of graph facts. They should not infer a
parallel hierarchy from whatever DOM happens to be visible in the browser.

---

## 6. The complete lifecycle

The main pipeline is small enough to draw, but large enough to expose where
cost and authority live. Solid arrows are required work for a build; the
side branches are derived capabilities that can be delayed when their facts
are not needed for the current page.

```mermaid
flowchart TD
  File["Markdown Source on disk"] --> Read["Environment reads UTF-8 bytes"]
  Read --> Parse["Parse frontmatter and Markdown structure"]
  Parse --> Identity["Normalize Source id and type"]
  Identity --> Blocks["Extract authored Blocks"]
  Identity --> Headings["Index headings"]
  Identity --> Links["Index outgoing links"]
  Identity --> Fences["Index fenced content"]

  Blocks --> SourceIndex["Replace Source-owned index facts"]
  Headings --> SourceIndex
  Links --> Resolve["Resolve targets"]
  Fences --> SourceIndex
  Resolve --> Graph["Rebuild Source graph"]
  SourceIndex --> Graph

  Graph --> Request["Authorize and resolve page request"]
  Request --> Select["Select page Source"]
  Select --> Cache{"Compiled page cached?"}
  Cache -->|Miss| Compile["Create compile context"]
  Compile --> Pre["Run precompile hooks"]
  Pre --> Markdown["Compile Markdown to HTML"]
  Markdown --> Post["Run postcompile hooks"]
  Post --> Page["Run page hooks"]

  Pre --> Mermaid["Render Mermaid to inline SVG"]
  Pre --> MathStash["Protect TeX from Markdown parsing"]
  Post --> Highlight["Highlight code tokens"]
  Post --> MathML["Render protected TeX as MathML"]
  Page --> Assets["Collect scripts and styles"]
  Mermaid --> Markdown
  MathStash --> Markdown
  Highlight --> Page
  MathML --> Page

  Assets --> Hash["Hash document assets"]
  Page --> Document["Assemble semantic document"]
  Hash --> Document
  Document --> Store["Store compiled page cache"]
  Store --> Theme["Attach current theme asset"]
  Cache -->|Hit| Theme
  Theme --> Serve["Serve HTML response"]
  Serve --> Runtime["Runtime enhances navigation and Actions"]
  Runtime --> Live["Live refresh observes relevant changes"]
  Live --> Request

  Graph --> Search["Optional search projection"]
  Graph --> Export["Optional static export"]
  Graph --> Audit["Optional diagnostics and provenance"]
```

No single arrow grants permission to skip the authority boundary. A cached
page may avoid recompilation, but an HTTP request still resolves credentials
and access before protected output is returned.

---

## 7. Compilation is an ordered conversation

Plugins participate through narrow hooks. `precompile` sees Markdown and may
stash syntax that the Markdown compiler would otherwise consume.
`postcompile` sees HTML and can replace safe placeholders. `page` sees the
whole compiled page and can contribute document assets. Ordering is part of
the contract because one plugin's output can become another plugin's input.

For this page, Mermaid runs before the default stack so diagrams become slots
before the code highlighter sees fenced content. Math protects TeX before
Markdown parsing and replaces its placeholders afterward. Code highlighting
operates on ordinary code blocks but never double-highlights SVG created by
the Mermaid renderer.

Suppose hook $p$ runs over contexts $C_p$ and takes time $t(p,c)$ for context
$c$. Its total contribution is

$$
T_p = \sum_{c \in C_p} t(p,c).
$$

A performance trace should therefore report both $T_p$ and
$\max_{c\in C_p}t(p,c)$. A high total with a low maximum suggests repeated
overhead; a high maximum points toward one pathological Source, Block, or
diagram.

---

## 8. Mermaid is build-time content

Build-time Mermaid keeps the served document simple: the browser receives
inline SVG rather than a diagram parser, layout engine, and client-side render
queue. That improves determinism and avoids layout shifts, but the build
process must pay parser and layout cost. The current beautiful renderer uses
ELK for graph layout, so its first graph also activates a material resident
working set.

This fixture includes three different diagram families on purpose. The large
flowchart stresses graph layout, the sequence diagram protects the quoted
message syntax PathMX authors use, and the state diagram exercises a separate
parser and rendering path. Successful compilation must produce three SVG
figures, not three highlighted Mermaid code blocks.

Let $d$ be the number of diagrams, $n_i$ the nodes in diagram $i$, and $e_i$
its edges. A useful observation vector is
$D=(d,\sum_i n_i,\sum_i e_i,\max_i n_i)$. Diagram count alone cannot describe
a dense layout problem.

---

## 9. Code highlighting should scale with code, not prose

The highlighter searches compiled code blocks, identifies languages from
their classes, and tokenizes only languages it knows. Prose and Mermaid SVG
should take fast paths. Unknown languages remain escaped, readable code rather
than becoming build failures.

The environment adapter owns bundling of the small copy-button client. A Bun
environment can use Bun's native bundler while another runtime supplies the
same capability through its own adapter:

```js
export function createEnvironment(runtime) {
  return {
    async readText(path) {
      return runtime.files.readUtf8(path)
    },

    async bundle(entry) {
      const result = await runtime.bundle({
        entrypoints: [entry],
        minify: true,
        target: "browser",
      })
      return result.outputs
    },

    hash(text) {
      return runtime.crypto.sha256(text).slice(0, 8)
    },
  }
}
```

The portable engine asks for “bundle this client entry”; it does not import a
Bun-only API. That seam is what lets the same core architecture target Bun,
Node, Workers, and future hosts without pretending their filesystem and module
systems are identical.

---

## 10. Math is stashed before Markdown compilation

Dollar-delimited TeX overlaps with ordinary Markdown punctuation, inline code,
and currency prose. The math plugin first masks inline code and fenced regions,
then stashes recognized display and inline expressions. After Markdown has
produced HTML, the plugin replaces numbered placeholders with MathML.

For example, the cache hit ratio is $h=H/(H+M)$ for cache hits $H$ and misses
$M$. If a hit costs $T_h$ and a miss costs $T_m$, average request work is

$$
E[T] = hT_h + (1-h)T_m.
$$

This page also exercises a matrix,
$A=\begin{bmatrix}1&1\\0&1\end{bmatrix}$, a set
$R=\{s\in S\mid s\text{ is reachable from the Root}\}$, and a bounded sum
$\sum_{i=1}^{d}(n_i+e_i)$. Each expression has architectural meaning while
forcing the renderer to handle more than the smallest `$x$` case.

---

## 11. Assets are page facts before they are URLs

Plugins contribute named stylesheets and scripts to the compile context.
Document assembly deduplicates those assets, hashes their content, and exposes
immutable URLs. A page without math should not receive the math stylesheet; a
page without code should not receive the copy-button client.

The distinction between an asset fact and its served URL is useful. Plugins
can say “this page needs `math.css`” without predicting the final content hash
or route. The document layer can then combine identical assets across many
pages and keep caching policy centralized.

A compact manifest might look like this:

```json
{
  "source": "/guides/source-journey.path",
  "assets": [
    { "type": "stylesheet", "name": "theme.css", "immutable": true },
    { "type": "stylesheet", "name": "math.css", "immutable": true },
    { "type": "stylesheet", "name": "code-highlight.css", "immutable": true },
    { "type": "script", "name": "code-highlight.js", "module": true }
  ],
  "document": {
    "view": "main[data-pmx-view]",
    "live": true
  }
}
```

The manifest is illustrative rather than a second configuration format. The
real API remains typed objects passed between plugins and the engine.

---

## 12. Cache entries are replaceable projections

Compiled pages are cached by canonical Source identity. A clean build compiles
every page Source; a watched edit should invalidate only pages whose output can
actually change. If a shared component or global style changes, dependency
facts may fan that invalidation out to multiple pages. If ordinary prose
changes, global invalidation is evidence of an overly broad dependency.

Let $P$ be the page set, $C\subseteq P$ the pages compiled after an edit, and
$A\subseteq P$ the pages whose artifacts could change. Correct invalidation
requires $A\subseteq C$; efficient invalidation tries to minimize
$|C\setminus A|$. Compiling fewer pages is not a success if a genuinely
affected page stays stale.

Cache replacement should be atomic from the reader's perspective. A request
observes the old complete page or the new complete page, not half-updated HTML
paired with a new theme hash.

---

## 13. Requests still cross an authority boundary

Compilation answers “what would this Source render as?” Request handling
answers “may this Principal receive it now?” Those are different questions.
Public Sources, private Homes, internal actor records, shared Sources, and
attachments all use the same resolved request credentials but can apply
different access facts.

The server should avoid revealing whether a protected Source exists to an
unauthorized caller. Exact access decisions can use the Actor directory and
Source access index internally while the external response remains
non-enumerating.

An authorization decision can be modeled as
$allow = f(principal,operation,source,currentFacts)$. The word “current” is
important: a cached page compiled before a roster or membership change must
not bypass the new access decision.

---

## 14. A request-to-live-refresh sequence

The sequence below makes ownership explicit. The browser owns navigation
intent, the Host owns credentials and authorization, the engine owns compiled
page projections, and the repository owns current Sources. A live event is a
hint to reconcile; it is not itself the durable content.

```mermaid
sequenceDiagram
  participant Author as "Author or CI"
  participant Repo as "Source repository"
  participant Engine as "PathMX engine"
  participant Host as "Authorized Host"
  participant Player as "Browser Runtime"

  Author->>Repo: "write Markdown Source M2"
  Repo->>Engine: "changed source /guides/journey.path"
  Engine->>Engine: "index, rebuild affected graph facts"
  Engine->>Engine: "compile page and immutable assets"
  Engine-->>Host: "publish cache generation G2"
  Player->>Host: "GET /guides/journey"
  Host->>Host: "resolve Principal and current access"
  Host->>Engine: "read authorized page from G2"
  Engine-->>Host: "HTML plus asset references"
  Host-->>Player: "200 document from Source M2"
  Player->>Host: "subscribe to live page events"
  Author->>Repo: "write corrected Source M3"
  Repo->>Engine: "invalidate affected page"
  Engine-->>Host: "publish cache generation G3"
  Host-->>Player: "page changed; reconcile"
  Player->>Host: "GET current document"
  Host-->>Player: "authorized document from M3"
```

Quoted messages are intentional. They protect punctuation-rich PathMX prose
that has historically exposed differences between Mermaid parsers.

---

## 15. Runtime enhancement preserves document semantics

The served HTML is complete enough for ordinary navigation and forms without
JavaScript. The Runtime enhances eligible same-origin navigation, Action
submission, theme switching, and live refresh. It does not become the only
authority for routes or mutations.

When enhanced navigation succeeds, the Runtime replaces one explicit view,
reconciles document metadata and assets, restores focus and scroll behavior,
and rebinds live observation. When it cannot prove that the response is a
compatible PathMX document, normal browser navigation is the recovery path.

The desired hierarchy is progressive: semantic document first, enhancement
second. This is why performance measurements should include HTML bytes and
first contentful paint rather than reporting only client bundle execution.

---

## 16. Actions are trusted mutations, not arbitrary scripts

An Action receives an authenticated context, validates input, and proposes a
mutation inside the Host's authority boundary. The browser may request the
Action, but it cannot grant itself access or write directly into another
Actor's Home.

This Python example is intentionally a conceptual adapter rather than a
PathMX production API. It demonstrates the data boundary a non-JavaScript host
would need to preserve:

```python
from dataclasses import dataclass

@dataclass(frozen=True)
class MutationRequest:
    operation_id: str
    actor_id: str
    source_id: str
    expected_version: str
    markdown: str

def admit(request: MutationRequest, authority, repository):
    current = repository.version(request.source_id)
    if current != request.expected_version:
        return {"type": "conflict", "current": current}
    if not authority.may_write(request.actor_id, request.source_id):
        return {"type": "denied"}
    return {"type": "accepted", "operation": request.operation_id}
```

The durable invariants are portable even if transaction and filesystem APIs
differ by host: exact Actor identity, current authorization, optimistic
conflict detection, deterministic operation identity, and an auditable Source
transition.

---

## 17. Live state has an explicit lifecycle

A page moves through a small number of states. Keeping them explicit prevents
“there is a socket” from being mistaken for “the learner sees current work.”

```mermaid
stateDiagram-v2
  [*] --> Unloaded
  Unloaded --> Loading: authorized navigation
  Loading --> Current: document and assets accepted
  Loading --> Failed: request or document rejected
  Current --> Watching: live subscription established
  Watching --> Refreshing: relevant Source changed
  Refreshing --> Current: replacement document accepted
  Refreshing --> Stale: refresh failed; current view retained
  Stale --> Refreshing: retry or reconnect
  Stale --> Loading: explicit reload
  Watching --> Loading: full navigation required
  Failed --> Loading: retry
  Current --> [*]: page closed
  Watching --> [*]: page closed
```

`Stale` is not the same as `Failed`. A transient live-refresh error can leave a
usable document on screen while honestly reporting that it may no longer be
current. An uncertain Action result is different again: the mutation may have
completed, so blind resubmission can be unsafe.

---

## 18. A small performance model

For one cold Source compilation, separate setup, transformation, layout,
assembly, and retention:

$$
T_{cold}=T_{load}+T_{index}+T_{compile}+T_{assets}+T_{layout}.
$$

For a warm watched edit, loaded modules and bundled document assets can be
reused, giving approximately
$T_{warm}=T_{reindex}+T_{affected}+T_{replace}$. Neither equation guarantees
that warm work is cheap; it merely identifies which terms should disappear.

Peak memory should also be decomposed. Let $R_0$ be resident memory before the
feature activates, $R_f$ the feature's retained runtime, $R_i$ temporary input
and layout state, and $R_o$ retained output. Then

$$
R_{peak}\approx R_0+R_f+R_i+R_o.
$$

If output is one megabyte but RSS rises by two hundred megabytes, optimizing
SVG whitespace cannot explain or repair the dominant term. Conversely, a
renderer that uses little memory but emits repeated megabytes of inline CSS
may still be a poor cache and network tradeoff.

---

## 19. Measure complete operations

A useful benchmark names its lifecycle. “Render time” might mean parsing one
warm diagram, importing a renderer and producing SVG, compiling a Source,
building all pages, or navigating a browser to first contentful paint. Those
numbers answer different questions.

For this heavy reference Source, report at least:

- environment and runtime version;
- Source bytes, lines, Blocks, code fences, math expressions, diagram families,
  nodes, and edges;
- cold setup and compile time in a fresh process;
- warm median and p95 compile time after feature activation;
- HTML and document-asset bytes;
- RSS before compilation, RSS after the cold compile, and OS maximum RSS;
- plugin warnings and counts of actually rendered artifacts.

The benchmark should fail if diagrams silently fall back to code, math remains
as raw dollar syntax, or code highlighting stops tokenizing. Faster incorrect
output is not a performance improvement.

---

## 20. Portability lives in capability seams

The core needs clocks, hashing, file discovery, file reads, asset bundling, and
possibly durable stores. It should ask an environment for those capabilities
instead of importing one runtime's globals throughout repository and engine
code.

The shell below illustrates a portable operator contract: inputs and outputs
are explicit, the Source root is not inferred from a home directory, and a
diagnostic run can be isolated from production state.

```bash
set -euo pipefail

source_root="${1:?pass a Source root}"
output_root="${2:?pass an output directory}"

bun run pathmx/core/cli/index.ts build \
  --root "$source_root" \
  --out "$output_root" \
  --print-url

test -f "$output_root/index.html"
```

A Node, Worker, or Vercel adapter may expose different mechanisms, but it can
preserve the same observable operation: load one Source graph, compile the
selected pages, and return explicit artifacts or diagnostics.

---

## 21. Source changes should have narrow consequences

An edit can affect parsing, graph facts, compiled HTML, shared components,
styles, or authorization metadata. Invalidation should be derived from those
facts. Filename suffixes and broad directory membership are convenient hints,
but they are not sufficient evidence that every page depends on a Source.

For a change $\Delta s$, define $deps(\Delta s)$ as the proven dependent pages.
The ideal work set is $W=\{s\}\cup deps(\Delta s)$. A system that recompiles
all $|P|$ pages for every edit has cost $O(|P|)$ even when $|W|=1$; a system
that compiles only $s$ when a shared component changed is fast but wrong.

Observability makes that tradeoff reviewable. A watched edit should log which
Source changed, which dependency rule selected each affected page, how many
pages compiled, when the new page became visible, and whether optional search
or export projections are still catching up.

---

## 22. Themes remain document-level capabilities

Theme tokens let authored content adapt without baking one palette into every
Source. Mermaid SVG should use the same background, foreground, surface,
border, muted, and accent variables as prose and code. MathML should inherit
the surrounding text color. Highlighting may provide token colors while still
respecting contrast in both light and dark modes.

This CSS example shows the intended seam rather than a separate design system:

```css
:root {
  --pmx-color-bg: oklch(0.985 0.006 255);
  --pmx-color-fg: oklch(0.25 0.025 255);
  --pmx-color-surface: oklch(0.96 0.012 255);
  --pmx-color-border: oklch(0.82 0.025 255);
  --pmx-color-accent: oklch(0.58 0.16 245);
  --pmx-font-body: Inter, ui-sans-serif, system-ui, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    --pmx-color-bg: oklch(0.19 0.02 255);
    --pmx-color-fg: oklch(0.92 0.015 255);
    --pmx-color-surface: oklch(0.24 0.025 255);
    --pmx-color-border: oklch(0.38 0.035 255);
  }
}

.pmx-mermaid svg,
[data-pathmx-math] {
  max-inline-size: 100%;
}
```

Theme verification must inspect real rendered artifacts. A CSS variable in
Source code is only intent until the browser shows that SVG text, lines,
surfaces, and MathML remain legible in both schemes.

---

## 23. Failure should preserve authored meaning

If Mermaid parsing fails, the original fenced diagram remains readable and a
Source-local warning identifies the failure. If TeX is unsupported, its text
remains visible in an error wrapper. If a highlighter does not know a language,
the escaped code remains available. These are graceful degradations because
authored evidence survives.

The same principle applies at larger boundaries. A static export failure must
not corrupt the repository. A live refresh failure must not erase the current
view. A denied write must not partially mutate related Sources. A cache miss
may compile from current Sources, but it must not fabricate content from stale
or unrelated artifacts.

Operational status should be equally precise: provider success is not mailbox
delivery, HTTP 200 is not browser acceptance, and a generated asset is not a
live route until its document actually references and serves it.

---

## 24. A request diagnostic in TypeScript

The diagnostic below keeps phases separate so a slow public route does not
collapse origin, gateway, and browser behavior into one number:

```ts
type Timing = {
  label: string
  status: number
  headersMs: number
  bodyMs: number
  bytes: number
}

async function measure(label: string, url: string): Promise<Timing> {
  const started = performance.now()
  const response = await fetch(url, { redirect: "manual" })
  const headers = performance.now()
  const body = await response.arrayBuffer()
  const finished = performance.now()

  return {
    label,
    status: response.status,
    headersMs: headers - started,
    bodyMs: finished - headers,
    bytes: body.byteLength,
  }
}

const rows = await Promise.all([
  measure("origin", "http://127.0.0.1:3000/guides/journey"),
  measure("gateway", "http://127.0.0.1:8787/guides/journey"),
  measure("public", "https://example.test/guides/journey"),
])

console.table(rows)
```

A multi-second 200 is degraded, not healthy. Separating time to headers from
body transfer also distinguishes server work from unexpectedly large output.

---

## 25. A portable benchmark record

Machine-readable output makes before/after comparisons less dependent on log
formatting. This example records provenance and keeps cold, warm, and memory
observations distinct:

```json
{
  "benchmark": "heavy-source-v1",
  "runtime": { "name": "bun", "version": "1.3.14" },
  "machine": { "class": "same-mbp", "arch": "arm64" },
  "fixture": {
    "source": "/examples/pathmx-source-journey.demo",
    "codeBlocks": 9,
    "mathExpressions": 58,
    "mermaidDiagrams": 3
  },
  "cold": { "samples": 3, "metric": "compile.page" },
  "warm": { "samples": 5, "summary": ["median", "p95"] },
  "memory": { "before": "rss", "after": "rss", "external": "max-rss" },
  "correctness": {
    "requireHighlightedCode": true,
    "requireMathML": true,
    "requireInlineSvg": true,
    "allowRendererWarnings": false
  }
}
```

Numbers are intentionally absent from the authored example. Baselines belong
in the performance log beside the exact commit, runtime, and command that
produced them; the Source fixture defines work, not a forever claim about one
machine.

---

## 26. Review the output structurally and visually

Structural assertions catch missing work cheaply: count three Mermaid figures,
nine ordinary code wrappers, the expected MathML wrappers, required assets, and
zero renderer warnings. They also verify that the large flowchart labels and
quoted sequence message survive compilation.

Visual review catches what counts cannot: clipped labels, edge crossings,
illegible dark-mode colors, horizontally overflowing equations, copy buttons
covering code, and a table of contents that becomes unwieldy. A performance
fixture is still a document; if it looks absurd, it is a poor representative
of the product experience.

The two review modes complement one another. Screenshots alone cannot prove
that every equation rendered, and string counts cannot prove that a 40-node
diagram is readable.

---

## 27. Interpret cold and warm results separately

Cold activation answers what happens when a small build or CLI process meets
its first expensive Source. It includes dynamic module import, renderer
initialization, initial asset bundling, and the first parse/layout operation.
Warm compilation answers what happens during subsequent edits while those
modules and caches remain resident.

Neither is universally more important. A long-lived development Host cares
about warm edit visibility and retained memory. A serverless build or one-page
export may care more about cold latency. A full static build cares about
throughput across many distinct Sources and total retained output.

For repeated warm samples $x_1,\ldots,x_n$, report the median to resist one
scheduler interruption and p95 to expose tail behavior. Do not silently discard
the first sample and then describe the result as cold.

---

## 28. Define a heavy reference case, not an infinite worst case

There is no finite worst Source unless PathMX imposes limits on Source bytes,
Block count, code tokens, TeX complexity, and diagram nodes and edges. This
fixture instead defines one reviewable reference case that is large enough to
exercise realistic expensive paths while remaining understandable to a human.

The bounds are part of the evidence. If the fixture later grows from three
diagrams to thirty or from thirty kilobytes to three megabytes, its baseline
must not be compared to the old one as though the work were unchanged.

Separate adversarial limit tests can cover malformed or intentionally enormous
input. Their job is bounded failure and resource safety. This fixture's job is
representative heavy rendering with correct, attractive output.

---

## 29. Operational checklist

When a PathMX page seems slow or stale:

1. Identify the exact Source, route, Host, runtime, and corpus snapshot.
2. Confirm whether the request compiled, read cache, or served a static export.
3. Inspect `compile.page` and per-plugin totals plus maximum labeled contexts.
4. Separate cold renderer activation from warm diagram layout.
5. Compare RSS before activation, after activation, and after many pages.
6. Verify the rendered HTML contains expected code, MathML, and SVG artifacts.
7. Measure direct origin, local gateway, and public HTTPS independently.
8. Confirm current authorization and generated asset responses.
9. Inspect the browser's visible page and console before calling it healthy.
10. Record the command, runtime, machine, result, and remaining uncertainty.

This sequence keeps diagnosis source-first. It narrows the failing boundary
before restarting shared infrastructure or changing architecture.

---

## 30. The architectural through-line

PathMX can remain small because each layer has one job. The repository owns
durable Sources. Parsing and plugins derive facts. The graph relates them. The
compiler creates replaceable documents. The cache accelerates reads. The Host
owns credentials and authority. The Runtime enhances an already meaningful
page. Optional search and exports consume the same current graph at the edge.

The whole lifecycle is summarized by one invariant:

$$
\text{durable Source} \;\longrightarrow\; \text{derived, replaceable views}.
$$

Performance work should protect that direction. Faster derivation is valuable;
making a cache or browser session the only surviving copy of authorship is not.
The best optimization removes repeated derived work while leaving Source
ownership, provenance, and authorization easier—not harder—to explain.
