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

1317 lines
59 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.
This manual describes the DocForge 1.4.0 release. The tagged `v1.0.0` baseline was the first stable
product release. Version 1.4.0 preserves its project-scoped graph, CLI and MCP query
surfaces, hash-approved proposal application, generic and project-owned adapters, declared
rendering, and Nodes/Flow/Web model while adding the maintained incremental, projection, adapter
SDK, recovery, and release proofs documented below.
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.
## 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.
- Relationship-only changeset operations that do not rewrite node content.
- Hash-bound canonical application through both CLI and an explicitly enabled MCP tool.
- Opt-in incremental adapter extraction with reverse-dependency invalidation.
- Lazy function-scoped logic projections that do not densify the primary graph.
- Declared HTML render views. Arbitrary templates, render commands, and output paths are rejected.
- Separate versioned manual and portable graph plans, immutable packages, detached built-in
renderers, and validated receipts.
- Content-addressed portable Nodes/Flow/Web artifacts with receipt-only status and repair.
- Independent manual, portable-graph, and live-viewer policy.
- 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.
- A generic Markdown/TOML adapter plus contracts for deterministic project-owned adapters.
- A public adapter SDK, optional Python/JavaScript/TypeScript/C++ reference integrations, and one
fixed read-only reference MCP binding.
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 / compile context
├── ManualRenderPlanV1 → detached manual renderer → declared manual
├── GraphViewPlanV1 → detached graph renderer → portable Nodes/Flow/Web artifact
└── pinned index → managed live Nodes/Flow/Web/Logic viewer
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.
Generic canonical application compare-and-swaps each target against its exact expected identity.
A concurrent create, update, or delete fails closed, rolls back when the exact displaced state is
still provable, or preserves recovery evidence without overwriting foreign data. Per-file
publication is atomic, but an application spanning several canonical files has no process-death
journal and does not claim crash atomicity across the group.
## Setup
### Requirements
- Python 3.12 or newer.
- [`uv`](https://docs.astral.sh/uv/) for the development environment.
- Node.js and npm for browser asset validation and strict Pyright checking.
Clone and verify DocForge:
```bash
git clone forgejo@repo.andraxion.net:administrator/DocForge2.git /absolute/path/DocForge2
cd /absolute/path/DocForge2
uv sync --group dev
npm ci
npx pyright
npm run lint:web
uv run ruff check src tests tools
uv run ruff format --check src tests tools
uv run pytest -q
```
Use the executables under `/absolute/path/DocForge/.venv/bin/` when DocForge is not installed into
the active shell environment.
For an installed distribution, choose only the language extras the project needs:
```bash
python -m pip install docforge
python -m pip install 'docforge[javascript]'
python -m pip install 'docforge[typescript]'
python -m pip install 'docforge[cpp]'
```
The base wheel contains the Python reference adapter and no Tree-sitter distribution. JavaScript,
TypeScript, and C++ require their matching optional extras. `docforge[languages]` installs all
three optional frontend groups.
Verify the four executable surfaces from the exact installed environment:
```bash
python -m docforge.cli --version
python -m docforge.mcp_server --version
python -m docforge.reference_mcp --version
python -m docforge.viewer_manager --version
```
For version 1.4.0 these report `docforge 1.4.0`, `docforge-mcp 1.4.0`,
`python -m docforge.reference_mcp 1.4.0`, and `docforge-viewer-manager 1.4.0`. Package metadata,
Python imports, generated generic and adapter configurations, and these commands share the same
version authority.
### Configure a reference source project
Reference adapters are a narrow alternative to the generic documentation descriptor. Create
`.docforge/reference-adapter.toml`:
```toml reference-adapter
schema_version = 1
project_id = "my-python-project"
title = "My Python Project"
language = "python"
source_roots = ["src"]
```
Start the fixed read-only server:
```bash
python -I -m docforge.reference_mcp \
--project-root /absolute/path/MyProject \
--capability-mode read
```
For C++, set `language = "cpp"` and add a project-relative
`compilation_database = "compile_commands.json"`. The database is inert bounded inventory; the
reference adapter does not execute its commands or compiler.
The reference integrations publish syntax and local static relationships only. They do not claim
resolved calls, types, inheritance, macro behavior, compiler include semantics, runtime behavior,
or semantic ownership. See [reference adapters](REFERENCE_ADAPTERS.md) for exact evidence and
limitations.
### Assess and onboard an unconfigured project
Run a read-only assessment before writing configuration:
```bash
docforge --project-root /absolute/path/MyProject onboard
```
The result reports detected languages, build evidence, likely documentation, existing
configuration, and capability status. Detection does not claim that a language frontend exists.
Limit the assessment with one or more `--language` options when needed.
Create, index, and render a generic starter manual explicitly:
```bash
docforge --project-root /absolute/path/MyProject onboard \
--language rust \
--scaffold \
--project-id my-project \
--title "My Project"
```
Scaffolding refuses to replace existing target files. It leaves source-graph status at
`adapter_required` until a project integration implements and proves the adapter contract.
See [Project onboarding](PROJECT_ONBOARDING.md) for the complete language-neutral checklist.
Use the [Language Adapter Authoring Guide](ADAPTER_AUTHORING_GUIDE.md) when implementing that
frontend. It covers stable identities, overlapping compiler evidence, deterministic ownership,
normalization, incremental equivalence, failure recovery, and the required proof matrix.
### 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_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
[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 projects 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.
Status separates the worker lifecycle from snapshot freshness. A worker may remain `running` while
`snapshot_state` is `stale`; it will not be reused by the next `visualize` call. `freshness.index`
checks the exact pinned index publication with file identity only. `freshness.source` compares the
cheap project generation when the project can prove one. Unavailable proof is `unknown`, never
silently `current`. Status does not load project content, open SQLite, rebuild the index, or renew
browser activity.
The freshness protocol requires viewer manager version 2. After upgrading an already running
installation, rerun `docforge-viewer-manager install-user-service` or restart the foreground
manager before requesting status.
## Visualization usage
- Left-click a node for its compact descriptor.
- Right-click a node for the full inspector.
- Use **Open source** to read the nodes 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.
### 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.
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.
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.
### 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`.
- **Convergence** cards where alternate paths rejoin, including decision, case, loop-exit, and
exception convergence.
- **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.
The built-in analyzers cover Python, JavaScript, and C++. Python uses the standard-library AST.
JavaScript and C++ use pinned Tree-sitter grammars behind the same language-neutral
`LogicProjection` contract. Tree-sitter handles concrete syntax; DocForge keeps a thin
language-specific control-flow profile for constructs such as conditions, loops, cases,
exceptions, returns, and short-circuit operators. Adding a language therefore requires a grammar
and a semantic profile, not a new visualization or database design.
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.
### Finding the right node
The left panel combines independent filters rather than forcing users to scan the complete node
list:
- **Text** searches indexed titles, summaries, and content.
- **Family** selects the project-defined family.
- **Node type** selects callables or an exact indexed kind such as function, method, class, route,
test, module, or document.
- **Language** selects an indexed language tag such as Python, JavaScript, or C++.
- **Capability** selects nodes with source navigation or an available Logic projection.
Quick presets select common combinations for Logic-ready nodes, Python callables, tests, routes,
and documentation. Filters compose, so `JavaScript` plus `Logic available` lists only JavaScript
functions that can open Logic. Result cards show the readable leaf name, kind, language, path, and
source anchor. Full identities remain in the tooltip and inspector.
Selecting any canvas node highlights its directly connected nodes and the exact edges between
them. Other nodes and edges remain visible at reduced opacity. This local trace works in Nodes,
Flow, Web, and Logic without changing the root or querying a different graph.
### 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.
### 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.
- 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.
- 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.
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>
```
The sections below group common workflows. The implementation-derived list of all 28 current
commands, exact invocations, 36 generic MCP tools, arguments, and input-schema hashes is the
[generated command reference](COMMAND_REFERENCE.md).
### Project and index commands
```text
info
validate
build
reindex
sync
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.
- `sync` checks the index and rebuilds it only when it is missing, stale, or invalid.
- `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] [--limit N]
dependencies NODE_ID [--depth N] [--limit N]
impact NODE_ID [--depth N] [--limit N]
context PROFILE [--budget N] [--limit N] [--cursor OPAQUE]
generation-diff [--limit N] [--cursor OPAQUE]
```
`generation-diff` returns the latest verified primary-graph transition. It is not a history query.
Current results carry a version-1 page, a `receipt_header` bound to the complete stored receipt by
`stored_receipt_hash`, and one top-level pagination cursor. Missing, unsafe, stale, corrupt, or
unprovable disposable evidence is reported as a non-repairing receipt status. The command never
builds or repairs the index.
### Render and proposal commands
```text
render-status [VIEW_ID] [--deep]
render VIEW_ID
graph-plan VIEW_ID
graph-render VIEW_ID
graph-render-status [VIEW_ID]
preview CHANGESET_ID VIEW_ID
apply CHANGESET_ID --changeset-hash SHA256 --applier WRITER_ID
```
`graph-plan` validates and returns one declared `GraphViewPlanV1` without publishing. A portable
view must select exactly one stable `root` or metadata-only lexical `query`. It may use only Nodes,
Flow, or Web as `initial_mode`; portable version 1 excludes function-scoped Logic.
`graph-render` explicitly publishes the declared static artifact, content-addressed renderer
evidence, and generation/view manifest. `graph-render-status` verifies only bounded committed
evidence and never plans or renders. Portable publication is a local CLI action.
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 manual render when manual policy is `auto`. It does not publish portable graphs, commit,
or push the result.
### Viewer commands
```text
visualize [--node NODE_ID | --query QUERY] [--depth N] [--no-open]
visualization-status
visualization-stop
```
### Client configuration and doctor
Preview one deterministic standalone client fragment:
```bash
docforge configure codex --project /absolute/path/MyProject
docforge configure claude --project /absolute/path/MyProject
docforge configure openclaw --project /absolute/path/MyProject
```
Preview is the default. Add `--output /absolute/path/fragment` to create a new private fragment in
an existing real directory. Publication is create-only. DocForge accepts an identical existing
private single-link file as unchanged, but it never merges, replaces, broadens permissions, or
follows a symlink. Descriptor, parent, and target identities are revalidated across the
publication commit.
The generated command uses the exact current Python interpreter with isolated module startup.
Generation first proves that this interpreter can import `docforge.mcp_server`. The result binds
the project root, effective policy, arguments, artifact bytes, and all hashes. It copies no ambient
environment values.
Select authority explicitly:
```bash
docforge configure codex \
--project /absolute/path/MyProject \
--capability-mode proposal \
--proposal-writer project-editor
docforge configure codex \
--project /absolute/path/MyProject \
--capability-mode application \
--proposal-writer project-editor \
--canonical-applier project-editor
```
Read mode is the default. Proposal and application modes fail closed unless the descriptor
declares the named writer, and application requires the same writer/applier identity. Add
`--no-ast` to preserve the no-AST binding. Generic CLI generation refuses project-owned adapters
because it cannot safely reconstruct their composition.
A custom adapter owner supplies the already constructed project and immutable launcher through the
Python API:
```python
from docforge.adapter_launcher import AdapterLauncherV1
from docforge.client_config import generate_adapter_client_configuration
launcher = AdapterLauncherV1.for_project(
project,
module="my_project_docforge",
)
fragment = generate_adapter_client_configuration(
project,
launcher,
"codex",
capability_mode="read",
)
```
The top-level module must be installed for the exact isolated Python environment and resolve to a
regular file inside the project root. The fixed `docforge.reference_mcp` module is the only trusted
dotted exception. Generation probes resolution without importing the custom module, binds current
source availability and policy, and emits no arbitrary command, arguments, working directory, or
environment.
Select projection behavior independently:
```bash
docforge configure codex \
--project /absolute/path/MyProject \
--manual-render-policy explicit \
--portable-graph-policy disabled \
--live-viewer-policy on-demand
```
The generated version-1 configuration result carries an additive version-2 `projection_policy`,
its hash, projection availability, and the exact descriptor hash. Omitted default selectors are
validated against that descriptor rather than trusted as self-reported output.
Inspect one configured client binding:
```bash
docforge doctor --client codex --project /absolute/path/MyProject
docforge doctor --client codex \
--project /absolute/path/MyProject \
--config /absolute/path/config.toml \
--server-name my-project-docforge
```
Doctor returns `healthy`, `degraded`, or `unhealthy` with exit codes 0, 1, or 2. Its fixed
version-1 inventory checks project and descriptor binding, the client driver and entry, executable
and arguments, project root, effective policy, no-AST state, timeouts, environment-key names,
tool-filter representation, and stat-only index presence.
Doctor is intentionally not a connection test. It never loads canonical sources, opens SQLite,
starts MCP, executes the configured command, synchronizes, builds, renders, starts a viewer, or
writes configuration. Claude timeout representation and client filtering that cannot be proved
locally remain explicit warnings.
## Independent projection behavior
Manual and portable graph renderers consume immutable, path-free packages. A package binds one
generation-pinned plan, inert assets, fixed component versions, a built-in renderer identity, and
an exact artifact inventory. The detached child cannot select nodes, open the project or index,
choose a publication path, execute project code, or mutate canonical facts.
Child startup is fixed to isolated Python, a private module entrypoint, a trusted working
directory, and a sanitized environment. One request and response use canonical newline-terminated
JSON. The request, response, receipt, execution time, and disk-spooled stdout are bounded. Actual
artifact transfer is capped at 20,000,000 bytes even when the descriptor retains a larger
`max_render_bytes` compatibility value.
Manual fragment records are disposable semantic cache entries. On a cold miss, DocForge performs a
trusted full detached render, extracts candidate page fragments, and compares fragment-assisted
output byte-for-byte before publishing records. On a warm hit, the worker recomputes each expected
page fragment before accepting cached bytes. Corrupt, forged, stale, individually oversized, or
aggregate-oversized records fall back to the full oracle. Fragment reuse is currently a correctness
and recovery boundary, not a promised speedup.
Projection policy version 2 is:
```text
manual: auto | explicit | disabled
portable_graph: explicit | disabled
live_viewer: on-demand | disabled
```
For ordinary CLI commands, place the corresponding global flag before the subcommand:
```bash
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 returns `projection_policy_forbids_operation` before hidden
work. Manual and portable receipt-only status remain available. Viewer status and explicit stop
remain available when viewer start is disabled.
A non-disabled projection also requires its declared configuration or runtime. Manual `explicit`
requires manual render configuration. Manual `auto` additionally requires canonical application in
the current operation or server capability. Portable graph `explicit` requires portable graph
render configuration, and live viewer `on-demand` requires its runtime. An unavailable selection
returns `projection_policy_unavailable` before work begins. In particular, ordinary CLI `render`
operations cannot select manual `auto`; use `explicit`, or let a configured canonical `apply`
operation own automatic regeneration.
## 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.
For `.docforge/reference-adapter.toml`, use the fixed `docforge.reference_mcp` command shown in
[setup](#configure-a-reference-source-project). It exposes exactly the 21 read tools and never
registers proposal or application tools.
Select the session's declared surface explicitly when useful:
```bash
docforge-mcp \
--project-root /absolute/path/MyProject \
--capability-mode read \
--manual-render-policy explicit \
--portable-graph-policy explicit \
--live-viewer-policy on-demand
```
Supported modes are `read`, `proposal`, `application`, and `operator`. Existing startup defaults
remain compatible. Capability mode describes the registered surface; bootstrap separately reports
whether a configured writer or applier actually grants mutation access. Application mode refuses
startup without a canonical applier. Operator mode is reserved and currently adds no tools.
Add `--diagnostics` when profiling a development or benchmark session. Each MCP response then
includes bounded stage timings and compiler-work counters. The same flag is available on
`docforge`. Diagnostics are disabled by default, record no project content or paths, and never
displace a primary MCP result that already needs the configured output budget.
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. Generic CLI and MCP application require the changeset creator, configured
writer, and canonical applier to agree.
A project-owned adapter server can separately pass `accepted_proposal_writers` to
`create_project_server`. This explicit allowlist lets its startup-bound applier accept an exact
reviewed changeset from another configured contributor identity. The default remains the applier
identity only. Accepted contributors retain their original proposal permissions and do not receive
canonical application authority.
Call `docforge_bootstrap` first. Its version-1 `session_contract` contains the fixed binding,
current graph generation, effective policy, actual capabilities, render policies, prohibitions,
and a recommended first operation. The result also carries the independently composed version-2
`projection_policy` and hash. Workflow guidance does not recommend registration or application
when those startup capabilities are unavailable.
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_bootstrap`
- `docforge_sync`
- `docforge_project_info`
- `docforge_get_contract`
- `docforge_get_node`
- `docforge_get_logic`
- `docforge_search`
- `docforge_filter_nodes`
- `docforge_backlinks`
- `docforge_dependencies`
- `docforge_impact`
- `docforge_get_context`
- `docforge_get_task_context`
- `docforge_validate_project`
- `docforge_render_status`
- `docforge_graph_plan`
- `docforge_graph_render_status`
- `docforge_visualize`
- `docforge_visualization_status`
- `docforge_stop_visualization`
- `docforge_get_generation_diff`
MCP graph plan and status are read-only. MCP does not expose portable graph publication; use the
explicit local `graph-render` CLI command.
### Proposal tools
- `docforge_create_changeset`
- `docforge_register_changes`
- `docforge_list_changesets`
- `docforge_get_changeset`
- `docforge_rebase_changeset`
- `docforge_abandon_changeset`
- `docforge_propose_node_create`
- `docforge_propose_node_update`
- `docforge_propose_node_move`
- `docforge_propose_relationship_update`
- `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.
Use `docforge_get_task_context` when an agent needs one bounded task-shaped intake instead of a
named profile. Choose `task_kind` from `change`, `implementation`, `failure`, `ownership`, `test`,
`operation`, or `release`. Supply `focus_node_id` when the stable node is known. Without it,
DocForge performs a bounded lexical focus search and refuses a tied best match instead of silently
choosing one.
The returned version-1 capsule includes:
- The exact project, adapter, source generation, effective policy, request, and retrieval-plan
hashes.
- Ordered focus and related evidence with source paths, content hashes, graph paths, and all
qualifying relationship reasons observed during the bounded traversal.
- Explicit evidence gaps and omissions, including whether a check completed.
- Provenance limitations for facts that the current graph does not carry, such as extractor
identity, observation time, and source provenance for relationships.
Project descriptors still own the valid relation vocabulary. The planner recognizes a fixed alias
map for structure, implementation, dependency, execution, data, evidence, and context. Any other
valid project relation is returned unchanged as `unclassified`; it is never assigned guessed task
semantics.
A relationship inside `relationship_path` describes the direction traveled from the preceding
node. A relationship inside `relationship_reasons` describes direction from the evidence item
itself. This keeps stored source and target identity exact while making each evidence explanation
locally readable.
Task context never exceeds 1,000 evidence items, 100,000 examined candidate edges, or 10,000 task
query characters, even when a project configures broader general limits. An edge-work or
unclassified-relation ceiling appears as an explicit omission rather than an unbounded response.
Use `docforge_get_generation_diff` after synchronization or a completed implementation slice to
inspect the one latest verified primary-graph transition. The version-1 receipt reports exact
added, removed, and changed node counts plus added and removed edge counts. Retained node details
identify changed fields and before/after hashes and source paths. Edge details retain the exact raw
relation triple. The receipt stores no source text, rendered content, Logic identities, or
historical sequence.
The first successful publication is an explicit baseline and does not claim every current node was
added. A corrupt, foreign, unsafe, or unavailable predecessor produces an unavailable comparison
rather than fabricated removals. A same-generation reindex preserves the latest meaningful
transition. Each later real transition atomically replaces the single disposable receipt.
Generation-diff reads use only the bounded receipt, stable file identities, and an adapter's cheap
source-generation proof. They do not open SQLite, load a complete adapter projection, parse source,
synchronize, build, or repair. Legacy adapters without cheap identity report `unknown`. Missing,
corrupt, foreign, oversized, or concurrently changed receipts report an explicit receipt state and
do not trigger hidden recovery.
Recommended release-candidate sequence:
1. Call `docforge_bootstrap`. It synchronizes derived state and reports the exact fixed binding.
2. Read only the relevant canonical context, implementation, configuration, tests, and release
rules.
3. Record the expected documentation impact in the working plan. Do not create or apply a
changeset yet.
4. Implement and run focused checks iteratively. Canonical documentation remains read-only during
this loop.
5. Freeze one release candidate after implementation stops changing.
6. Run the complete project gate, deployment preflight, candidate deployment, live checks, data
integrity checks, and release-identity checks.
7. If candidate validation fails, return to implementation. Do not document the failed candidate.
8. Call `docforge_sync` once after the candidate is green.
9. Call `docforge_register_changes` once with the complete operation list for every affected
canonical node.
10. Inspect the structured diff and every required preview.
11. Obtain human approval for the final changeset hash when required by the client workflow.
12. Call `docforge_apply_changeset` with that exact hash.
13. Run documentation-only validation and render checks.
14. Call `docforge_bootstrap` to verify the new canonical and derived identity.
15. Commit, tag, and publish the final revision containing both the verified implementation and
canonical documentation.
This cadence separates documentation intake from documentation publication. It avoids repeatedly
rewriting the manual around intermediate implementation states. One second documentation write is
allowed only for a narrow evidence correction that could not exist before deployment. If a late
check exposes an implementation defect, abandon or rebase the pending proposal and return to the
implementation loop.
The older create-and-append tools remain supported for interactive proposal construction.
`docforge_register_changes` avoids intermediate empty changesets and caller-managed hash chaining.
For update, move, and delete operations it captures the synchronized current node hash when
`expected_content_hash` is omitted.
MCP mutations are preflighted against the configured response limit. Small mutations keep their
full response. Large successful mutations return a compact or minimum version-1 receipt with
`mutation_committed = true` and the exact current changeset hash. A preflight size failure has
`mutation_committed = false`; it is safe to correct the request or policy before retrying. A
committed mutation is never reported as `result_too_large`.
Active changeset listing includes draft and ready proposals. Stale work remains available through
an explicit `status="stale"` query for rebase decisions. Applied and abandoned proposals are
terminal history, remain available by status or history request, and no longer block new proposals
against the same canonical base.
Context and changeset reads use version-1 continuation receipts when their evidence exceeds one
page. Follow `pagination.next_cursor` with the same tool and semantic arguments until
`pagination.has_more` is false. Page size may change between calls. Treat the cursor as opaque.
It is bound to the project, adapter, source generation, query, exact changeset hash, and collection
identity. `stale_cursor` means evidence changed between pages; discard prior pages and restart the
read instead of mixing generations.
`docforge_get_context` paginates one ordered evidence stream: selected entries followed by explicit
omissions. An entry too large for one MCP response is represented by a bounded omission carrying
its node ID and detail hash, and the cursor advances. `docforge_list_changesets`,
`docforge_get_changeset`, `docforge_validate_changeset`, and `docforge_get_changeset_diff` accept
the same optional `limit` and `cursor` fields. Small results keep their familiar fields. Large
inspection pages may use hash summaries. A large diff may return `result_mode =
"canonical_json_chunk"`; concatenate the chunks in order and verify `payload_hash` before decoding
the reconstructed `operations` and `changes` object.
`docforge_get_task_context` uses the same opaque continuation discipline over capsule evidence
followed by capsule omissions. Keep the semantic task arguments unchanged while paging. Page size
may change. Every page retains the same plan, collection, and capsule hashes. A `stale_cursor`
means that the generation, policy, plan, or collection changed; discard earlier pages and restart.
`docforge_get_generation_diff` paginates only the details retained in the latest bounded receipt.
Its summary counts and full collection hash still cover permanently truncated details. The cursor
binds the exact receipt, target generation, retained and full collection hashes, receipt state, and
effective policy. A replacement receipt returns `stale_cursor`; restart from its first page.
Canonical application records its terminal receipt immediately after the project-owned serializer
verifies the new canonical state. A later index or render refresh failure is reported as degraded
derived state with remediation, not as permission to apply the same canonical change again.
Likewise, failure to remove a private transaction artifact after semantic commit returns
`applied`, closes the proposal, and persists compact `application_recovery` lifecycle metadata
with `cleanup_required`, retained paths, and remediation. Inspect and remove only files proven to
be DocForge-owned.
Every successful declared render publishes a bounded version-1 receipt below the disposable cache.
Normal `render-status` compares cheap source-generation, view-configuration, template-file, and
output-file identities. It does not parse canonical nodes, prepare Markdown, construct HTML, or
hash the complete output. Missing or corrupt receipts are `unverified`; changed sources, templates,
or outputs are `stale`. Use `render-status --deep` only when explicitly requesting the
side-effect-free full-render equivalence oracle.
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.
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.
## 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.
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.
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
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.
See [Incremental Adapter Indexing](INCREMENTAL_INDEXING.md) for the complete contract, cache
invalidation rules, manual-application lifecycle, and lazy Logic boundary.
### Preserving an older non-AST adapter
Use `--no-ast` on the MCP binding when the project owner wants the existing adapter preserved
without AST, Tree-sitter, compiler-AST, or function-Logic upgrades:
```bash
docforge-mcp --project-root /absolute/project --no-ast
```
For a project-owned server, pass `no_ast=True` to `create_project_server()` or
`create_read_only_server()`. Bootstrap and contract responses then expose
`mode=preserve-no-ast`. The Logic tool is blocked, and DocForge refuses to publish nonempty Logic
projections.
This policy does not disable the Release 1 `load_projection()` path. It also permits incremental
fingerprinting and caching when those mechanisms do not add AST analysis. The adapter can
therefore benefit from current synchronization, proposals, application, rendering, and graph tools
without a source-analysis rewrite.
The binding rejects a pre-existing index containing Logic before reads or live visualization. A
configured canonical application service also refreshes through the same no-AST index policy.
DocForge does not inspect arbitrary adapter source to prove which parsing library it uses, so
repository permissions and project instructions remain responsible for adapter implementation
changes outside this process boundary.
## Troubleshooting
### `optional_dependency_missing`
Install the exact extra named in the error into the same Python environment that starts DocForge:
```bash
python -m pip install 'docforge[javascript]'
python -m pip install 'docforge[typescript]'
python -m pip install 'docforge[cpp]'
```
Do not install every frontend merely to suppress the check. A missing optional parser is a closed,
actionable capability error and does not affect base generic or Python reference operation.
### `adapter_launcher_unavailable` or `invalid_adapter_launcher`
Use one installed top-level Python module whose resolved regular-file origin is inside the project
root, or use the fixed `docforge.reference_mcp` binding. Arbitrary dotted modules, packages,
stdlib modules, missing modules, commands, argument strings, working directories, and environment
injection are rejected. Test the exact generated fragment rather than editing its command by hand.
See [agent integration](AGENT_INTEGRATION.md) and the [security model](SECURITY.md).
### `adapter_restart_required`
The project-local adapter code, its declared descriptor, or another implementation file changed
after the project-bound MCP process started. DocForge rejects every further operation before
synchronization because the live Python objects still represent the prior implementation.
Restart the MCP server or start a fresh client session. Do not stage files merely to change the
adapter's source manifest, and do not attempt in-process module reloading. The error includes
bounded added, changed, and deleted path evidence to identify the changed implementation boundary.
### `stale_index` or `visualization_stale`
Normal MCP operations automatically repair a missing, stale, or invalid disposable index under a
project lock. `docforge_sync` can be called explicitly to inspect whether synchronization was a
no-op or rebuild. The CLI equivalent is:
```bash
docforge --project-root "$PROJECT" sync
docforge --project-root "$PROJECT" visualize
```
An existing graph browser intentionally stays pinned to its original index identity. Reopen it
after synchronization or reindexing.
Every complete index build also writes a disposable whole-file SHA-256 attestation. A new MCP
process verifies the unchanged database against that receipt instead of reconstructing every graph
row. Missing or mismatched receipts fall back to complete verification and are recreated only after
the full check succeeds.
Milestone 5 maintains exact recovery for four corrupt derived artifacts. Synchronization restores
a corrupt index attestation after complete verification. Explicit `render` restores a corrupt
manual receipt to the exact output and receipt semantics. A complete `reindex` recreates a corrupt
generation-diff baseline against the exact current graph. Explicit `graph-render` recreates a
corrupt portable-graph manifest and exact artifact. Status operations diagnose these conditions
without hidden repair.
### `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. Call `docforge_rebase_changeset` with the exact current changeset hash. DocForge
will rebind it only when every touched fact is unchanged and the proposal still validates. A
content or relationship conflict remains fail-closed and requires a newly reviewed proposal.
### `application_mismatch`
The written sources did not reproduce the validated projection. During an ordinary in-process
failure, DocForge rolls generic canonical files back when their exact publication identities are
still provable. If another process raced a target, DocForge preserves foreign and displaced data
and returns `application_recovery_required` rather than overwriting either. For a custom adapter,
fix its serializer or node-to-source mapping before retrying.
### `application_recovery_required` or `cleanup_required`
`application_recovery_required` means canonical publication or rollback encountered concurrent or
unprovable state. Preserve every retained file named in the error. Compare it with the canonical
target and resolve the project before creating a newly reviewed proposal. Do not retry the old
approved hash.
`cleanup_required` means semantic application already committed. The proposal is closed as
`applied`, and its lifecycle receipt names private transaction artifacts that could not be removed.
Inspect those files and remove only confirmed DocForge-owned artifacts. The canonical change must
not be applied again.
Generic application uses mode-0700 transaction directories, but DocForge is not a filesystem
sandbox. Deliberate arbitrary tampering by another process running as the same operating-system
user is outside that integrity boundary. A process or host death can also interrupt a multi-file
application because canonical application has no process-death journal.
### `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 adapters `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
DocForge 1.4 uses a fixed header and footer with a scrollable inspector body. If an older page is
still open, stop and reopen the visualization so it loads the current `graph-browser@17` template.
### Render output is stale
```bash
docforge --project-root "$PROJECT" render-status
docforge --project-root "$PROJECT" render VIEW_ID
```
Successful canonical apply regenerates declared manual views only when manual policy is `auto`.
A manual canonical edit requires reindexing and explicit rendering. Portable graph publication
always remains a separate explicit CLI action.
Portable graph publication has separate status and policy:
```bash
docforge --project-root "$PROJECT" graph-render-status
docforge --project-root "$PROJECT" graph-render architecture
```
### `projection_policy_forbids_operation`
The process was deliberately started with the relevant manual, portable-graph, or live-viewer
operation disabled. Restart with an allowed selector after confirming that the integration should
receive that capability. Status and explicit stop operations remain available as described above.
### `projection_policy_unavailable`
The selected non-disabled projection has no matching project configuration or runtime. Add the
declared manual or portable graph render configuration, or make the live viewer runtime available,
before selecting that mode. Manual `auto` also requires an operation or MCP server with canonical
application enabled. Use manual `explicit` for a standalone CLI render.
### 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 ordinary repository gate:
```bash
make gate
```
Use `make benchmark` for the historical Milestone 0 baseline, `make benchmark-m1` for the
counter-gated warm-operation benchmark, `make benchmark-m2` for agent workflow gates, and
`make benchmark-m3-full` for the ten-sample 1,000-node projection, worker, fragment, status,
equivalence, response-size, and memory gates. `make benchmark-m4-full` runs the 1,002-node adapter
and recovery benchmark. `make adoption-m4` performs the offline fresh-wheel proof.
`make command-reference-check` rejects command-reference drift, and `make docs-check` validates
the maintained documentation graph. `make accessibility` runs the generated manual, portable
graph, and live viewer axe and keyboard flows.
Milestone 5 adds maintained compatibility, migration, concurrency, recovery, comparative-task,
release-identity, reproducible-artifact, secret-scan, and fresh-clone gates:
```bash
make compatibility-m5
make migration-m5
make concurrency-m5
make recovery-m5
make task-evidence-m5
make release-gate
make fresh-clone-m5
```
`release-gate` aggregates the full quality, browser, compatibility, migration, concurrency,
recovery, task-evidence, fresh-wheel, version, artifact, secret-scan, and benchmark suite.
`fresh-clone-m5` anonymously clones the exact published candidate over HTTPS, fetches and verifies
the frozen annotated `v1.0.0` migration tag, and repeats `release-gate`. Release operators use
`make release-pretag` before creating `v1.4.0` and `make release-posttag` after the annotated tag
points to the exact release commit.
Project-specific vocabulary, extraction rules, and serialization belong in the project adapter.
Generic core behavior must remain deterministic, project-bound, and recoverable.