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

Close Milestone 4 with adapter adoption evidence

This commit is contained in:
Andraxion 2026-07-29 15:34:25 -04:00
parent 95271dcf2e
commit 6d06195950
27 changed files with 2870 additions and 325 deletions

101
docs/SECURITY.md Normal file
View file

@ -0,0 +1,101 @@
# Security model
DocForge is a project-bound knowledge compiler. Its security boundary is an explicit project root,
closed configuration, bounded data, and exact identities. It is not a general process sandbox.
Start with [core authority](CORE_CONCEPTS_AND_AUTHORITY.md), then use
[policy precedence](POLICY_PRECEDENCE.md) to decide which capabilities a server should expose.
## Project and path confinement
Descriptors, reference-adapter configurations, canonical sources, authority files, templates,
changesets, caches, indexes, previews, and declared outputs are resolved against one project root.
DocForge rejects absolute paths where only project-relative paths are allowed, parent traversal,
symbolic-link escapes, unsafe file types, and protected-root overlap. Important reads use
no-follow file descriptors and compare file identity before and after reading.
Confinement protects DocForge operations. It does not stop another process with repository access
from changing files. Long-running bindings revalidate descriptor and adapter implementation
identity and require a restart after drift.
## Untrusted project content
Documentation, source text, templates, adapter metadata, compiler-database entries, and changeset
content are data. They cannot redefine policy or instruct DocForge to execute a command. Generic
manual rendering disables raw HTML, accepts a fixed template vocabulary, and rejects script-like
content. Portable graph and manual workers accept validated inert packages and fixed built-in
renderer identities.
The C++ reference adapter reads `compile_commands.json` only as bounded translation-unit inventory
and fingerprint evidence. It never executes the recorded command, compiler, response file, or
project program.
## Adapter launcher boundary
`AdapterLauncherV1` contains one Python module name and project identity. It contains no command,
shell string, arbitrary argument list, working directory, environment, discovery rule, or callable
selector.
Custom modules must be installed top-level modules. An isolated `python -I` probe resolves the
module without importing it and requires its regular-file origin to remain inside the bound
project. The sole trusted dotted exception is the packaged `docforge.reference_mcp` module. Client
fragments use the exact validated interpreter and canonical fixed arguments with an empty
environment.
This proves that the declared module is resolvable and project-bound. It does not make arbitrary
module code safe. Project owners remain responsible for the implementation they install.
## Mutation boundary
Normal MCP and the fixed reference server are read-only. Proposal tools exist only when a
startup-bound writer is authorized by the descriptor. Canonical application exists only when a
matching applier is explicitly configured.
Every proposal append, rebase, abandonment, and application is hash-bound. Application requires
the exact changeset hash that was reviewed. Source identity, content hashes, permissions,
conflicts, graph validity, and serializer round trips are checked before success. DocForge never
turns prose approval into a fuzzy merge.
## Derived state and publication
SQLite indexes, source-generation receipts, extraction caches, render fragments, previews, and
portable artifacts are disposable. Corrupt, stale, foreign, oversized, or mismatched derived
state is rejected or rebuilt from current project evidence.
Generated command-reference publication serializes cooperating writers and uses no-clobber or
compare-and-swap publication. A raced target is restored or retained for recovery instead of being
silently discarded. Projection publication records when an artifact was committed but later
receipt verification degraded, so a completed mutation is never reported as an ordinary failure.
## Limits and denial-of-service resistance
Inputs, results, traversal, context, changesets, renders, worker protocols, manifests, adapter
assemblies, and extraction caches have explicit count and byte limits. Incremental extraction
caches are capped at 10,000 sources and 64,000,000 bytes. Adapter primary nodes use the project
`max_nodes` limit; edges and Logic have deterministic multipliers over that limit.
Limits reduce accidental and adversarial amplification. An in-process adapter can still allocate
memory before returning data, so only trusted project-owned adapter code should run in the server
process.
## Secrets and network behavior
DocForge does not copy the parent environment into generated client fragments or detached
projection workers. Doctor checks never return environment values. The live viewer binds to
loopback, uses an unguessable URL token, supports read-only methods, and serves no arbitrary
filesystem tree.
Project secrets must not be placed in canonical documentation, adapter configuration, compiler
databases, templates, or changesets. Repository release gates include secret scanning, but that
scan is not a substitute for credential hygiene.
## No-AST boundary
`--no-ast` is a binding policy that preserves the selected adapter and prohibits Logic publication
and retrieval. It is not a parser detector, filesystem sandbox, or promise that unrelated
processes cannot parse source. See [legacy and no-AST operation](LEGACY_AND_NO_AST.md).
## Reporting and recovery
Do not bypass a confinement, identity, policy, hash, or limit error. Preserve the failing evidence,
stop the affected binding, and follow [recovery and performance](RECOVERY_AND_PERFORMANCE.md).