2026-07-22 01:29:32 -04:00
|
|
|
|
# DocForge
|
|
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
DocForge is a project-scoped documentation service for people and AI agents. It reads canonical
|
|
|
|
|
|
Markdown and TOML from one repository, validates stable nodes and relationships, builds a
|
|
|
|
|
|
disposable graph/search index, and returns bounded context with source provenance.
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
The canonical manual remains the project’s source of truth. DocForge does not apply canonical
|
|
|
|
|
|
changes, select project work, run project commands, commit, push, deploy, or publish. It may write
|
|
|
|
|
|
only configured derived output and isolated proposal previews through explicit boundaries.
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
This README is the complete setup and command reference. `docs/NEW_PROJECT_QUICKSTART.md` is kept
|
|
|
|
|
|
only as a compatibility link for existing bookmarks.
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
## What DocForge provides
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
- A project-bound CLI for validation, indexing, graph queries, context, and declared renders.
|
|
|
|
|
|
- A stdio MCP server with a fixed, project-scoped read surface.
|
|
|
|
|
|
- Optional isolated documentation proposal changesets. Canonical application stays in the owning
|
|
|
|
|
|
project’s normal editing and review workflow.
|
|
|
|
|
|
- A loopback-only graph browser with a native per-user viewer manager.
|
|
|
|
|
|
- A generic manual adapter and a contract for project-owned source-code adapters.
|
2026-07-24 16:01:03 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
The generic adapter reads only declared Markdown and TOML nodes. It does not infer application
|
|
|
|
|
|
modules, functions, calls, routes, tables, tests, or ownership. Projects that need those facts
|
|
|
|
|
|
provide a deterministic, project-owned source adapter.
|
2026-07-24 16:09:56 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
## Install and verify
|
2026-07-24 21:01:53 -04:00
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
Requirements: Python 3.12+, [`uv`](https://docs.astral.sh/uv/), and Node/npm for browser-asset
|
|
|
|
|
|
validation. Install Pyright once globally.
|
2026-07-24 22:26:01 -04:00
|
|
|
|
|
2026-07-22 01:29:32 -04:00
|
|
|
|
```bash
|
2026-07-25 01:16:05 -04:00
|
|
|
|
git clone forgejo@repo.andraxion.net:administrator/DocForge.git /absolute/path/DocForge
|
|
|
|
|
|
cd /absolute/path/DocForge
|
2026-07-22 01:29:32 -04:00
|
|
|
|
uv sync
|
2026-07-24 22:36:44 -04:00
|
|
|
|
npm ci
|
2026-07-25 01:16:05 -04:00
|
|
|
|
npm install -g pyright
|
|
|
|
|
|
|
|
|
|
|
|
pyright --pythonpath .venv/bin/python
|
2026-07-24 22:36:44 -04:00
|
|
|
|
npm run lint:web
|
|
|
|
|
|
uv run ruff check src tests tools
|
|
|
|
|
|
uv run ruff format --check src tests tools
|
2026-07-22 01:29:32 -04:00
|
|
|
|
uv run python -m unittest discover -s tests -v
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-07-25 01:16:05 -04:00
|
|
|
|
`npm run lint:web` validates the exact HTML, CSS, and JavaScript served by the graph browser, plus
|
|
|
|
|
|
a freshly rendered fixture manual.
|
|
|
|
|
|
|
|
|
|
|
|
## Connect a generic project
|
|
|
|
|
|
|
|
|
|
|
|
### 1. Create the project descriptor
|
|
|
|
|
|
|
|
|
|
|
|
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", "core", "system", "function", "operations", "roadmap"]
|
|
|
|
|
|
operations = ["create", "update", "move", "delete"]
|
|
|
|
|
|
|
|
|
|
|
|
[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", "core", "system", "function", "operations", "roadmap"]
|
|
|
|
|
|
statuses = ["current", "active", "open", "verified"]
|
|
|
|
|
|
required_nodes = ["architecture.overview"]
|
|
|
|
|
|
token_budget = 8000
|
|
|
|
|
|
dependency_depth = 3
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Choose only family names, relations, limits, and required root nodes that the actual project can
|
|
|
|
|
|
support truthfully.
|
|
|
|
|
|
|
|
|
|
|
|
### 2. Add canonical nodes
|
|
|
|
|
|
|
|
|
|
|
|
Create `/absolute/path/MyProject/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."
|
|
|
|
|
|
+++
|
|
|
|
|
|
|
|
|
|
|
|
# Architecture overview
|
|
|
|
|
|
|
|
|
|
|
|
Describe the project’s core authorities, system boundaries, persistence owners, runtime flow,
|
|
|
|
|
|
failure behavior, tests, and operational entry points.
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Every node needs a stable, unique `id`. Declare relationships in the same front matter:
|
|
|
|
|
|
|
|
|
|
|
|
```toml
|
|
|
|
|
|
depends_on = ["core.database"]
|
|
|
|
|
|
calls = ["system.metadata"]
|
|
|
|
|
|
tested_by = ["function.test-metadata-publication"]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Targets must already exist in the graph. Keep each node focused enough that an agent can retrieve
|
|
|
|
|
|
relevant facts without loading the entire manual.
|
|
|
|
|
|
|
|
|
|
|
|
### 3. Build and check the derived graph
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
DOCFORGE=/absolute/path/DocForge/.venv/bin/docforge
|
|
|
|
|
|
PROJECT=/absolute/path/MyProject
|
|
|
|
|
|
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" validate
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" build
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" check
|
|
|
|
|
|
"$DOCFORGE" --project-root "$PROJECT" context development
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`build` creates the disposable SQLite index in the configured cache path. Canonical Markdown and
|
|
|
|
|
|
TOML remain authoritative. Rebuild after canonical documentation changes. A stale or altered index
|
|
|
|
|
|
fails closed.
|
|
|
|
|
|
|
|
|
|
|
|
## CLI command reference
|
|
|
|
|
|
|
|
|
|
|
|
Every command emits deterministic JSON and begins with:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge --project-root /absolute/path/MyProject <command>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
| Command | Purpose |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `info` | Report the bound project and descriptor facts. |
|
|
|
|
|
|
| `validate` | Validate the descriptor and canonical source graph. |
|
|
|
|
|
|
| `build` | Build the disposable index. |
|
|
|
|
|
|
| `check` | Validate source and confirm the index matches it. |
|
|
|
|
|
|
| `validate-index` | Validate the existing derived index’s schema and identity. |
|
|
|
|
|
|
| `show NODE_ID` | Return one complete node. |
|
|
|
|
|
|
| `search QUERY [--limit N]` | Lexically search nodes. |
|
|
|
|
|
|
| `filter [--family X] [--authority X] [--status X] [--tag X] [--limit N]` | Filter nodes by declared fields. |
|
|
|
|
|
|
| `backlinks NODE_ID [--relation RELATION]` | Return incoming relationships. |
|
|
|
|
|
|
| `dependencies NODE_ID [--depth N]` | Traverse declared dependencies. |
|
|
|
|
|
|
| `impact NODE_ID [--depth N]` | Traverse likely downstream impact. |
|
|
|
|
|
|
| `context PROFILE [--budget N]` | Return bounded, cited context for one configured profile. |
|
|
|
|
|
|
| `render-status [VIEW_ID]` | Report declared render output state. |
|
|
|
|
|
|
| `render VIEW_ID` | Generate one configured canonical render output. |
|
|
|
|
|
|
| `preview CHANGESET_ID VIEW_ID` | Render one isolated changeset preview. |
|
|
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge --project-root "$PROJECT" show architecture.overview
|
|
|
|
|
|
docforge --project-root "$PROJECT" search metadata --limit 20
|
|
|
|
|
|
docforge --project-root "$PROJECT" filter --family system --status current
|
|
|
|
|
|
docforge --project-root "$PROJECT" backlinks system.metadata --relation calls
|
|
|
|
|
|
docforge --project-root "$PROJECT" dependencies system.metadata --depth 3
|
|
|
|
|
|
docforge --project-root "$PROJECT" impact system.metadata --depth 3
|
|
|
|
|
|
docforge --project-root "$PROJECT" render-status manual
|
|
|
|
|
|
docforge --project-root "$PROJECT" render manual
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## MCP server
|
|
|
|
|
|
|
|
|
|
|
|
Run one MCP server per project. Use absolute paths.
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-mcp --project-root /absolute/path/MyProject --proposal-writer project-editor
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Omit `--proposal-writer` for a read-only integration. The writer value is a configured writer ID,
|
|
|
|
|
|
not a shell command.
|
|
|
|
|
|
|
|
|
|
|
|
For an MCP client that uses JSON configuration:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"mcpServers": {
|
|
|
|
|
|
"my-project-docforge": {
|
|
|
|
|
|
"command": "/absolute/path/DocForge/.venv/bin/docforge-mcp",
|
|
|
|
|
|
"args": [
|
|
|
|
|
|
"--project-root",
|
|
|
|
|
|
"/absolute/path/MyProject",
|
|
|
|
|
|
"--proposal-writer",
|
|
|
|
|
|
"project-editor"
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Fixed read tools
|
|
|
|
|
|
|
|
|
|
|
|
| MCP tool | Purpose |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| `docforge_project_info` | Project identity, index health, and capabilities. |
|
|
|
|
|
|
| `docforge_get_contract` | Bound project contract and excluded operations. |
|
|
|
|
|
|
| `docforge_get_node` | One exact node with full validated content. |
|
|
|
|
|
|
| `docforge_search` | Lexical node search. |
|
|
|
|
|
|
| `docforge_filter_nodes` | Filter by family, authority, status, or tag. |
|
|
|
|
|
|
| `docforge_backlinks` | Incoming graph relationships. |
|
|
|
|
|
|
| `docforge_dependencies` | Declared dependency traversal. |
|
|
|
|
|
|
| `docforge_impact` | Downstream impact traversal. |
|
|
|
|
|
|
| `docforge_get_context` | Bounded, cited context for a configured profile. |
|
|
|
|
|
|
| `docforge_validate_project` | Validate source and derived index state. |
|
|
|
|
|
|
| `docforge_render_status` | Declared render-output state. |
|
|
|
|
|
|
| `docforge_visualize` | Start or reuse the project’s managed, read-only graph viewer. |
|
|
|
|
|
|
| `docforge_visualization_status` | Viewer state, URL, and lifecycle information. |
|
|
|
|
|
|
| `docforge_stop_visualization` | Explicitly stop the project viewer. |
|
|
|
|
|
|
|
|
|
|
|
|
When a proposal writer is configured, the server additionally exposes:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
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
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
MCP proposals write only isolated changesets. Review the diff, apply the approved text through the
|
|
|
|
|
|
project’s normal workflow, then run `validate`, `build`, and `check`.
|
|
|
|
|
|
|
|
|
|
|
|
## Managed graph viewer
|
|
|
|
|
|
|
|
|
|
|
|
Install the per-user manager once:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-viewer-manager install-user-service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Its lifecycle commands are:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
docforge-viewer-manager serve
|
|
|
|
|
|
docforge-viewer-manager uninstall-user-service
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The native supervisor is systemd on Linux, a LaunchAgent on macOS, and Task Scheduler on Windows.
|
|
|
|
|
|
The manager owns one loopback-only viewer worker per project snapshot. `docforge_visualize` starts
|
|
|
|
|
|
or reuses it. Active browser requests renew its one-hour idle timeout. Stop it explicitly through
|
|
|
|
|
|
`docforge_stop_visualization` when it is no longer wanted.
|
|
|
|
|
|
|
|
|
|
|
|
The viewer is read-only, token-protected, and bound to `127.0.0.1`. It shows both:
|
|
|
|
|
|
|
|
|
|
|
|
- **Nodes:** the bounded local graph with original stored relationship direction.
|
|
|
|
|
|
- **Flow:** the complete bounded directed ancestry of the selected node. It follows every incoming
|
|
|
|
|
|
stored edge recursively, preserving `source → target`; it does not infer or reverse arrows based
|
|
|
|
|
|
on relationship names.
|
|
|
|
|
|
|
|
|
|
|
|
## Project-owned source adapters
|
|
|
|
|
|
|
|
|
|
|
|
Use the generic adapter when a declared manual graph is sufficient. Build a project-owned adapter
|
|
|
|
|
|
when the graph must include source files, modules, functions, routes, tables, tests, or other
|
|
|
|
|
|
code-derived facts.
|
|
|
|
|
|
|
|
|
|
|
|
An adapter must:
|
|
|
|
|
|
|
|
|
|
|
|
1. Read source as data. Never import or execute the application to discover facts.
|
|
|
|
|
|
2. Use a deterministic, project-confined source set. For Git repositories, start with
|
|
|
|
|
|
`git ls-files` and exclude generated output, caches, secrets, and binaries.
|
|
|
|
|
|
3. Emit only evidence-backed nodes and edges with stable IDs, safe relative anchors, and hashes.
|
|
|
|
|
|
4. Sort nodes, edges, and metadata deterministically.
|
|
|
|
|
|
5. Return one immutable `AdapterProjection` through `AdapterLoader.load_projection()`.
|
|
|
|
|
|
6. Keep its cache within the project and build/check through `ProjectIndex`.
|
|
|
|
|
|
7. Bind the projection to `create_read_only_server()` unless an explicit proposal policy exists.
|
|
|
|
|
|
8. Reject proposal operations against derived nodes and adapter-created edges.
|
|
|
|
|
|
|
|
|
|
|
|
The project owns its adapter and launches it rather than generic `docforge-mcp`:
|
|
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"mcpServers": {
|
|
|
|
|
|
"my-project-docforge": {
|
|
|
|
|
|
"command": "/absolute/path/MyProject/.venv/bin/python",
|
|
|
|
|
|
"args": [
|
|
|
|
|
|
"-m",
|
|
|
|
|
|
"docforge_adapter.server",
|
|
|
|
|
|
"serve",
|
|
|
|
|
|
"--project-root",
|
|
|
|
|
|
"/absolute/path/MyProject"
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Require deterministic build, staleness, malformed-input, project-isolation, MCP-protocol, and
|
|
|
|
|
|
project full-gate tests before relying on an adapter.
|
|
|
|
|
|
|
|
|
|
|
|
## Agent policy
|
|
|
|
|
|
|
|
|
|
|
|
Add a project-specific version of this to `AGENTS.md`:
|
|
|
|
|
|
|
|
|
|
|
|
```markdown
|
|
|
|
|
|
## Canonical documentation and DocForge
|
|
|
|
|
|
|
|
|
|
|
|
- `/Docs/Manual/` is the canonical systems manual and architecture source of truth.
|
|
|
|
|
|
- Before a systems-level, persistence, API, worker, plugin, operational, or mainline change, call
|
|
|
|
|
|
`docforge_project_info` or `docforge_validate_project`, then retrieve relevant nodes with
|
|
|
|
|
|
`docforge_search`, `docforge_get_context`, or `docforge_get_node`.
|
|
|
|
|
|
- Inspect dependencies, backlinks, and impact at ownership boundaries. Read implementation and
|
|
|
|
|
|
tests as well as the manual. Treat a code/manual disagreement as a defect.
|
|
|
|
|
|
- After implementation, create and validate an isolated DocForge changeset. Review its diff.
|
|
|
|
|
|
- Apply approved text through the normal editing workflow, then run `validate`, `build`, and
|
|
|
|
|
|
`check`. Do not commit derived caches, changesets, or previews unless the project explicitly says
|
|
|
|
|
|
otherwise.
|
|
|
|
|
|
- When asked to visualize a project or node, call `docforge_visualize`.
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## Normal development loop
|
|
|
|
|
|
|
|
|
|
|
|
1. Validate the DocForge project.
|
|
|
|
|
|
2. Retrieve relevant context, backlinks, dependencies, and impact.
|
|
|
|
|
|
3. Inspect the corresponding implementation and tests.
|
|
|
|
|
|
4. Implement and test the change.
|
|
|
|
|
|
5. Create and validate a DocForge proposal when manual changes are needed.
|
|
|
|
|
|
6. Review the proposal diff and apply approved text through the normal project workflow.
|
|
|
|
|
|
7. Run `validate`, `build`, and `check`.
|
|
|
|
|
|
8. Run the project’s complete test gate.
|
|
|
|
|
|
9. Commit code, tests, and canonical manual updates together.
|
|
|
|
|
|
|
|
|
|
|
|
DocForge never applies, commits, pushes, builds, deploys, or publishes on the project’s behalf.
|