Agent Docs Concept¶
docs/agent/ is a machine-readable contract layer for Kova's research
agent. It answers three questions the research phase must answer before it
writes code: what exists (which structs, functions, and files form a
module's contract), what it touches (which processes, drivers, and
environment variables a module actually uses at runtime), and how data
moves (the execution chain from an input struct to a written artifact).
Human documentation (docs/human/, this MkDocs site) explains intent and
context. Agent documentation is the precise, lint-checked subset the model
may rely on as ground truth — and the only place its writes declarations
are enforced.
Why two tiers¶
- Tier 1 — module contracts (
docs/agent/tier1/). One doc per logical module (engine.md,mcp.md,pipeline.md). Declares the module's publicstructs, the input contracts itreads, and the state itwrites— output types and declared state mutations. This is the surface a plan must name before it proposes touching the module. - Tier 2 — side-effect surfaces (
docs/agent/tier2/). One doc per concrete file with real side effects (engine_ops.md→crates/kova-core/src/state.rs,mcp_runner.md→crates/kova-mcp/src/server.rs). Declares the OS-level truth: whichprocsare spawned, which externaldrivers(databases, runtimes, services) are invoked, and whichenvvariables are read. A plan that adds a subprocess or a new driver without updating its Tier 2 doc fails the linter. - Code flows (
docs/agent/code_flows/). Execution chains in the standardized formatStruct → Reads → Fn → File + Proc + Env → Writes → Env, one line per hop, tracing a request from entry struct to written artifact. These are the trace the agent follows when it reasons about "what happens if I change X."
The tiering matters because the failure modes differ: a wrong Tier 1 doc makes the agent invent APIs; a wrong Tier 2 doc makes the agent miss side effects (a spawned process, an env var, a DB write). The linter treats the two tiers with different schemas.
Frontmatter schema¶
Every file in docs/agent/ (except templates/) starts with YAML
frontmatter. The linter (the kova-docs-lint crate, run in CI) enforces:
| Doc kind | Required fields |
|---|---|
Tier 1 (doc_tier: 1) |
module (crate name), structs (list), reads (list of input contracts), writes (list of output contracts + state mutations) |
Tier 2 (doc_tier: 2) |
target_file (repo-relative path), procs (list), drivers (list), env (list) |
Code flow (doc_kind: code_flow) |
module, chain (list of chain lines) |
Rules:
- Frontmatter must parse as YAML and sit at the very top of the file
(
---delimited). - Lists may be empty (
procs: []) but the key must be present — an empty list is a claim ("this file spawns nothing"), not an omission. writesentries in Tier 1 docs are the write-limit declarations: they name the exact state surfaces the module may mutate (state types, event ring, fenced plan paths). The Codebase Write Limits validator consumes them (see below).- Every doc names real code: each
structsentry and eachtarget_filemust resolve to a symbol/file in the tree. Docs are verified against the codebase, not against each other.
Templates¶
Scaffold new docs from docs/agent/templates/:
tier1_template.md— module contract skeleton.tier2_template.md— side-effect surface skeleton.code_flow_template.md— execution-chain skeleton with the standardized hop format and worked example.
Enforcement¶
- Frontmatter linter — CI runs
cargo run -p kova-docs-lint -- lint; it fails the build on malformed frontmatter, missing required keys, or a doc whosemodule/target_filedoes not resolve in the tree. - Link check — Tier 1 docs must cross-reference their Tier 2 surface
docs (e.g.
engine.md→engine_ops.md); the checker verifies every such relative link resolves. - Write limits — the agent's
writesdeclarations are the declared write boundary: plan artifacts are already fenced toresearch/plans/byvalidate_plan_name+plan_pathinkova-primitives::plan, and CI cross-checks planned file writes against the boundary (Tier 2target_files,file:entries,state:names, plus the fencedresearch/plans/surface) viakova-docs-lint check-writesandkova-docs-lint check-plan.
What the research agent gets out of it¶
- A plan may only name structs/files that appear in some Tier 1 doc's
structsor Tier 2 doc'starget_file— no invented APIs. - Before proposing a change that touches a process, driver, or env var, the agent reads the relevant Tier 2 doc and names the side effect in its plan.
- When reasoning about a change, the agent follows the matching code-flow chain instead of re-deriving the call path.