Close Milestone 4 with adapter adoption evidence
This commit is contained in:
parent
95271dcf2e
commit
6d06195950
27 changed files with 2870 additions and 325 deletions
279
docs/PROJECT_DESCRIPTOR.md
Normal file
279
docs/PROJECT_DESCRIPTOR.md
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
# Project descriptor
|
||||
|
||||
A generic DocForge project is selected by one fixed file:
|
||||
`.docforge/project.toml` beneath an explicit project root. The descriptor is schema version 1.
|
||||
DocForge validates both the JSON-schema shape in `schemas/project.schema.json` and runtime
|
||||
invariants that schema alone cannot prove.
|
||||
|
||||
Reference integrations use a different fixed descriptor,
|
||||
`.docforge/reference-adapter.toml`; see [Reference adapters](REFERENCE_ADAPTERS.md).
|
||||
Project-owned adapters construct the same runtime `ProjectDescriptor` contract through the public
|
||||
adapter SDK.
|
||||
|
||||
## Complete generic example
|
||||
|
||||
```toml
|
||||
schema_version = 1
|
||||
project_id = "my-project"
|
||||
title = "My Project"
|
||||
adapter = "generic"
|
||||
|
||||
[sources]
|
||||
content_roots = ["docs/docforge/content"]
|
||||
authority_files = []
|
||||
|
||||
[derived]
|
||||
cache_root = ".docforge/cache"
|
||||
index = ".docforge/cache/index.sqlite3"
|
||||
|
||||
[changesets]
|
||||
root = ".docforge/changesets"
|
||||
|
||||
[[changesets.writers]]
|
||||
id = "project-editor"
|
||||
families = ["architecture", "operations", "system"]
|
||||
operations = ["create", "update", "move", "delete"]
|
||||
|
||||
[render]
|
||||
template_root = ".docforge/templates"
|
||||
preview_root = ".docforge/previews"
|
||||
|
||||
[[render.views]]
|
||||
id = "manual"
|
||||
renderer = "generic_html"
|
||||
template = "manual.html"
|
||||
output = ".docforge/rendered/manual.html"
|
||||
title = "My Project Manual"
|
||||
families = ["architecture", "operations", "system"]
|
||||
|
||||
[graph_render]
|
||||
output_root = ".docforge/portable-graph"
|
||||
|
||||
[[graph_render.views]]
|
||||
id = "architecture"
|
||||
renderer = "portable_graph_html"
|
||||
output = "architecture.html"
|
||||
title = "Architecture"
|
||||
root = "architecture.overview"
|
||||
initial_mode = "web"
|
||||
depth = 3
|
||||
max_nodes = 250
|
||||
max_edges = 1000
|
||||
max_work = 100000
|
||||
families = ["architecture", "system"]
|
||||
relations = ["depends_on", "owns", "calls", "reads", "writes", "tested_by", "relates_to"]
|
||||
authorities = []
|
||||
statuses = ["current", "active", "verified"]
|
||||
tags = []
|
||||
include_logic = false
|
||||
|
||||
[graph]
|
||||
allowed_relations = [
|
||||
"calls",
|
||||
"depends_on",
|
||||
"owns",
|
||||
"reads",
|
||||
"relates_to",
|
||||
"tested_by",
|
||||
"writes",
|
||||
]
|
||||
|
||||
[limits]
|
||||
max_source_bytes = 500000
|
||||
max_nodes = 10000
|
||||
max_query_chars = 500
|
||||
max_results = 100
|
||||
max_traversal_depth = 6
|
||||
max_context_tokens = 12000
|
||||
max_tool_output_chars = 200000
|
||||
max_changesets = 100
|
||||
max_changeset_operations = 100
|
||||
max_changeset_bytes = 1000000
|
||||
max_render_views = 20
|
||||
max_template_bytes = 1000000
|
||||
max_render_bytes = 1000000
|
||||
|
||||
[[profiles]]
|
||||
id = "development"
|
||||
families = ["architecture", "operations", "system"]
|
||||
statuses = ["current", "active", "verified"]
|
||||
required_nodes = ["architecture.overview"]
|
||||
token_budget = 8000
|
||||
dependency_depth = 3
|
||||
```
|
||||
|
||||
Rendering sections are optional. Profiles and limits may also be omitted; runtime defaults then
|
||||
apply. The required top-level fields are `schema_version`, `project_id`, `title`, `adapter`,
|
||||
`sources`, `derived`, `changesets`, and `graph`.
|
||||
|
||||
## Identity fields
|
||||
|
||||
`schema_version` must be `1`.
|
||||
|
||||
`project_id` is the stable machine identity. It is lowercase and may contain digits, dots,
|
||||
underscores, and hyphens after its first character. Do not derive it from a mutable display title.
|
||||
|
||||
`title` is the human-readable project name.
|
||||
|
||||
`adapter` is `generic` for this file format. Project-owned adapters publish a validated
|
||||
`adapter_id@adapter_version` identity through their runtime descriptor; changing adapter identity
|
||||
invalidates incompatible derived state.
|
||||
|
||||
The descriptor's byte content contributes to a descriptor hash. Client fragments, launchers, index
|
||||
evidence, and policy results use that hash to detect drift.
|
||||
|
||||
## Canonical sources
|
||||
|
||||
`sources.content_roots` lists the project-relative directories containing generic Markdown and TOML
|
||||
nodes. Each path must resolve beneath the project root. Canonical content roots may not overlap the
|
||||
derived cache.
|
||||
|
||||
`sources.authority_files` lists additional project-relative regular files whose content belongs to
|
||||
the canonical project identity. They are not automatically parsed as nodes.
|
||||
|
||||
A Markdown node contains one TOML metadata block followed by Markdown content:
|
||||
|
||||
```markdown
|
||||
+++
|
||||
schema_version = 1
|
||||
id = "architecture.overview"
|
||||
title = "Architecture overview"
|
||||
family = "architecture"
|
||||
authority = "authoritative"
|
||||
status = "current"
|
||||
tags = ["architecture"]
|
||||
summary = "Defines the top-level architecture and ownership."
|
||||
+++
|
||||
|
||||
# Architecture overview
|
||||
|
||||
Describe systems, ownership, runtime flow, failure behavior, and proof.
|
||||
```
|
||||
|
||||
Every node ID is project-wide and stable. Every relationship target must resolve. A TOML source may
|
||||
contain multiple `[[nodes]]` records; proposal-enabled multi-node files need stable
|
||||
`source_anchor` values where creation or movement requires an exact record boundary.
|
||||
|
||||
## Derived state
|
||||
|
||||
`derived.cache_root` owns disposable indexes, attestations, extraction caches, render receipts,
|
||||
projection artifacts, and viewer registry state.
|
||||
|
||||
`derived.index` must be inside `derived.cache_root`. Canonical content and cache paths must not
|
||||
overlap.
|
||||
|
||||
Derived state is not a backup. If it is deleted or rejected as corrupt, DocForge rebuilds it from
|
||||
validated canonical sources.
|
||||
|
||||
## Changesets and writers
|
||||
|
||||
`changesets.root` is the confined proposal store. It must not overlap canonical content or the
|
||||
derived cache.
|
||||
|
||||
Each `changesets.writers` entry declares:
|
||||
|
||||
- a stable writer `id`;
|
||||
- the node `families` that writer may change;
|
||||
- allowed `operations`: `create`, `update`, `move`, and/or `delete`.
|
||||
|
||||
The descriptor grant is necessary but not sufficient. A process must also select that writer at
|
||||
startup, and canonical application requires a separately bound matching applier. Capability mode
|
||||
does not broaden the descriptor grant. See [Policy precedence](POLICY_PRECEDENCE.md).
|
||||
|
||||
## Allowed relationships
|
||||
|
||||
`graph.allowed_relations` is the exact project vocabulary accepted on edges. It must be nonempty.
|
||||
Relationship names are stable IDs. DocForge rejects relationships that are not declared and gives
|
||||
`depends_on` additional cycle validation.
|
||||
|
||||
The core does not reinterpret a custom relationship just because its spelling resembles a known
|
||||
term. Task-context retrieval classifies only the documented versioned aliases and preserves
|
||||
unknown allowed relationships as `unclassified`.
|
||||
|
||||
## Context profiles
|
||||
|
||||
Each `profiles` entry defines one bounded context compilation:
|
||||
|
||||
- `id` selects the profile;
|
||||
- `families` and `statuses` filter eligible nodes;
|
||||
- `required_nodes` names stable nodes that must be present;
|
||||
- `token_budget` limits compiled content;
|
||||
- `dependency_depth` bounds relationship expansion.
|
||||
|
||||
Profiles choose derived retrieval scope. They do not change node authority or writer permissions.
|
||||
|
||||
## Limits
|
||||
|
||||
Positive limits bound input, graph, retrieval, proposal, and rendering work. Current defaults are:
|
||||
|
||||
- `max_source_bytes = 1000000`
|
||||
- `max_nodes = 10000`
|
||||
- `max_query_chars = 500`
|
||||
- `max_results = 100`
|
||||
- `max_traversal_depth = 8`
|
||||
- `max_context_tokens = 32000`
|
||||
- `max_tool_output_chars = 200000`
|
||||
- `max_changesets = 1000`
|
||||
- `max_changeset_operations = 100`
|
||||
- `max_changeset_bytes = 1000000`
|
||||
- `max_render_views = 100`
|
||||
- `max_template_bytes = 1000000`
|
||||
- `max_render_bytes = 1000000`
|
||||
|
||||
Smaller project limits are useful policy. They cannot widen fixed internal worker, package,
|
||||
response, or cache ceilings. In particular, detached renderer transfer has its own fixed boundary
|
||||
even if a compatibility descriptor retains a larger `max_render_bytes`.
|
||||
|
||||
## Manual rendering
|
||||
|
||||
The optional `render` section declares:
|
||||
|
||||
- one confined `template_root`;
|
||||
- one isolated `preview_root`;
|
||||
- one or more stable views.
|
||||
|
||||
Each view uses the built-in `generic_html` renderer, a template beneath `template_root`, one
|
||||
declared output path, a title, and a family filter. Paths may not overlap canonical content,
|
||||
authority files, changesets, cache, templates, or previews in unsafe ways.
|
||||
|
||||
Templates are inert UTF-8 files with a fixed token vocabulary. They cannot select executable
|
||||
renderers or commands. See [Rendering and visualization](RENDERING_AND_VISUALIZATION.md).
|
||||
|
||||
## Portable graph rendering
|
||||
|
||||
The optional `graph_render` section declares an output root and one or more
|
||||
`portable_graph_html` views. Each view selects exactly one:
|
||||
|
||||
- `root`, an exact stable node ID; or
|
||||
- `query`, a bounded metadata-only lexical seed.
|
||||
|
||||
It may then restrict families, relations, authorities, statuses, and tags, plus depth, node, edge,
|
||||
and work limits. `initial_mode` is `nodes`, `flow`, or `web`. Portable graph contract version 1
|
||||
requires `include_logic = false`.
|
||||
|
||||
The declared `output` is relative to `graph_render.output_root`.
|
||||
|
||||
## Paths and confinement
|
||||
|
||||
Descriptor paths are project-relative. Absolute paths and parent traversal are rejected. Runtime
|
||||
validation also rejects symlink escapes, unexpected file types, unsafe overlap, changing path
|
||||
identity during sensitive reads or publication, and derived outputs outside their declared roots.
|
||||
|
||||
The explicit CLI `--project-root` is the only project selector. The MCP process binds it at startup
|
||||
and exposes no project-switching tool.
|
||||
|
||||
## Validate changes safely
|
||||
|
||||
After editing the descriptor:
|
||||
|
||||
```bash
|
||||
docforge --project-root /absolute/path/MyProject validate
|
||||
docforge --project-root /absolute/path/MyProject reindex
|
||||
docforge --project-root /absolute/path/MyProject check
|
||||
```
|
||||
|
||||
Descriptor or adapter implementation drift makes a project-owned running process fail closed; start
|
||||
a fresh process after changing those boundaries.
|
||||
|
||||
For first-time creation, prefer the create-only [New-project
|
||||
quickstart](NEW_PROJECT_QUICKSTART.md). For full invariants, read the [Core contract](CONTRACT.md).
|
||||
Loading…
Add table
Add a link
Reference in a new issue