1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages

Add gated changeset application and graph controls

This commit is contained in:
Andraxion 2026-07-25 16:00:19 -04:00
parent 3c15e26283
commit 78335c8973
20 changed files with 1813 additions and 453 deletions

View file

@ -1,62 +1,47 @@
# Canonical application decision
**Status:** DFG-9 complete.
**Status:** Superseded by the DocForge 0.13 hash-bound application contract.
**Decision:** DocForge does not apply changesets to canonical project files. Accepted proposals are
manually integrated through the owning project's established source, build, test, and Git workflow.
This is the permanent DocForge 0.x policy, not a deferred implementation item.
## Decision
## Evidence
DocForge may apply one isolated changeset to canonical project sources through an explicit,
project-bound canonical applier. Application is available through both CLI and MCP. It is never an
implicit consequence of validation, diffing, previewing, or rendering.
DFG-8 produced one real AssetForge proposal. DocForge automated source-hash checks, writer scope,
changeset storage, conflict detection, project validation, structured diffing, and escaped preview
rendering. The remaining integration step was one reviewed content replacement in one existing
Markdown chapter. That step completed without an integration failure, lost work, or material delay.
The generic adapter owns a deterministic Markdown/TOML serializer. Custom adapters must provide a
project-owned `CanonicalApplier`. Core DocForge does not guess how adapter nodes map back to source
files.
There is no recorded evidence of repeated manual-integration errors, costly multi-file application,
or another project requiring canonical application. A generic application command would therefore
add more authority and failure handling than the observed workflow needs. It would require:
## Authorization
- project-specific Markdown and TOML writers instead of the current read and validation adapters;
- atomic rollback across every affected canonical file;
- recovery when source application succeeds but a project build or validation later fails;
- a developer authorization boundary that cannot be reached through MCP or an agent writer;
- exact handling for create, move, delete, metadata, relationship, and manifest ownership; and
- new cross-project proof that the generic core does not assume Worldforge source semantics.
- CLI requires `apply CHANGESET_ID --changeset-hash SHA256 --applier WRITER_ID`.
- MCP registers `docforge_apply_changeset` only when the server starts with an explicit canonical
applier identity and compatible applier implementation.
- The changeset creator and applier identity must match a configured proposal writer.
- The exact final changeset hash is required. Any proposal mutation invalidates an earlier
approval.
Adding those capabilities to remove one deliberate copy step would weaken the existing ownership
boundary without measured benefit.
## Application boundary
## Permanent boundary
Application revalidates the canonical base, node hashes, graph, permissions, conflicts, target
paths, and projection. Generic writes are staged, confined to declared content roots, and rolled
back if the result does not reproduce the approved projection. Successful application rebuilds and
checks the derived index and regenerates declared render views.
DocForge may read canonical sources and write only configured indexes, changesets, previews, and
declared derived renders. It may validate, diff, and preview a proposed graph. It does not write,
rename, or delete canonical sources through its library, CLI, or MCP server.
Application does not run project commands, tests, shell operations, Git, deployment, publication,
or arbitrary renderers. Those remain with the owning project workflow.
The developer or project owner retains these actions:
## Why the earlier decision changed
1. review the complete changeset diff and preview;
2. confirm the current canonical source and base hashes still match;
3. manually integrate only the accepted content through the project's canonical source owner;
4. run the project's builder, index refresh, tests, and generated-output checks; and
5. inspect, commit, push, deploy, or publish through the project's normal workflow.
The earlier DFG-9 decision preserved manual integration because there was not yet repeated evidence
for canonical application. Later multi-project use produced recurring proposal application work,
stale-index round trips, and an explicit user requirement for faster approved integration. The new
contract addresses the original safety concerns with:
If canonical state changes before integration, the proposal must be refreshed or recreated. A
developer must not bypass a stale or conflicting changeset by applying it mechanically.
## Reopening criteria
DFG-9 is closed. Canonical application may be reconsidered only through a new explicitly approved
gate with measured evidence of repeated integration failures or meaningful repeated work across
more than one project. That gate must define source-format ownership, developer authorization,
atomic rollback, failure recovery, compatibility, and complete cross-project proof before code is
written. It must not add an MCP application tool.
## Proof
- The MCP protocol test asserts the exact tool list and rejects any tool name containing `apply`,
`commit`, `push`, `deploy`, `publish`, or `shell`.
- Proposal and adapter tests prove canonical source bytes remain unchanged during create, validate,
diff, preview, conflict, and stale-source operations.
- DFG-8 completed a real reviewed proposal through manual integration and the Worldforge canonical
builder without an application command.
- exact changeset-hash approval;
- startup-bound applier identity;
- project-owned serializers for custom adapters;
- canonical path and symlink confinement;
- rollback and semantic round-trip verification;
- deterministic derived-state refresh; and
- complete separation from Git, builds, deployment, and publication.

View file

@ -1,4 +1,4 @@
# DocForge 0.12 contract
# DocForge 0.13 contract
## Authority boundary
@ -6,15 +6,11 @@ DocForge is bound to one explicit project root. Canonical project files own docu
Indexes, query results, context packs, changesets, previews, and renders are derived artifacts.
The generic core validates and retrieves canonical nodes. A project-bound proposal service writes
only isolated changesets. Canonical application, project builds, Git mutation, deployment, and
publication remain external integration actions. Passive revision detection may read the current Git
isolated changesets. A separately gated canonical application service may apply one exact,
hash-approved changeset through a generic or project-owned serializer. Project builds, Git mutation,
deployment, and publication remain external. Passive revision detection may read the current Git
commit when Git is available; it cannot change repository state.
DFG-9 made manual canonical integration the permanent DocForge 0.x policy. The library, CLI, and
MCP server do not apply changesets to canonical files. Reconsidering that boundary requires a new
approved contract and measured cross-project evidence; it is not an unimplemented 0.x feature. See
`APPLICATION_DECISION.md`.
## Versioned contracts
- Project descriptor schema: `schemas/project.schema.json`, version 1.
@ -23,7 +19,7 @@ approved contract and measured cross-project evidence; it is not an unimplemente
- Result envelope: `schemas/result.schema.json`, version 1.
- Changeset schema: `schemas/changeset.schema.json`, version 1.
- Index schema: version 1, disposable and reproducible.
- Core, CLI, and MCP server: version 0.12.0.
- Core, CLI, and MCP server: version 0.13.0.
Schema files describe the generic interchange contract. Runtime validation remains responsible for
path confinement, source hashing, relationship resolution, dependency cycles, project limits, stale
@ -49,8 +45,8 @@ if canonical source no longer matches the derived index.
Create, update, move, and delete are ordered node operations inside an isolated changeset. Every
operation names its expected base hash. A move preserves the stable node ID. A delete must resolve
every incident relationship. Proposal validation and storage are atomic. Canonical application
remains external, and prose is never auto-merged.
every incident relationship. Proposal validation and storage are atomic. Application requires the
exact final changeset hash; prose is never auto-merged.
The MCP process binds to one configured writer identity at startup. The project descriptor grants
that writer explicit families and operation types. A changeset records its creator, project root
@ -80,9 +76,10 @@ changeset only to its isolated preview path. Status recomputes expected output w
reports `current`, `stale`, `missing`, `unsafe`, or `oversized`. Input changes detected before atomic
replacement fail without replacing the prior output.
Normal MCP access does not expose canonical application, declared project-output rendering,
arbitrary renderer execution, arbitrary file writes, shell commands, Git mutation, build commands,
deployment, or publication.
Normal MCP access does not expose canonical application. An explicitly configured canonical
applier registers one hash-bound application tool. No MCP mode exposes arbitrary renderer
execution, arbitrary file writes, shell commands, Git mutation, build commands, deployment, or
publication.
## Project-bound graph visualization
@ -102,11 +99,12 @@ random token is part of every accepted URL path. Only `GET` and `HEAD` are suppo
no-store caching, a restrictive content-security policy, frame denial, MIME sniffing protection,
and no-referrer policy. The built-in template uses only same-origin JSON endpoints for graph
overview, bounded search, exact descriptor-category filtering, exact node content, bounded
incoming-and-outgoing neighborhoods. Descriptor filtering accepts only
incoming-and-outgoing neighborhoods, and one node's bounded project-confined source file.
Descriptor filtering accepts only
family, authority, status, or tag plus one exact value. There is no write endpoint, arbitrary query
endpoint, static filesystem handler, external asset, or project-selection control.
The `graph-browser@11` template provides mouse-wheel zoom centered on the pointer, left-button drag
The `graph-browser@12` template provides mouse-wheel zoom centered on the pointer, left-button drag
pan, explicit zoom-in and zoom-out buttons, a reset-view button, and a live zoom percentage. A
four-pixel drag threshold defers pointer capture and preserves node activation for ordinary clicks.
Loading another root node fits the viewport to the returned neighborhood, including a useful
@ -123,8 +121,11 @@ status, and tag pills are buttons that replace the left result list with exact m
Right-clicking or pressing Shift+Enter opens the complete inspector. Inspection does not replace
the current neighborhood or reset the viewport. Both dialogs support Escape, explicit close
controls, and backdrop dismissal. Loading the inspected node as the new root requires the separate
Explore neighborhood action. Both side panels support pointer and keyboard resizing. The unblurred
full inspector supports native resizing and constrained title-bar dragging.
Explore neighborhood action. Non-focus nodes may be hidden from the presentation and restored
without mutating graph state. Source actions open the project-confined source and navigate to
supported line, TOML, heading, or text anchors. Both side panels support pointer and keyboard
resizing. The unblurred full inspector supports native resizing, constrained title-bar dragging,
and a fixed header/footer surrounding a scrollable body.
The header exposes a Nodes/Flow segmented selector. Nodes displays the complete bounded
neighborhood. Flow displays an upstream lineage ending at the current root. Calls, dispatches,
@ -185,5 +186,6 @@ project semantics that the generic core cannot infer. Generic projects retain th
and TOML source-layout validator.
An explicit integration may construct the full fixed MCP surface for a configured adapter project
and one startup-bound writer. This does not add adapter discovery or canonical application. An
adapter without proposal settings or validation remains read-only.
and one startup-bound writer. Canonical application is registered only when the integration also
supplies a startup-bound applier identity and project-owned `CanonicalApplier`. An adapter without
proposal settings or validation remains read-only.

View file

@ -6,6 +6,10 @@ configured `--proposal-writer`. It opens no network listener at startup. The exp
`docforge_visualize` read tool may start one token-protected loopback-only HTTP listener for the
same immutable project binding.
Canonical application is a second independent startup gate. The generic server accepts
`--canonical-applier WRITER_ID`. A project adapter must also supply a compatible project-owned
canonical applier implementation.
## Read tools
- `docforge_project_info`
@ -33,8 +37,9 @@ partitioning, and custom context policy remain outside the DocForge core.
An explicit project integration may construct the full fixed surface only after supplying a
confined proposal policy and startup-bound writer. Adapter proposal validators may narrow the
writer's declared operations further. They cannot add tools, weaken core changeset validation, or
enable canonical application.
writer's declared operations further. They cannot add arbitrary tools or weaken core changeset
validation. The fixed application tool is registered only through the separate canonical applier
gate.
## Isolated proposal tools
@ -54,6 +59,20 @@ change canonical files or declared project output. Without `--proposal-writer`,
tools return `proposal_access_disabled`. Validation, diff retrieval, and preview remain available
for existing changesets. A preview accepts a declared view ID, not a renderer name or command.
## Canonical application tool
- `docforge_apply_changeset`
The tool is absent unless canonical application was explicitly enabled at startup. It accepts one
changeset ID and the exact final changeset SHA-256. It revalidates the current canonical base,
proposal ownership, node hashes, conflicts, graph, permissions, and paths before invoking the
configured serializer.
The generic serializer confines staged Markdown/TOML writes to declared content roots and verifies
that the applied files reproduce the approved graph projection. A mismatch rolls canonical files
back. A successful apply rebuilds and checks the derived index and regenerates all declared render
views. It does not run project commands, shell, Git, builds, deployment, or publication.
## Render boundary
`docforge_render_status` recomputes expected hashes without writing. `docforge_preview_changeset`
@ -63,13 +82,14 @@ only through the explicit local CLI integration command.
## Visualization boundary
`docforge_visualize` starts the fixed built-in `graph-browser@11` template against the currently
`docforge_visualize` starts the fixed built-in `graph-browser@12` template against the currently
validated derived index. It may focus one stable node, run one bounded lexical query, or open the
project overview. The tool returns a loopback URL and exact snapshot identity.
The tool cannot select a project, database, template, host, port, filesystem path, or SQL
expression. Its HTTP surface is token-bound, read-only, same-origin, and limited to overview,
search, exact family/authority/status/tag filtering, and node-neighborhood JSON. The browser
search, exact family/authority/status/tag filtering, node-neighborhood JSON, and a bounded
project-confined source read for one indexed node. The browser
exposes an exact validated index snapshot. It rejects index
replacement or alteration and requires another MCP invocation to refresh.
Viewport interaction is entirely client-side: fitted neighborhood framing, wheel zoom, left-button
@ -77,7 +97,9 @@ drag pan, explicit zoom buttons, reset, and Space-to-center selection never requ
project data. Left activation visibly selects the node and opens a compact descriptor card.
Right-click opens the full inspector. Descriptor-pill activation fills the fixed left panel with an
exact bounded category result set. The fixed right panel contains neighborhood navigation.
Replacing the current root requires an explicit Explore neighborhood action. Nodes presents the
Replacing the current root requires an explicit Explore neighborhood action. Users may hide
non-focus nodes and restore them entirely client-side. Source actions open the indexed source path
and navigate to recognized anchors. Nodes presents the
bounded neighborhood with relation-specific colors, line patterns, directional symbols, and a
visible key. Its navigation groups the focus, nodes reachable through outgoing edges, and remaining
incoming or lateral context. Flow presents the same bounded snapshot as an upstream lineage.
@ -92,14 +114,10 @@ worker only after one hour with no browser activity.
## Excluded tools
The normal server never exposes shell execution, arbitrary reads or writes, canonical changeset
application, declared project-output rendering, arbitrary renderer execution, Git mutation, project
builds, deployment, publication, external HTTP binding, global project selection, or cross-project
retrieval.
DFG-9 permanently retained manual canonical integration for DocForge 0.x. No application tool is
planned for MCP. A future local developer workflow may be considered only through a new approved
contract, and it must not make canonical application reachable from an MCP writer.
The normal server never exposes shell execution, arbitrary reads or writes, arbitrary renderer
execution, Git mutation, project builds, deployment, publication, external HTTP binding, global
project selection, or cross-project retrieval. Without the explicit canonical applier gate, it also
does not expose canonical application.
DocForge pins the official stable Python MCP SDK to the compatible `mcp>=1.28,<2` release line.
Migration to a later major release requires a separate contract and protocol compatibility review.

View file

@ -1,7 +1,6 @@
# DocForge setup moved to the README
# DocForge setup moved to the user manual
The complete installation, project setup, CLI, MCP, viewer-manager, adapter, and agent-policy
reference now lives in the [DocForge README](../README.md).
The complete installation, project setup, visualization, CLI, MCP, application, adapter, and
troubleshooting reference now lives in the [DocForge user manual](USER_MANUAL.md).
This file remains only so existing bookmarks and links continue to resolve. Update links to point
to `README.md`.
This file remains only so existing bookmarks and links continue to resolve.

498
docs/USER_MANUAL.md Normal file
View file

@ -0,0 +1,498 @@
# 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.
## 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.
- Hash-bound canonical application through both CLI and an explicitly enabled MCP tool.
- Declared HTML render views. Arbitrary templates, render commands, and output paths are rejected.
- A loopback-only graph browser with Nodes and Flow views, relationship keys, source inspection,
node hiding, panel resizing, zooming, and managed idle shutdown.
- 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.
- Node.js and npm for browser asset validation.
- Pyright for strict static type checking.
Clone and verify DocForge:
```bash
git clone forgejo@repo.andraxion.net:administrator/DocForge.git /absolute/path/DocForge
cd /absolute/path/DocForge
uv sync
npm ci
npm install -g pyright
pyright --pythonpath .venv/bin/python
npm run lint:web
uv run ruff check src tests tools
uv run ruff format --check src tests tools
uv run python -m unittest discover -s tests -v
```
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 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.
## 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 **Hide node** to remove noisy non-focus nodes from the current presentation.
- Use **Restore hidden** above the graph to bring hidden nodes back.
- Use **Explore neighborhood** to make a node the new focus.
- Switch to **Flow** to inspect bounded directed ancestry.
- Use the mouse wheel or viewport buttons to zoom. Drag the canvas to pan. Press Space to center
the selected node.
Hidden nodes are a browser presentation preference. They do not alter the index or canonical graph.
The focus node cannot be hidden; focus another node first.
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`
- `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`
- `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.
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.
## 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 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 0.13 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@12` template.
### 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
pyright --pythonpath .venv/bin/python
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
uv run python -W error -m unittest discover -s tests -v
```
Project-specific vocabulary, extraction rules, and serialization belong in the project adapter.
Generic core behavior must remain deterministic, project-bound, and recoverable.

View file

@ -13,6 +13,17 @@ One worker is reused per project binding and validated index snapshot. `docforge
the worker only after the snapshot changes. `docforge_visualization_status` reports its state, and
`docforge_stop_visualization` explicitly stops it.
The same lifecycle is available without an MCP client:
```bash
docforge --project-root /absolute/path/MyProject reindex
docforge --project-root /absolute/path/MyProject visualize
docforge --project-root /absolute/path/MyProject visualization-status
docforge --project-root /absolute/path/MyProject visualization-stop
```
`visualize` opens the default browser. Add `--no-open` to return JSON without launching it.
The default one-hour idle policy is intentional. Browser requests, including the existing visible
page heartbeat, renew activity. A page is never tied to the lifetime of one MCP request or host
process. The manager stops genuinely abandoned workers after an hour without activity. Stopping the