2026-07-24 23:40:47 -04:00
|
|
|
# DocForge 0.10 contract
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
|
|
|
## Authority boundary
|
|
|
|
|
|
|
|
|
|
DocForge is bound to one explicit project root. Canonical project files own documentation facts.
|
|
|
|
|
Indexes, query results, context packs, changesets, previews, and renders are derived artifacts.
|
|
|
|
|
|
2026-07-22 02:58:51 -04:00
|
|
|
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
|
2026-07-22 01:29:32 -04:00
|
|
|
publication remain external integration actions. Passive revision detection may read the current Git
|
|
|
|
|
commit when Git is available; it cannot change repository state.
|
|
|
|
|
|
2026-07-22 12:06:04 -04:00
|
|
|
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`.
|
|
|
|
|
|
2026-07-22 01:29:32 -04:00
|
|
|
## Versioned contracts
|
|
|
|
|
|
|
|
|
|
- Project descriptor schema: `schemas/project.schema.json`, version 1.
|
|
|
|
|
- Node schema: `schemas/node.schema.json`, version 1.
|
|
|
|
|
- Edge schema: `schemas/edge.schema.json`, version 1.
|
|
|
|
|
- Result envelope: `schemas/result.schema.json`, version 1.
|
2026-07-22 02:58:51 -04:00
|
|
|
- Changeset schema: `schemas/changeset.schema.json`, version 1.
|
2026-07-22 01:29:32 -04:00
|
|
|
- Index schema: version 1, disposable and reproducible.
|
2026-07-24 23:40:47 -04:00
|
|
|
- Core, CLI, and MCP server: version 0.10.0.
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
|
|
|
Schema files describe the generic interchange contract. Runtime validation remains responsible for
|
|
|
|
|
path confinement, source hashing, relationship resolution, dependency cycles, project limits, stale
|
|
|
|
|
state, and adapter-specific rules that JSON Schema cannot prove by itself.
|
|
|
|
|
|
|
|
|
|
## Generic node storage
|
|
|
|
|
|
|
|
|
|
Markdown nodes begin with a TOML metadata block delimited by `+++`. The remaining Markdown is the
|
|
|
|
|
node content. TOML sources contain one or more `[[nodes]]` tables and store content in a `content`
|
|
|
|
|
field. Every node has a stable project-wide ID.
|
|
|
|
|
|
|
|
|
|
The generic authority vocabulary is `authoritative`, `approved_plan`, `derived`, `proposal`, and
|
|
|
|
|
`historical`. Projects define statuses and allowed relationship names in their descriptor. The core
|
|
|
|
|
gives special acyclic validation to `depends_on`; adapters may add stricter rules.
|
|
|
|
|
|
|
|
|
|
## Result identity
|
|
|
|
|
|
|
|
|
|
Successful operations identify the project, adapter, current revision when available, and canonical
|
|
|
|
|
source hash. Errors use a stable code, direct message, and structured details. Query operations fail
|
|
|
|
|
if canonical source no longer matches the derived index.
|
|
|
|
|
|
2026-07-22 02:58:51 -04:00
|
|
|
## Isolated proposal model
|
2026-07-22 01:29:32 -04:00
|
|
|
|
|
|
|
|
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
|
2026-07-22 02:58:51 -04:00
|
|
|
every incident relationship. Proposal validation and storage are atomic. Canonical application
|
|
|
|
|
remains external, and 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
|
|
|
|
|
fingerprint, base revision, canonical source hash, and ordered operations. Every append requires the
|
|
|
|
|
current changeset hash, so simultaneous writers cannot silently lose an operation.
|
|
|
|
|
|
|
|
|
|
Changesets from the same canonical base may coexist only when their touched node and source sets do
|
|
|
|
|
not overlap. Exact overlaps return structured conflicts naming the other changesets, nodes, and
|
|
|
|
|
sources. A stale canonical base, stale node hash, stale changeset hash, unauthorized family, unsafe
|
|
|
|
|
path, invalid graph, dependency cycle, unresolved delete relationship, or configured limit fails
|
|
|
|
|
before the proposal file changes.
|
|
|
|
|
|
2026-07-22 03:32:05 -04:00
|
|
|
## Declared rendering and previews
|
|
|
|
|
|
|
|
|
|
Render configuration is optional. A configured project declares one template root, one isolated
|
|
|
|
|
preview root, and one or more stable view IDs. Each view names a built-in renderer, template,
|
|
|
|
|
derived output file, title, and optional family filter. Paths are resolved under the project root
|
|
|
|
|
and may not overlap canonical content, authority files, changesets, templates, or previews.
|
|
|
|
|
|
|
|
|
|
The initial `generic_html` renderer uses pinned CommonMark parsing with raw HTML disabled. Templates
|
|
|
|
|
are UTF-8 files with a fixed token vocabulary; they cannot name commands, modules, or executable
|
|
|
|
|
renderers. Render identity covers the canonical source hash, optional changeset hash, selected node
|
|
|
|
|
and edge identities, view configuration, template hash, renderer contract, and exact parser version.
|
|
|
|
|
|
|
|
|
|
An explicit CLI render atomically replaces one declared derived output. MCP can render a validated
|
|
|
|
|
changeset only to its isolated preview path. Status recomputes expected output without writing and
|
|
|
|
|
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.
|
2026-07-22 04:17:05 -04:00
|
|
|
|
2026-07-24 16:01:03 -04:00
|
|
|
## Project-bound graph visualization
|
|
|
|
|
|
2026-07-24 21:43:11 -04:00
|
|
|
The fixed `docforge_visualize` MCP tool starts one leased read-only graph browser for the
|
2026-07-24 16:01:03 -04:00
|
|
|
server's already-configured project. It accepts only an optional stable node ID, an optional lexical
|
|
|
|
|
query, and a bounded traversal depth. It does not accept a project root, database path, SQL,
|
|
|
|
|
template path, bind address, command, or renderer.
|
|
|
|
|
|
|
|
|
|
The runner validates the complete canonical projection and derived index before it starts. It then
|
|
|
|
|
pins the browser to that exact validated SQLite file identity and project metadata so normal UI
|
|
|
|
|
queries do not rebuild a large adapter graph. Replacement or alteration of the index file makes the
|
|
|
|
|
browser fail closed; the user must invoke the tool again. The browser identifies itself as a
|
|
|
|
|
validated snapshot rather than claiming that canonical files are continuously monitored.
|
|
|
|
|
|
|
|
|
|
The HTTP listener binds to `127.0.0.1` on an operating-system-selected port. A cryptographically
|
|
|
|
|
random token is part of every accepted URL path. Only `GET` and `HEAD` are supported. Responses use
|
|
|
|
|
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
|
2026-07-24 23:15:57 -04:00
|
|
|
overview, bounded search, exact descriptor-category filtering, exact node content, bounded
|
|
|
|
|
incoming-and-outgoing neighborhoods, and one lease heartbeat. Descriptor filtering accepts only
|
|
|
|
|
family, authority, status, or tag plus one exact value. The heartbeat changes no project or index
|
|
|
|
|
state. There is no write endpoint, arbitrary query endpoint, static filesystem handler, external
|
|
|
|
|
asset, or project-selection control.
|
2026-07-24 16:01:03 -04:00
|
|
|
|
2026-07-24 23:40:47 -04:00
|
|
|
The `graph-browser@8` template provides mouse-wheel zoom centered on the pointer, left-button drag
|
2026-07-24 16:09:56 -04:00
|
|
|
pan, explicit zoom-in and zoom-out buttons, a reset-view button, and a live zoom percentage. A
|
2026-07-24 21:14:30 -04:00
|
|
|
four-pixel drag threshold defers pointer capture and preserves node activation for ordinary clicks.
|
2026-07-24 22:54:19 -04:00
|
|
|
Loading another root node fits the viewport to the returned neighborhood, including a useful
|
|
|
|
|
minimum scale for a single-node result. The current root begins selected, and activating another
|
|
|
|
|
graph node moves the visible selection ring to it. Space centers the viewport on the selected node
|
|
|
|
|
without changing zoom. Reset restores the fitted neighborhood view. Empty-canvas guidance is hidden
|
2026-07-24 23:15:57 -04:00
|
|
|
whenever a neighborhood is rendered. The page is fixed to the browser viewport. Search and exact
|
|
|
|
|
filter results fill the left panel, neighborhood traversal fills the right panel, and only the
|
|
|
|
|
center SVG canvas pans or zooms.
|
|
|
|
|
|
|
|
|
|
Left-clicking or pressing Enter on a graph node opens a compact descriptor card containing the
|
|
|
|
|
validated metadata and content previously shown in the details panel. Its family, authority,
|
|
|
|
|
status, and tag pills are buttons that replace the left result list with exact matching nodes.
|
|
|
|
|
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.
|
|
|
|
|
|
2026-07-24 23:40:47 -04:00
|
|
|
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,
|
|
|
|
|
launches, activations, and writes retain their declared source-to-target direction. Reads, imports,
|
|
|
|
|
and dependencies reverse for lineage presentation because the declared target feeds the source.
|
|
|
|
|
Structural, evidence, and context relations remain available in Nodes but are excluded from Flow.
|
|
|
|
|
This is a presentation transform over the validated bounded snapshot; it does not add or change
|
|
|
|
|
project relationships.
|
|
|
|
|
|
|
|
|
|
Both views color edges by relationship semantics and retain direction with visible SVG endpoint
|
|
|
|
|
symbols. Line patterns provide a non-color cue. A static canvas key shows the exact symbol, color,
|
|
|
|
|
label, and visible count for each displayed relation, including a deterministic fallback for
|
|
|
|
|
project-defined relations. Nodes and Flow use the same map.
|
|
|
|
|
|
|
|
|
|
The browser derives node presentation roles only from the returned bounded graph. The current root
|
|
|
|
|
is the focus. In Nodes, nodes reachable through outgoing edges are shown as outgoing paths; the
|
|
|
|
|
remaining visible nodes are incoming or lateral context. In Flow, lineage predecessors are shown as
|
|
|
|
|
upstream nodes. These roles receive distinct palettes and navigation sections. An undirected
|
|
|
|
|
shortest-hop calculation places Nodes on distance rings; Flow uses left-to-right distance layers
|
|
|
|
|
with the destination on the right. Each role palette darkens progressively by distance, capped at
|
|
|
|
|
fifty percent.
|
2026-07-24 21:01:53 -04:00
|
|
|
|
2026-07-24 22:07:33 -04:00
|
|
|
Each invocation launches the validated snapshot in a detached local worker. The worker is outside
|
|
|
|
|
the short-lived MCP transport process, so transport teardown cannot close an active browser. It
|
|
|
|
|
tracks the longer-lived MCP client host and closes when that owner process exits. A repeated
|
|
|
|
|
invocation in the same MCP process replaces its tracked worker after a fresh index check.
|
|
|
|
|
|
|
|
|
|
The page renews a 180-second lease every 15 seconds and when it becomes visible; a link never opened
|
|
|
|
|
receives a 120-second startup grace. An abandoned page stops renewing and the detached worker closes
|
|
|
|
|
after the bounded lease. Explicit service shutdown closes the worker tracked by that service
|
|
|
|
|
immediately. Project-specific integrations receive the same tool because the parent validates and
|
|
|
|
|
serializes only the supplied `ProjectService` and `ProjectIndex` snapshot; the detached worker does
|
|
|
|
|
not discover projects or load canonical sources.
|
2026-07-24 16:01:03 -04:00
|
|
|
|
2026-07-22 04:17:05 -04:00
|
|
|
## Project adapter boundary
|
|
|
|
|
|
|
|
|
|
An adapter supplies one deterministically ordered `AdapterProjection` containing core nodes and
|
|
|
|
|
edges plus ordered adapter metadata. The core validates root identity, graph integrity, stable
|
|
|
|
|
ordering, and metadata-key uniqueness before exposing the projection through the standard derived
|
|
|
|
|
index. The loader is called again during an operation so identity or source changes fail closed.
|
|
|
|
|
|
|
|
|
|
Adapters own stricter project semantics such as authority precedence, phase rules, context
|
|
|
|
|
selection, query ordering, and render-model composition. They may not weaken root confinement,
|
|
|
|
|
canonical authority, graph validation, hashing, stale-state checks, or derived-output boundaries.
|
2026-07-22 05:59:20 -04:00
|
|
|
Shadow adapters are explicit local integrations and are not loaded by the normal generic MCP
|
|
|
|
|
process. A project integration may explicitly construct a read-only MCP server from one validated
|
|
|
|
|
`ProjectService` and an optional project-owned context provider. That server exposes only the fixed
|
|
|
|
|
read tool surface. The core does not discover adapters, choose projects or sessions, or import
|
|
|
|
|
project policy.
|
2026-07-22 11:50:49 -04:00
|
|
|
|
|
|
|
|
A proposal-enabled adapter declares confined canonical source, changeset, template, preview, and
|
|
|
|
|
render paths plus fixed writer permissions. It must supply a proposal validator. The core continues
|
|
|
|
|
to enforce optimistic hashes, writer permissions, graph integrity, limits, atomic changeset storage,
|
|
|
|
|
conflict detection, and preview confinement. The adapter validator enforces source-format and
|
|
|
|
|
project semantics that the generic core cannot infer. Generic projects retain the built-in Markdown
|
|
|
|
|
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.
|