# Policy precedence DocForge composes an immutable effective policy for each project-bound process. It resolves restrictions in a fixed order: ```text core safety > explicit binding > no-AST shorthand > resource availability ``` A lower layer can make a requested operation unavailable; it cannot override a higher-layer prohibition. Bootstrap and generated client evidence report the composed result and hashes so a client does not need to infer policy from command-line arguments. ## 1. Core safety Core safety is unconditional. No capability mode exposes: - arbitrary file access or project switching; - arbitrary renderer, module, command, shell, argument, working-directory, or environment selection; - Git mutation; - project builds or compiler execution; - deployment or publication. Canonical application is limited to DocForge's validated serializer boundary. Adapter launch is limited to the immutable launcher contract. Rendering is limited to declared views and fixed built-in workers. An indexed instruction cannot alter any of these rules. ## 2. Explicit binding A process is bound at startup to one project root, descriptor, adapter, capability mode, writer and applier identities when present, no-AST selection, diagnostics selection, and projection modes. The binding does not change during the process lifetime. Capability modes are: - `read`: register only the read surface; - `proposal`: add proposal tools when a valid selected writer is available; - `application`: require a startup-bound canonical applier and expose exact-hash application; - `operator`: reserved; it currently adds no tools. Mode describes the maximum registered surface. Actual authority can be narrower. A descriptor must declare the selected writer, including allowed families and operation types. Application requires the matching configured writer, changeset creator, and canonical-applier identity. A mode name cannot create a missing descriptor grant. Generic generated client fragments default to read mode. Other construction paths preserve their documented compatible factory defaults. Treat `docforge_bootstrap.session_contract` and its actual capabilities as authoritative for a running server. ## 3. No-AST shorthand `--no-ast` is a restrictive compatibility shorthand. It composes: - adapter evolution `preserve`; - AST analysis `forbidden`; - Logic indexing `off`; - `docforge_get_logic` blocked; - prohibitions on AST, Tree-sitter, compiler-AST, and function-Logic upgrades. Non-AST source fingerprinting and incremental caching remain allowed. Existing one-method adapters continue to use `load_projection()`. The shorthand does not inspect how an existing adapter was implemented, sandbox its filesystem reads, or transform an AST-based adapter into a no-AST adapter. Do not run the Python, JavaScript/TypeScript, or C++ syntax reference integrations and then describe the binding as a proved no-AST integration. See [Legacy and no-AST operation](LEGACY_AND_NO_AST.md). ## 4. Resource availability Even an allowed policy cannot create a missing resource: - application mode requires a startup-bound canonical applier; - manual `explicit` or `auto` requires declared manual render configuration; - manual `auto` also requires canonical application in the current operation or server; - portable graph `explicit` requires declared portable graph configuration; - live viewer `on-demand` requires the viewer runtime; - an optional reference language requires its installed extra; - a project-owned launcher module must be installed, isolated, project-owned, and unchanged. Unavailable requested modes fail before hidden work. Missing optional language grammars return an actionable install target such as `docforge[typescript]` or `docforge[cpp]`; DocForge does not silently downgrade to a different frontend. ## Effective process policy The version-1 effective policy reports: - capability mode and whether it came from a factory default or explicit selection; - adapter evolution, AST analysis, and Logic indexing; - automatic synchronization and validated integrity; - the compatible manual-render projection; - profiling state; - blocked tools and prohibitions; - the exact precedence list. This version-1 projection preserves compatibility. It is not the complete version-2 rendering policy; portable graph and live-viewer choices are reported separately. ## Independent projection policy Manual rendering, portable graph publication, and live visualization use a separate immutable version-2 policy: ```text manual: auto | explicit | disabled portable_graph: explicit | disabled live_viewer: on-demand | disabled ``` When a selector is omitted, composition uses availability-aware defaults: - manual is `auto` only when manual configuration and canonical application are both available; otherwise it is `explicit` when configured, or `disabled`; - portable graph is `explicit` when configured, otherwise `disabled`; - live viewer is `on-demand` when the runtime is available, otherwise `disabled`. An explicit non-disabled selection for a missing resource returns `projection_policy_unavailable`. An active operation prohibited by the selected policy returns `projection_policy_forbids_operation` before planning, rendering, or viewer startup. Status remains intentionally narrower than active work. Manual and portable receipt-only status are available when their active operations are disabled. Viewer status and explicit stop remain available when viewer start is disabled. Ordinary standalone CLI rendering uses manual `explicit`. Manual `auto` belongs to a canonical application operation that owns automatic regeneration. ## Diagnostics do not grant authority `--diagnostics` enables bounded request-local stage timings and compiler-work counters. It does not enable tools, broaden paths, retain project content, or displace a primary MCP result that already needs the response budget. ## Descriptor policy and process policy The project descriptor is canonical project configuration. The process policy is a runtime restriction. They compose by intersection: ```text operation is available only if core permits it and the startup binding registers it and no-AST permits it and required resources exist and the descriptor grants the requested project authority and current graph/hash preconditions validate ``` Changing a descriptor does not retarget a running project-owned process. Descriptor, adapter implementation, or launcher drift requires a fresh process. ## Common decisions For an agent that only reads documentation: ```bash docforge-mcp \ --project-root /absolute/path/MyProject \ --capability-mode read ``` For an agent that may prepare reviewable proposals: ```bash docforge-mcp \ --project-root /absolute/path/MyProject \ --capability-mode proposal \ --proposal-writer project-editor ``` For a tightly controlled application process: ```bash docforge-mcp \ --project-root /absolute/path/MyProject \ --capability-mode application \ --proposal-writer project-editor \ --canonical-applier project-editor ``` For a read binding with every active output projection disabled: ```bash docforge-mcp \ --project-root /absolute/path/MyProject \ --capability-mode read \ --manual-render-policy disabled \ --portable-graph-policy disabled \ --live-viewer-policy disabled ``` Prefer the narrowest binding that completes the workflow. Call `docforge_bootstrap` first and use the returned effective policy, projection policy, actual capabilities, and prohibitions rather than assumptions based on client configuration. See the [MCP contract](MCP_CONTRACT.md), [Security](SECURITY.md), [Project descriptor](PROJECT_DESCRIPTOR.md), and [Rendering and visualization](RENDERING_AND_VISUALIZATION.md).