Add gated changeset application and graph controls
This commit is contained in:
parent
3c15e26283
commit
78335c8973
20 changed files with 1813 additions and 453 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
498
docs/USER_MANUAL.md
Normal 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 project’s systems, authorities, persistence owners, runtime flow, failure behavior,
|
||||
tests, and operational entry points.
|
||||
```
|
||||
|
||||
Each Markdown file contains one node. A TOML source may contain multiple `[[nodes]]` records. TOML
|
||||
nodes need stable `source_anchor` values when proposals may create or move records within the file.
|
||||
Every relationship target must exist.
|
||||
|
||||
### Build the graph
|
||||
|
||||
```bash
|
||||
PROJECT=/absolute/path/MyProject
|
||||
DOCFORGE=/absolute/path/DocForge/.venv/bin/docforge
|
||||
|
||||
"$DOCFORGE" --project-root "$PROJECT" validate
|
||||
"$DOCFORGE" --project-root "$PROJECT" reindex
|
||||
"$DOCFORGE" --project-root "$PROJECT" context development
|
||||
```
|
||||
|
||||
`reindex` builds the SQLite graph and immediately checks its identity. Run it after canonical
|
||||
documentation or adapter sources change.
|
||||
|
||||
### Install the viewer manager
|
||||
|
||||
Install the native per-user supervisor once:
|
||||
|
||||
```bash
|
||||
docforge-viewer-manager install-user-service
|
||||
```
|
||||
|
||||
Linux uses `systemd --user`, macOS uses a LaunchAgent, and Windows uses Task Scheduler. If the
|
||||
virtual environment moves, reinstall the service so it points at the current Python interpreter.
|
||||
|
||||
For a temporary foreground manager:
|
||||
|
||||
```bash
|
||||
docforge-viewer-manager serve
|
||||
```
|
||||
|
||||
Open a project graph without Codex:
|
||||
|
||||
```bash
|
||||
docforge --project-root "$PROJECT" visualize
|
||||
docforge --project-root "$PROJECT" visualize --node architecture.overview
|
||||
docforge --project-root "$PROJECT" visualize --query persistence
|
||||
```
|
||||
|
||||
The command opens the default browser. Add `--no-open` when a script only needs the returned JSON
|
||||
URL. Use `visualization-status` and `visualization-stop` to inspect or stop the project viewer.
|
||||
|
||||
## Visualization usage
|
||||
|
||||
- Left-click a node for its compact descriptor.
|
||||
- Right-click a node for the full inspector.
|
||||
- Use **Open source** to read the node’s project-confined source at its anchor.
|
||||
- Use **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 adapter’s `source_anchor` to a line, stable heading, TOML `node-N` anchor, or distinctive
|
||||
symbol. DocForge can open the file safely, but it cannot infer a perfect code location from
|
||||
ambiguous adapter evidence.
|
||||
|
||||
### Full inspector content does not fit
|
||||
|
||||
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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue