1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages
DocForge2/docs/RENDERING_AND_VISUALIZATION.md

9.7 KiB

Rendering and visualization

DocForge has three independent ways to present one validated graph generation:

validated generation
    ├── manual plan → immutable package → detached HTML renderer → declared manual output
    ├── graph plan  → immutable package → detached graph renderer → portable static artifact
    └── pinned index → managed loopback viewer → interactive Nodes, Flow, Web, and lazy Logic

They share validated facts but not authority, publication, or lifecycle. A manual render does not publish a portable graph. A portable graph does not start the live viewer. None is canonical project content.

Manual rendering

A generic descriptor may declare a manual template root, isolated preview root, and stable views:

[render]
template_root = ".docforge/templates"
preview_root = ".docforge/previews"

[[render.views]]
id = "manual"
renderer = "generic_html"
template = "manual.html"
output = ".docforge/rendered/manual.html"
title = "My Project Manual"
families = ["architecture", "operations", "system"]

The renderer name is fixed to generic_html. Templates are confined UTF-8 assets with a fixed token vocabulary. They cannot name commands, Python modules, executable renderers, or arbitrary publication paths. Raw HTML in canonical Markdown is disabled by the pinned CommonMark path.

Plan and render identity covers the canonical source hash, optional changeset hash, selected nodes and relationships, view configuration, template hash, renderer contract, and parser version.

Use:

docforge --project-root "$PROJECT" render-status
docforge --project-root "$PROJECT" render-status manual --deep
docforge --project-root "$PROJECT" render manual
docforge --project-root "$PROJECT" preview CHANGESET_ID manual

Normal status verifies bounded source, configuration, template, output, renderer, and receipt identities without reconstructing output. --deep explicitly runs the side-effect-free full-render oracle. A changeset preview writes only to the isolated preview root.

Manual auto means that a successful canonical application owns regeneration of every declared manual view. It does not mean background rendering, and ordinary standalone CLI render cannot select auto; use explicit.

Portable graph rendering

Portable graph configuration is separate:

[graph_render]
output_root = ".docforge/portable-graph"

[[graph_render.views]]
id = "architecture"
renderer = "portable_graph_html"
output = "architecture.html"
title = "Architecture"
root = "architecture.overview"
initial_mode = "web"
depth = 3
max_nodes = 250
max_edges = 1000
max_work = 100000
families = ["architecture", "system"]
relations = ["depends_on", "owns", "calls", "reads", "writes", "tested_by", "relates_to"]
authorities = []
statuses = ["current", "active", "verified"]
tags = []
include_logic = false

A view selects exactly one exact root node or bounded metadata-only lexical query. Exact filters and node, edge, depth, and work limits close the selection. The initial mode is nodes, flow, or web. Portable graph contract version 1 excludes function-scoped Logic.

Use:

docforge --project-root "$PROJECT" graph-plan architecture
docforge --project-root "$PROJECT" graph-render architecture
docforge --project-root "$PROJECT" graph-render-status architecture

graph-plan validates and returns the generation-pinned plan without publication. graph-render is an explicit local CLI publication action. It commits a content-addressed artifact, renderer receipt, and bounded generation/view manifest in that order; the manifest is the publication commit. graph-render-status checks only bounded committed evidence and never plans or renders.

MCP may plan and inspect portable graph evidence, but it does not publish the portable artifact. Use the explicit project-local CLI command for publication.

Portable output is a complete static artifact. JavaScript is progressive enhancement, not a requirement for the graph facts to be present.

Live viewer

The live viewer is a managed, read-only browser over one generation-pinned validated SQLite file. Install the per-user manager once:

docforge-viewer-manager install-user-service

Then operate a project viewer:

docforge --project-root "$PROJECT" visualize
docforge --project-root "$PROJECT" visualize --node architecture.overview
docforge --project-root "$PROJECT" visualize --query persistence
docforge --project-root "$PROJECT" visualization-status
docforge --project-root "$PROJECT" visualization-stop

visualize accepts only an optional stable node ID or lexical query, bounded traversal depth, and the local --no-open presentation choice. It does not accept a project root override, database path, SQL, template, command, renderer, bind address, or module.

The HTTP listener binds to 127.0.0.1 on an operating-system-selected port. A random token is part of every accepted path. The server supports only GET and HEAD, sets no-store and restrictive browser security headers, and has no write, project-selection, arbitrary-query, or static filesystem endpoint.

The viewer is a snapshot. Index replacement or alteration makes that snapshot fail closed; start a new visualization to use a new validated generation. Source inspection reads only project-confined source evidence bound to the pinned generation.

Nodes, Flow, Web, and Logic

The interactive viewer offers four complementary projections:

  • Nodes shows a bounded relation-neutral incoming and outgoing neighborhood.
  • Flow presents semantic contributors toward the focus. Prerequisite-style stored relationships may be reversed for presentation without changing stored direction.
  • Web expands the convergence picture with contributors, callers, containers, members, and contextual relationships.
  • Logic loads a function-scoped control-flow projection only when requested.

Logic supports the explicit control paths published by Python, JavaScript, TypeScript, and C++ integrations. It stays outside the primary graph, portable graph version 1, search, and generation-diff receipts.

Hiding a node is presentation-only. In Flow and Web, ancestors without another path to the focus are removed. In Logic, an omitted-path bridge preserves downstream readability. Restore reverses the presentation change; neither action mutates the index.

Immutable plan and worker boundary

Manual and graph plans are versioned, canonical JSON with deterministic ordering and fixed structural and byte limits. They contain selected graph facts and bounded content, but no live project object, SQLite handle, absolute project or index path, arbitrary query, command, executable path, or caller-selected renderer module.

A projection package binds one plan to inert assets, fixed component versions, a closed built-in renderer identity, and an exact artifact inventory. The detached worker:

  • runs one fixed private module through isolated Python;
  • uses a trusted working directory and sanitized environment;
  • accepts one canonical newline-terminated JSON request;
  • returns one bounded canonical JSON response;
  • has a fixed renderer allowlist and timeout;
  • cannot select graph facts, read project state, choose output paths, or mutate canonical files.

The package contract is bounded, and actual artifact transfer has a fixed 20,000,000-byte ceiling. A larger descriptor max_render_bytes compatibility value does not widen that worker boundary.

Manual fragment reuse

Manual fragments are disposable semantic cache records, not publication authority. A cold record is accepted only after byte-exact comparison against a full detached render. On a warm hit, the worker independently recomputes the expected fragment before reuse.

Corrupt, forged, stale, incompatible, individually oversized, or aggregate-oversized records fall back to the complete full-render oracle. The current cache is bounded to 10,000 records and 64,000,000 bytes.

Fragment reuse is a correctness and recovery boundary. Do not promise a speedup without current measurements.

Projection policy

The version-2 projection policy is independent of capability mode:

manual:         auto | explicit | disabled
portable_graph: explicit | disabled
live_viewer:    on-demand | disabled

Set global CLI flags before the subcommand:

docforge --project-root "$PROJECT" --manual-render-policy disabled render manual
docforge --project-root "$PROJECT" --portable-graph-policy disabled graph-plan architecture
docforge --project-root "$PROJECT" --live-viewer-policy disabled visualize

An active operation blocked by policy fails before hidden work. Receipt-only manual and portable status remain available. Viewer status and explicit stop remain available when viewer startup is disabled.

A non-disabled selection also requires its resource: declared manual configuration, declared portable graph configuration, or viewer runtime. Manual auto additionally requires canonical application. Read Policy precedence for exact composition.

Failure and recovery

Render input drift detected before replacement fails without publishing a current receipt for stale output. Portable graph publication uses content-addressed evidence and a final manifest commit. Status never repairs implicitly.

Recovery is explicit:

  • rerun a manual render from validated canonical state;
  • use deep manual status for the full, side-effect-free equivalence oracle;
  • rerun portable graph publication, or repair only from validated content-addressed evidence;
  • stop and restart a stale live viewer against a current validated index.

Do not recover a derived output by editing its receipt or treating it as canonical. See Recovery and performance, Security, and the Viewer manager.