2026-07-25 16:00:19 -04:00
|
|
|
|
# DocForge user manual
|
|
|
|
|
|
|
|
|
|
|
|
DocForge turns project-owned documentation and source projections into a validated graph that
|
|
|
|
|
|
people and AI agents can search, inspect, visualize, and change through reviewable proposals.
|
|
|
|
|
|
Canonical project files remain authoritative. The SQLite graph, previews, rendered manuals, and
|
|
|
|
|
|
viewer processes are derived and can be rebuilt.
|
|
|
|
|
|
|
2026-07-25 18:33:42 -04:00
|
|
|
|
DocForge 1.0.0 is the first stable product release. It includes the project-scoped graph,
|
|
|
|
|
|
CLI and MCP query surfaces, hash-approved proposal application, generic and project-owned adapters,
|
|
|
|
|
|
declared rendering, and the Nodes/Flow/Web visualization model documented below.
|
|
|
|
|
|
|
2026-07-25 19:21:23 -04:00
|
|
|
|
Later incremental-compiler capabilities are additive. A Release 1 adapter with only
|
|
|
|
|
|
`load_projection()` remains valid and follows the same complete-rebuild path. No existing project
|
|
|
|
|
|
descriptor, canonical document, changeset, or adapter must be rewritten. Source-scoped caching and
|
|
|
|
|
|
lazy logic projections activate only for adapters that explicitly implement the optional
|
|
|
|
|
|
incremental methods while retaining the full loader as a fallback.
|
|
|
|
|
|
|
2026-07-25 16:00:19 -04:00
|
|
|
|
## Features
|
|
|
|
|
|
|
|
|
|
|
|
- Project-bound Markdown and TOML documentation graphs with stable node IDs.
|
|
|
|
|
|
- Deterministic validation for metadata, relationships, dependency cycles, paths, and limits.
|
|
|
|
|
|
- Disposable SQLite indexing with lexical search, filters, backlinks, dependencies, and impact.
|
|
|
|
|
|
- Bounded context profiles for AI agents, including source paths and content hashes.
|
|
|
|
|
|
- Isolated, optimistic changesets with create, update, move, delete, validation, diffs, and previews.
|
2026-07-25 19:08:39 -04:00
|
|
|
|
- Relationship-only changeset operations that do not rewrite node content.
|
2026-07-25 16:00:19 -04:00
|
|
|
|
- Hash-bound canonical application through both CLI and an explicitly enabled MCP tool.
|
2026-07-25 19:08:39 -04:00
|
|
|
|
- Opt-in incremental adapter extraction with reverse-dependency invalidation.
|
|
|
|
|
|
- Lazy function-scoped logic projections that do not densify the primary graph.
|
2026-07-25 16:00:19 -04:00
|
|
|
|
- Declared HTML render views. Arbitrary templates, render commands, and output paths are rejected.
|
2026-07-25 17:34:58 -04:00
|
|
|
|
- A loopback-only graph browser with Nodes, semantic Flow, and convergence Web views,
|
|
|
|
|
|
relationship keys, source inspection, branch-aware node hiding, panel resizing, zooming, and
|
|
|
|
|
|
managed idle shutdown.
|
2026-07-25 16:00:19 -04:00
|
|
|
|
- A generic Markdown/TOML adapter plus contracts for deterministic project-owned adapters.
|
|
|
|
|
|
|
|
|
|
|
|
DocForge does not run shell commands from documentation, mutate Git, build an application, deploy,
|
|
|
|
|
|
publish, choose a project globally, or cross project boundaries.
|
|
|
|
|
|
|
|
|
|
|
|
## Mental model
|
|
|
|
|
|
|
|
|
|
|
|
One `.docforge/project.toml` binds DocForge to one project root. The descriptor declares canonical
|
|
|
|
|
|
content roots, authority files, derived paths, proposal writers, relationship types, limits,
|
|
|
|
|
|
context profiles, and optional render views.
|
|
|
|
|
|
|
|
|
|
|
|
Canonical files own facts:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
canonical Markdown/TOML or adapter sources
|
|
|
|
|
|
↓ validate
|
|
|
|
|
|
disposable SQLite graph
|
|
|
|
|
|
↓ query / visualize / compile context
|
|
|
|
|
|
people and agents
|
|
|
|
|
|
↓ propose
|
|
|
|
|
|
isolated changeset + preview
|
|
|
|
|
|
↓ exact hash approval
|
|
|
|
|
|
canonical apply
|
|
|
|
|
|
↓
|
|
|
|
|
|
reindexed graph + declared renders
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
An apply operation is deliberately narrower than a general file editor. It accepts one validated
|
|
|
|
|
|
changeset ID and the exact SHA-256 changeset hash that was reviewed. It rejects stale canonical
|
|
|
|
|
|
sources, changed proposals, overlapping proposals, unauthorized families or operations, unsafe
|
|
|
|
|
|
paths, symlink escapes, and projections that do not round-trip through the project loader.
|
|
|
|
|
|
|
|
|
|
|
|
The generic adapter can serialize its Markdown and TOML nodes directly. A custom adapter must
|
|
|
|
|
|
provide its own canonical applier because only that project knows how a graph node maps back to its
|
|
|
|
|
|
source format.
|
|
|
|
|
|
|
|
|
|
|
|
## Setup
|
|
|
|
|
|
|
|
|
|
|
|
### Requirements
|
|
|
|
|
|
|
|
|
|
|
|
- Python 3.12 or newer.
|
|
|
|
|
|
- [`uv`](https://docs.astral.sh/uv/) for the development environment.
|
2026-07-25 16:23:23 -04:00
|
|
|
|
- Node.js and npm for browser asset validation and strict Pyright checking.
|
2026-07-25 16:00:19 -04:00
|
|
|
|
|
|
|
|
|
|
Clone and verify DocForge:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
git clone forgejo@repo.andraxion.net:administrator/DocForge.git /absolute/path/DocForge
|
|
|
|
|
|
cd /absolute/path/DocForge
|
2026-07-25 16:23:23 -04:00
|
|
|
|
uv sync --group dev
|
2026-07-25 16:00:19 -04:00
|
|
|
|
npm ci
|
|
|
|
|
|
|
2026-07-25 16:23:23 -04:00
|
|
|
|
npx pyright
|
2026-07-25 16:00:19 -04:00
|
|
|
|
npm run lint:web
|
|
|
|
|
|
uv run ruff check src tests tools
|
|
|
|
|
|
uv run ruff format --check src tests tools
|
2026-07-25 16:23:23 -04:00
|
|
|
|
uv run pytest -q
|
2026-07-25 16:00:19 -04:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Use the executables under `/absolute/path/DocForge/.venv/bin/` when DocForge is not installed into
|
|
|
|
|
|
the active shell environment.
|
|
|
|
|
|
|
|
|
|
|
|
### Configure a generic project
|
|
|
|
|
|
|
|
|
|
|
|
Create `/absolute/path/MyProject/.docforge/project.toml`:
|
|
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
|
schema_version = 1
|
|
|
|
|
|
project_id = "my-project"
|
|
|
|
|
|
title = "My Project"
|
|
|
|
|
|
adapter = "generic"
|
|
|
|
|
|
|
|
|
|
|
|
[sources]
|
|
|
|
|
|
content_roots = ["Docs/Manual"]
|
|
|
|
|
|
authority_files = []
|
|
|
|
|
|
|
|
|
|
|
|
[derived]
|
|
|
|
|
|
cache_root = ".docforge/cache"
|
|
|
|
|
|
index = ".docforge/cache/index.sqlite3"
|
|
|
|
|
|
|
|
|
|
|
|
[changesets]
|
|
|
|
|
|
root = ".docforge/changesets"
|
|
|
|
|
|
|
|
|
|
|
|
[[changesets.writers]]
|
|
|
|
|
|
id = "project-editor"
|
|
|
|
|
|
families = ["architecture", "system", "operations", "roadmap"]
|
|
|
|
|
|
operations = ["create", "update", "move", "delete"]
|
|
|
|
|
|
|
|
|
|
|
|
[render]
|
|
|
|
|
|
template_root = "Docs/Templates"
|
|
|
|
|
|
preview_root = ".docforge/previews"
|
|
|
|
|
|
|
|
|
|
|
|
[[render.views]]
|
|
|
|
|
|
id = "manual"
|
|
|
|
|
|
renderer = "generic_html"
|
|
|
|
|
|
template = "manual.html"
|
|
|
|
|
|
output = "Docs/Rendered/Manual.html"
|
|
|
|
|
|
title = "My Project Manual"
|
|
|
|
|
|
families = ["architecture", "system", "operations", "roadmap"]
|
|
|
|
|
|
|
|
|
|
|
|
[graph]
|
|
|
|
|
|
allowed_relations = ["depends_on", "owns", "calls", "reads", "writes", "tested_by", "relates_to"]
|
|
|
|
|
|
|
|
|
|
|
|
[limits]
|
|
|
|
|
|
max_source_bytes = 500000
|
|
|
|
|
|
max_nodes = 10000
|
|
|
|
|
|
max_query_chars = 500
|
|
|
|
|
|
max_results = 100
|
|
|
|
|
|
max_traversal_depth = 6
|
|
|
|
|
|
max_context_tokens = 12000
|
|
|
|
|
|
max_changesets = 100
|
|
|
|
|
|
max_changeset_operations = 100
|
|
|
|
|
|
max_changeset_bytes = 1000000
|
|
|
|
|
|
|
|
|
|
|
|
[[profiles]]
|
|
|
|
|
|
id = "development"
|
|
|
|
|
|
families = ["architecture", "system", "operations", "roadmap"]
|
|
|
|
|
|
statuses = ["current", "active", "verified"]
|
|
|
|
|
|
required_nodes = ["architecture.overview"]
|
|
|
|
|
|
token_budget = 8000
|
|
|
|
|
|
dependency_depth = 3
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Every path is resolved against the explicit project root. Canonical content, derived cache, and
|
|
|
|
|
|
changeset roots must not overlap.
|
|
|
|
|
|
|
|
|
|
|
|
### Add a Markdown node
|
|
|
|
|
|
|
|
|
|
|
|
Create `Docs/Manual/architecture-overview.md`:
|
|
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
|
+++
|
|
|
|
|
|
schema_version = 1
|
|
|
|
|
|
id = "architecture.overview"
|
|
|
|
|
|
title = "Architecture overview"
|
|
|
|
|
|
family = "architecture"
|
|
|
|
|
|
authority = "authoritative"
|
|
|
|
|
|
status = "current"
|
|
|
|
|
|
tags = ["architecture", "ownership"]
|
|
|
|
|
|
summary = "Defines the top-level systems and ownership boundaries."
|
|
|
|
|
|
depends_on = ["system.persistence"]
|
|
|
|
|
|
+++
|
|
|
|
|
|
|
|
|
|
|
|
# Architecture overview
|
|
|
|
|
|
|
|
|
|
|
|
Describe the project’s systems, authorities, persistence owners, runtime flow, failure behavior,
|
|
|
|
|
|
tests, and operational entry points.
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Each Markdown file contains one node. A TOML source may contain multiple `[[nodes]]` records. TOML
|
|
|
|
|
|
nodes need stable `source_anchor` values when proposals may create or move records within the file.
|
|
|
|
|
|
Every relationship target must exist.
|
|
|
|
|
|
|
|
|
|
|
|
### Build the graph
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
PROJECT=/absolute/path/MyProject
|
|
|
|
|
|
DOCFORGE=/absolute/path/DocForge/.venv/bin/docforge
|
|
|
|
|
|
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" validate
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" reindex
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" context development
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`reindex` builds the SQLite graph and immediately checks its identity. Run it after canonical
|
|
|
|
|
|
documentation or adapter sources change.
|
|
|
|
|
|
|
|
|
|
|
|
### Install the viewer manager
|
|
|
|
|
|
|
|
|
|
|
|
Install the native per-user supervisor once:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-viewer-manager install-user-service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Linux uses `systemd --user`, macOS uses a LaunchAgent, and Windows uses Task Scheduler. If the
|
|
|
|
|
|
virtual environment moves, reinstall the service so it points at the current Python interpreter.
|
|
|
|
|
|
|
|
|
|
|
|
For a temporary foreground manager:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-viewer-manager serve
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Open a project graph without Codex:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge --project-root "$PROJECT" visualize
|
|
|
|
|
|
docforge --project-root "$PROJECT" visualize --node architecture.overview
|
|
|
|
|
|
docforge --project-root "$PROJECT" visualize --query persistence
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The command opens the default browser. Add `--no-open` when a script only needs the returned JSON
|
|
|
|
|
|
URL. Use `visualization-status` and `visualization-stop` to inspect or stop the project viewer.
|
|
|
|
|
|
|
|
|
|
|
|
## Visualization usage
|
|
|
|
|
|
|
|
|
|
|
|
- Left-click a node for its compact descriptor.
|
|
|
|
|
|
- Right-click a node for the full inspector.
|
|
|
|
|
|
- Use **Open source** to read the node’s project-confined source at its anchor.
|
|
|
|
|
|
- Use **Explore neighborhood** to make a node the new focus.
|
|
|
|
|
|
- Use the mouse wheel or viewport buttons to zoom. Drag the canvas to pan. Press Space to center
|
|
|
|
|
|
the selected node.
|
|
|
|
|
|
|
2026-07-25 17:43:41 -04:00
|
|
|
|
### Nodes: bounded neighborhood
|
|
|
|
|
|
|
|
|
|
|
|
**Nodes** answers: “What is immediately related to this thing?”
|
|
|
|
|
|
|
|
|
|
|
|
DocForge starts at the focus and traverses every stored incoming and outgoing relationship up to
|
|
|
|
|
|
the selected depth and fixed edge limit. The graph preserves the relationships exactly as the
|
|
|
|
|
|
index stores them. It does not reinterpret direction or exclude contextual relationships.
|
|
|
|
|
|
|
2026-07-25 18:12:26 -04:00
|
|
|
|
The focus appears at the center. Every other card is categorized by the relationship that explains
|
|
|
|
|
|
its contribution to the focus: Structure, Behavior, Dependency, Execution, Data, Evidence,
|
|
|
|
|
|
Context, or Related. This is the broadest view and is useful for inspecting raw adapter output,
|
|
|
|
|
|
discovering nearby nodes, and choosing a better focus. It can also be the noisiest view because
|
|
|
|
|
|
containment, documentation, dependencies, calls, imports, and other relationship types may all
|
|
|
|
|
|
appear together.
|
2026-07-25 17:43:41 -04:00
|
|
|
|
|
|
|
|
|
|
In Nodes, **Hide node** removes that node and its incident edges from the presentation. It does not
|
|
|
|
|
|
remove other nodes merely because they become disconnected.
|
|
|
|
|
|
|
|
|
|
|
|
### Flow: semantic paths into the focus
|
|
|
|
|
|
|
|
|
|
|
|
**Flow** answers: “What origins and prerequisites lead to this thing?”
|
|
|
|
|
|
|
|
|
|
|
|
Flow builds bounded semantic paths whose destination is the focus. Structural and execution
|
|
|
|
|
|
relationships already aimed at the consumer keep their stored direction. Prerequisite-style
|
|
|
|
|
|
relationships are reversed for presentation so arrows consistently point toward the thing being
|
|
|
|
|
|
explained:
|
|
|
|
|
|
|
|
|
|
|
|
- `defined_in`, `inherits`, and `imports` become definition, base-class, and imported-module
|
|
|
|
|
|
contributions.
|
|
|
|
|
|
- `depends_on` and `reads` become dependency and data-source contributions.
|
|
|
|
|
|
- `tested_by` becomes a test path into the exercised node.
|
|
|
|
|
|
|
|
|
|
|
|
For example, a method can appear as:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
tests package → test module → test class → test method
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The displayed reversal is a visualization rule only. It does not mutate the canonical
|
|
|
|
|
|
relationship or derived index. Context-only relationships such as `documents`, `governs`, and
|
|
|
|
|
|
`relates_to` are omitted so Flow remains a focused origin-to-destination explanation.
|
|
|
|
|
|
|
|
|
|
|
|
### Web: convergence and makeup
|
|
|
|
|
|
|
|
|
|
|
|
**Web** answers: “What makes up this thing, and what paths converge on it?”
|
|
|
|
|
|
|
|
|
|
|
|
Web starts with the same semantic contributor direction as Flow, then includes contextual
|
|
|
|
|
|
relationships that Flow intentionally omits. It can show callers, containers, imports,
|
|
|
|
|
|
dependencies, evidence, documentation context, and other contributors converging on the focus.
|
|
|
|
|
|
It also presents direct relationships owned by the focus as adjacent contributor branches,
|
|
|
|
|
|
including supported `calls`, `contains`, `defines`, `dispatches_to`, `implemented_by`, `launches`,
|
|
|
|
|
|
`writes`, and `activates` relationships.
|
|
|
|
|
|
|
|
|
|
|
|
This makes classes and methods useful graph nodes rather than labels attached to a file. A class
|
|
|
|
|
|
can show its containing module, base class, callers, tests, and methods. A method can show the
|
|
|
|
|
|
package and class path that contains it alongside imported helpers, dependencies, callers, and
|
|
|
|
|
|
evidence. Every displayed path is oriented toward the focused node.
|
|
|
|
|
|
|
|
|
|
|
|
Adjacent traversal is deliberately bounded. After DocForge includes a direct member or execution
|
|
|
|
|
|
dependency owned by the focus, it continues toward that branch rather than fanning back out
|
|
|
|
|
|
through unrelated siblings. Depth and edge limits provide a second guard against an unbounded web.
|
|
|
|
|
|
|
2026-07-25 21:08:43 -04:00
|
|
|
|
### Logic: possible control paths
|
|
|
|
|
|
|
|
|
|
|
|
**Logic** answers: “What decisions and actions can occur inside this function or method?”
|
|
|
|
|
|
|
|
|
|
|
|
Logic appears when the focused node owns a function-scoped `LogicProjection`. It loads that
|
|
|
|
|
|
projection on demand instead of adding statements and conditions to the primary architecture
|
|
|
|
|
|
graph. The view presents:
|
|
|
|
|
|
|
|
|
|
|
|
- **Entry** and **Exit** terminals.
|
|
|
|
|
|
- **Decision** cards for `if`, `elif`, compound booleans, loop conditions, `match` cases, and
|
|
|
|
|
|
assertions.
|
|
|
|
|
|
- **Action** cards for executable statement blocks and calls.
|
|
|
|
|
|
- **Control** cards for loops, `break`, and `continue`.
|
|
|
|
|
|
- **Merge** cards where alternate paths converge.
|
|
|
|
|
|
- **Terminal** cards for returns and raised exceptions.
|
|
|
|
|
|
|
|
|
|
|
|
Edges use explicit labels and independent colors for `TRUE`, `FALSE`, `NEXT`, `CASE`, `LOOP`,
|
|
|
|
|
|
`EXCEPTION`, `RETURN`, `RAISE`, `BREAK`, and `CONTINUE`. Long predicates wrap on the card. The full
|
|
|
|
|
|
expression and source anchor remain available through inspection and source navigation.
|
|
|
|
|
|
|
|
|
|
|
|
Logic is static analysis. It shows paths the indexed source permits, not the branch that ran for a
|
|
|
|
|
|
particular request or the runtime value of a boolean. Dynamic dispatch, reflection, generated
|
|
|
|
|
|
behavior, and values returned by other processes may require runtime tracing to resolve.
|
|
|
|
|
|
|
2026-07-25 18:12:26 -04:00
|
|
|
|
### Reading graph cards
|
|
|
|
|
|
|
|
|
|
|
|
The canvas presents nodes as compact semantic cards rather than anonymous circles:
|
|
|
|
|
|
|
|
|
|
|
|
- **Focus** identifies the node being explained.
|
|
|
|
|
|
- **Structure** identifies packages, modules, classes, methods, definitions, and other containment
|
|
|
|
|
|
paths that establish where the focus exists.
|
|
|
|
|
|
- **Behavior** identifies base classes, derived classes, and implementation relationships.
|
|
|
|
|
|
- **Dependency** identifies imported modules and required services or helpers.
|
|
|
|
|
|
- **Execution** identifies callers, dispatchers, launchers, activators, and focus-owned execution
|
|
|
|
|
|
branches.
|
|
|
|
|
|
- **Data** identifies values or resources read and written.
|
|
|
|
|
|
- **Evidence** identifies tests, verification, governing rules, and documentation.
|
|
|
|
|
|
- **Context** identifies descriptive relationships that do not imply execution or ownership.
|
|
|
|
|
|
- **Related** is the deterministic fallback for adapter-specific relationships that do not fit a
|
|
|
|
|
|
built-in category.
|
|
|
|
|
|
|
|
|
|
|
|
The colored rail, category badge, edge style, and relationship label provide separate visual cues.
|
|
|
|
|
|
Color is not the only signal. Cards also display the node kind, such as `Test class` or
|
|
|
|
|
|
`Test method`.
|
|
|
|
|
|
|
|
|
|
|
|
Canvas cards use the readable leaf name. For example,
|
|
|
|
|
|
`tests.test_settings.SettingsTests.test_default_settings_load` appears as
|
|
|
|
|
|
`test_default_settings_load`, while `tests.test_settings` appears as `test_settings`. Long leaf
|
|
|
|
|
|
names wrap at identifier boundaries instead of being truncated. The complete qualified title and
|
|
|
|
|
|
stable node ID remain available in the pointer tooltip, compact descriptor, and full inspector, so
|
|
|
|
|
|
the shorter canvas label never changes identity or loses information.
|
|
|
|
|
|
|
2026-07-25 17:43:41 -04:00
|
|
|
|
### Hiding nodes and pruning ancestors
|
|
|
|
|
|
|
|
|
|
|
|
Hidden nodes are browser presentation state. Hiding never changes canonical files, the derived
|
|
|
|
|
|
index, or future graph queries. The focus cannot be hidden; focus another node first.
|
|
|
|
|
|
|
|
|
|
|
|
- In **Nodes**, hiding removes only the selected node and its incident edges.
|
|
|
|
|
|
- In **Flow** and **Web**, hiding removes the selected node, then prunes every upstream ancestor
|
|
|
|
|
|
whose only remaining route to the focus passed through it.
|
2026-07-25 21:08:43 -04:00
|
|
|
|
- In **Logic**, hiding removes the selected control-flow step and inserts an `omitted` bridge
|
|
|
|
|
|
between its visible predecessors and successors. This preserves the readable path without
|
|
|
|
|
|
pretending the hidden code disappeared from the indexed source.
|
2026-07-25 17:43:41 -04:00
|
|
|
|
- Descendant nodes between the hidden node and the focus remain visible.
|
|
|
|
|
|
- Ancestors with another valid path to the focus remain visible through that alternate path.
|
|
|
|
|
|
- The status line reports how many nodes were hidden or isolated.
|
|
|
|
|
|
- **Restore hidden** clears the hidden-node set and rebuilds the complete current view.
|
|
|
|
|
|
|
|
|
|
|
|
This behavior lets a user cut away a noisy or irrelevant branch without losing the useful
|
|
|
|
|
|
downstream chain that explains how the remaining nodes reach the focus.
|
2026-07-25 16:00:19 -04:00
|
|
|
|
|
|
|
|
|
|
Source navigation depends on adapter evidence. Numeric anchors, line-style anchors such as `L120`,
|
|
|
|
|
|
TOML `node-N` anchors, heading slugs, and searchable text anchors are recognized. If a custom
|
|
|
|
|
|
adapter supplies only a path or a vague symbol, the source viewer opens the file and falls back to
|
|
|
|
|
|
the closest match or first line.
|
|
|
|
|
|
|
|
|
|
|
|
## CLI usage
|
|
|
|
|
|
|
|
|
|
|
|
Every command emits deterministic JSON:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge --project-root /absolute/path/MyProject <command>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Project and index commands
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
info
|
|
|
|
|
|
validate
|
|
|
|
|
|
build
|
|
|
|
|
|
reindex
|
|
|
|
|
|
check
|
|
|
|
|
|
validate-index
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
- `info` reports the project binding and index health.
|
|
|
|
|
|
- `validate` validates current canonical sources without requiring an index.
|
|
|
|
|
|
- `build` rebuilds the disposable index.
|
|
|
|
|
|
- `reindex` rebuilds and checks the index in one operation.
|
|
|
|
|
|
- `check` and `validate-index` verify that the existing index matches current sources.
|
|
|
|
|
|
|
|
|
|
|
|
### Query commands
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
show NODE_ID
|
|
|
|
|
|
search QUERY [--limit N]
|
|
|
|
|
|
filter [--family X] [--authority X] [--status X] [--tag X] [--limit N]
|
|
|
|
|
|
backlinks NODE_ID [--relation RELATION]
|
|
|
|
|
|
dependencies NODE_ID [--depth N]
|
|
|
|
|
|
impact NODE_ID [--depth N]
|
|
|
|
|
|
context PROFILE [--budget N]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Render and proposal commands
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
render-status [VIEW_ID]
|
|
|
|
|
|
render VIEW_ID
|
|
|
|
|
|
preview CHANGESET_ID VIEW_ID
|
|
|
|
|
|
apply CHANGESET_ID --changeset-hash SHA256 --applier WRITER_ID
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The CLI apply command supports the generic adapter. It verifies that the configured writer owns the
|
|
|
|
|
|
changeset, applies the exact reviewed hash, rebuilds the index, checks it, and regenerates every
|
|
|
|
|
|
declared render. It does not commit or push the result.
|
|
|
|
|
|
|
|
|
|
|
|
### Viewer commands
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
visualize [--node NODE_ID | --query QUERY] [--depth N] [--no-open]
|
|
|
|
|
|
visualization-status
|
|
|
|
|
|
visualization-stop
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## MCP usage
|
|
|
|
|
|
|
|
|
|
|
|
Run one MCP server per project with absolute paths:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-mcp \
|
|
|
|
|
|
--project-root /absolute/path/MyProject \
|
|
|
|
|
|
--proposal-writer project-editor
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Omit `--proposal-writer` when the MCP client should not create or append proposals.
|
|
|
|
|
|
|
|
|
|
|
|
To expose canonical application, add a separate explicit startup gate:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-mcp \
|
|
|
|
|
|
--project-root /absolute/path/MyProject \
|
|
|
|
|
|
--proposal-writer project-editor \
|
|
|
|
|
|
--canonical-applier project-editor
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Without `--canonical-applier`, `docforge_apply_changeset` is not registered. The flag is an
|
|
|
|
|
|
identity, not a command. The changeset creator, configured writer, and canonical applier must agree.
|
|
|
|
|
|
|
|
|
|
|
|
Example MCP client configuration:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"mcpServers": {
|
|
|
|
|
|
"my-project-docforge": {
|
|
|
|
|
|
"command": "/absolute/path/DocForge/.venv/bin/docforge-mcp",
|
|
|
|
|
|
"args": [
|
|
|
|
|
|
"--project-root",
|
|
|
|
|
|
"/absolute/path/MyProject",
|
|
|
|
|
|
"--proposal-writer",
|
|
|
|
|
|
"project-editor",
|
|
|
|
|
|
"--canonical-applier",
|
|
|
|
|
|
"project-editor"
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Read tools
|
|
|
|
|
|
|
|
|
|
|
|
- `docforge_project_info`
|
|
|
|
|
|
- `docforge_get_contract`
|
|
|
|
|
|
- `docforge_get_node`
|
2026-07-25 21:08:43 -04:00
|
|
|
|
- `docforge_get_logic`
|
2026-07-25 16:00:19 -04:00
|
|
|
|
- `docforge_search`
|
|
|
|
|
|
- `docforge_filter_nodes`
|
|
|
|
|
|
- `docforge_backlinks`
|
|
|
|
|
|
- `docforge_dependencies`
|
|
|
|
|
|
- `docforge_impact`
|
|
|
|
|
|
- `docforge_get_context`
|
|
|
|
|
|
- `docforge_validate_project`
|
|
|
|
|
|
- `docforge_render_status`
|
|
|
|
|
|
- `docforge_visualize`
|
|
|
|
|
|
- `docforge_visualization_status`
|
|
|
|
|
|
- `docforge_stop_visualization`
|
|
|
|
|
|
|
|
|
|
|
|
### Proposal tools
|
|
|
|
|
|
|
|
|
|
|
|
- `docforge_create_changeset`
|
|
|
|
|
|
- `docforge_list_changesets`
|
|
|
|
|
|
- `docforge_get_changeset`
|
|
|
|
|
|
- `docforge_propose_node_create`
|
|
|
|
|
|
- `docforge_propose_node_update`
|
|
|
|
|
|
- `docforge_propose_node_move`
|
2026-07-25 19:08:39 -04:00
|
|
|
|
- `docforge_propose_relationship_update`
|
2026-07-25 16:00:19 -04:00
|
|
|
|
- `docforge_propose_node_delete`
|
|
|
|
|
|
- `docforge_validate_changeset`
|
|
|
|
|
|
- `docforge_get_changeset_diff`
|
|
|
|
|
|
- `docforge_preview_changeset`
|
|
|
|
|
|
|
|
|
|
|
|
### Application tool
|
|
|
|
|
|
|
|
|
|
|
|
- `docforge_apply_changeset`
|
|
|
|
|
|
|
|
|
|
|
|
The application call requires `changeset_id` and `expected_changeset_hash`. Always retrieve and
|
|
|
|
|
|
inspect the final diff after the last proposal mutation. Apply that exact hash. A proposal mutation
|
|
|
|
|
|
creates a new hash, so an earlier approval cannot silently apply later content.
|
|
|
|
|
|
|
|
|
|
|
|
Recommended agent sequence:
|
|
|
|
|
|
|
|
|
|
|
|
1. Read the contract and relevant nodes.
|
|
|
|
|
|
2. Create a changeset.
|
|
|
|
|
|
3. Add structured operations using the hash returned by each previous mutation.
|
|
|
|
|
|
4. Validate the changeset.
|
|
|
|
|
|
5. Inspect its structured diff and preview.
|
|
|
|
|
|
6. Obtain human approval for the final changeset hash when required by the client workflow.
|
|
|
|
|
|
7. Call `docforge_apply_changeset` with that exact hash.
|
|
|
|
|
|
8. Report changed canonical files and derived refresh results.
|
|
|
|
|
|
|
2026-07-25 19:08:39 -04:00
|
|
|
|
Use `docforge_propose_relationship_update` when the intended change is only an edge addition or
|
|
|
|
|
|
removal. It uses the same underlying validated update contract, but rejects empty relationship
|
|
|
|
|
|
lists and makes it explicit that node content will remain unchanged.
|
|
|
|
|
|
|
2026-07-25 16:00:19 -04:00
|
|
|
|
Custom adapters may expose the application tool only when they supply a project-owned
|
|
|
|
|
|
`CanonicalApplier`. Core DocForge will not guess how adapter nodes map back to canonical sources.
|
|
|
|
|
|
|
2026-07-25 19:08:39 -04:00
|
|
|
|
## Incremental adapter compilation
|
|
|
|
|
|
|
|
|
|
|
|
Release 1 complete-projection adapters remain supported. Adapters with large source trees can
|
|
|
|
|
|
implement the optional source-scoped manifest and extraction contract. DocForge then fingerprints
|
|
|
|
|
|
sources, reuses unchanged facts, reparses changed sources and their reverse dependents, validates a
|
|
|
|
|
|
complete candidate graph, and publishes the index atomically.
|
|
|
|
|
|
|
2026-07-25 19:21:23 -04:00
|
|
|
|
DocForge detects this capability structurally. An adapter without both `load_manifest()` and
|
|
|
|
|
|
`extract_source()` remains on the Release 1 path. Its behavior and query results are unchanged, but
|
|
|
|
|
|
it does not receive incremental performance until it opts in.
|
|
|
|
|
|
|
2026-07-25 19:08:39 -04:00
|
|
|
|
Build results report cache hits, reparsed sources, invalidated sources, deleted sources, and total
|
|
|
|
|
|
sources. A full projection remains the fallback and equivalence oracle.
|
|
|
|
|
|
|
|
|
|
|
|
Manual proposals remain separate from compilation. Applying an approved changeset updates
|
|
|
|
|
|
canonical sources first. Incremental compilation then notices those changed source fingerprints;
|
|
|
|
|
|
it never treats an unapplied proposal as canonical.
|
|
|
|
|
|
|
|
|
|
|
|
Function-scoped `LogicProjection` data is cached alongside its owning source but remains separate
|
2026-07-25 21:08:43 -04:00
|
|
|
|
from the primary Nodes, Flow, and Web graph. The Logic tab and `docforge_get_logic` load one
|
|
|
|
|
|
function or method on demand without adding every condition and basic block to ordinary graph
|
|
|
|
|
|
traversal.
|
2026-07-25 19:08:39 -04:00
|
|
|
|
|
|
|
|
|
|
See [Incremental Adapter Indexing](INCREMENTAL_INDEXING.md) for the complete contract, cache
|
|
|
|
|
|
invalidation rules, manual-application lifecycle, and lazy Logic boundary.
|
|
|
|
|
|
|
2026-07-25 16:00:19 -04:00
|
|
|
|
## Troubleshooting
|
|
|
|
|
|
|
|
|
|
|
|
### `stale_index` or `visualization_stale`
|
|
|
|
|
|
|
|
|
|
|
|
Canonical sources changed after the index or viewer snapshot was built.
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge --project-root "$PROJECT" reindex
|
|
|
|
|
|
docforge --project-root "$PROJECT" visualize
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
An existing graph browser intentionally stays pinned to its original index identity. Reopen it
|
|
|
|
|
|
after reindexing.
|
|
|
|
|
|
|
|
|
|
|
|
### `visualization_manager_unavailable`
|
|
|
|
|
|
|
|
|
|
|
|
The per-user manager is not installed, is stopped, or points to an old virtual environment.
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-viewer-manager install-user-service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
For diagnosis, run `docforge-viewer-manager serve` in a terminal and retry `docforge visualize`.
|
|
|
|
|
|
|
|
|
|
|
|
### The browser did not open
|
|
|
|
|
|
|
|
|
|
|
|
The command still returns the loopback URL as JSON. Open that URL manually. Desktop-less sessions
|
|
|
|
|
|
should use `--no-open`. Confirm a local browser is registered as the default URL handler.
|
|
|
|
|
|
|
|
|
|
|
|
### `docforge_apply_changeset` is missing
|
|
|
|
|
|
|
|
|
|
|
|
The MCP server was started without `--canonical-applier`, or a custom adapter did not supply a
|
|
|
|
|
|
canonical applier. Restart the MCP server with the explicit gate after deciding that canonical
|
|
|
|
|
|
application is appropriate for that project.
|
|
|
|
|
|
|
|
|
|
|
|
### `canonical_application_disabled`
|
|
|
|
|
|
|
|
|
|
|
|
The CLI/MCP process has no matching configured applier identity. Confirm the ID exists under
|
|
|
|
|
|
`[[changesets.writers]]`, owns the changeset, and is passed exactly to `--applier` or
|
|
|
|
|
|
`--canonical-applier`.
|
|
|
|
|
|
|
|
|
|
|
|
### `changeset_conflict`
|
|
|
|
|
|
|
|
|
|
|
|
The changeset changed after the caller read it. Retrieve the changeset and diff again. Review the
|
|
|
|
|
|
new hash rather than retrying with the old approval.
|
|
|
|
|
|
|
|
|
|
|
|
### `base_conflict`, `content_conflict`, or `proposal_conflict`
|
|
|
|
|
|
|
|
|
|
|
|
- `base_conflict`: canonical sources changed after changeset creation.
|
|
|
|
|
|
- `content_conflict`: a target node no longer has the expected content hash.
|
|
|
|
|
|
- `proposal_conflict`: another active proposal from the same base touches the same node or source.
|
|
|
|
|
|
|
|
|
|
|
|
Do not force apply. Rebase the intended changes into a new changeset after inspecting current
|
|
|
|
|
|
canonical content.
|
|
|
|
|
|
|
|
|
|
|
|
### `application_mismatch`
|
|
|
|
|
|
|
|
|
|
|
|
The written sources did not reproduce the validated projection. DocForge rolls the generic
|
|
|
|
|
|
canonical files back. For a custom adapter, fix its serializer or node-to-source mapping before
|
|
|
|
|
|
retrying.
|
|
|
|
|
|
|
|
|
|
|
|
### `path_escape`, `unsafe_template`, or missing source
|
|
|
|
|
|
|
|
|
|
|
|
DocForge rejects absolute paths, parent traversal, symlink escapes, overlapping canonical and
|
|
|
|
|
|
derived roots, unsafe render outputs, and source files outside the project root. Fix the descriptor
|
|
|
|
|
|
or adapter projection. Do not weaken confinement to make the error disappear.
|
|
|
|
|
|
|
|
|
|
|
|
### Source opens at the wrong place
|
|
|
|
|
|
|
|
|
|
|
|
The source path comes from the node. The anchor comes from the generic source or custom adapter.
|
|
|
|
|
|
Improve the adapter’s `source_anchor` to a line, stable heading, TOML `node-N` anchor, or distinctive
|
|
|
|
|
|
symbol. DocForge can open the file safely, but it cannot infer a perfect code location from
|
|
|
|
|
|
ambiguous adapter evidence.
|
|
|
|
|
|
|
|
|
|
|
|
### Full inspector content does not fit
|
|
|
|
|
|
|
2026-07-25 18:33:42 -04:00
|
|
|
|
DocForge 1.0 uses a fixed header and footer with a scrollable inspector body. If an older page is
|
2026-07-25 21:08:43 -04:00
|
|
|
|
still open, stop and reopen the visualization so it loads the current `graph-browser@16` template.
|
2026-07-25 16:00:19 -04:00
|
|
|
|
|
|
|
|
|
|
### Render output is stale
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge --project-root "$PROJECT" render-status
|
|
|
|
|
|
docforge --project-root "$PROJECT" render VIEW_ID
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Successful canonical apply regenerates all declared views automatically. A manual canonical edit
|
|
|
|
|
|
requires reindexing and rendering.
|
|
|
|
|
|
|
|
|
|
|
|
### Descriptor changed after startup
|
|
|
|
|
|
|
|
|
|
|
|
Long-lived CLI/MCP bindings fail closed if `.docforge/project.toml` changes underneath them. Restart
|
|
|
|
|
|
the process so it binds the new descriptor deliberately.
|
|
|
|
|
|
|
|
|
|
|
|
## Development and verification
|
|
|
|
|
|
|
|
|
|
|
|
Run the complete release gate from the DocForge repository:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
2026-07-25 16:23:23 -04:00
|
|
|
|
npx pyright
|
2026-07-25 16:00:19 -04:00
|
|
|
|
npm run lint:web
|
|
|
|
|
|
uv run ruff check src tests tools
|
|
|
|
|
|
uv run ruff format --check src tests tools
|
|
|
|
|
|
uv run python -m compileall -q src tests tools
|
2026-07-25 16:23:23 -04:00
|
|
|
|
uv run pytest -q
|
2026-07-25 16:00:19 -04:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Project-specific vocabulary, extraction rules, and serialization belong in the project adapter.
|
|
|
|
|
|
Generic core behavior must remain deterministic, project-bound, and recoverable.
|