Skip to content

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 public structs, the input contracts it reads, and the state it writes — 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: which procs are spawned, which external drivers (databases, runtimes, services) are invoked, and which env variables 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 format Struct → 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.
  • writes entries 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 structs entry and each target_file must 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

  1. Frontmatter linter — CI runs cargo run -p kova-docs-lint -- lint; it fails the build on malformed frontmatter, missing required keys, or a doc whose module / target_file does not resolve in the tree.
  2. 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.
  3. Write limits — the agent's writes declarations are the declared write boundary: plan artifacts are already fenced to research/plans/ by validate_plan_name + plan_path in kova-primitives::plan, and CI cross-checks planned file writes against the boundary (Tier 2 target_files, file: entries, state: names, plus the fenced research/plans/ surface) via kova-docs-lint check-writes and kova-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 structs or Tier 2 doc's target_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.