Engine charters

Generated from docs/ai/charters/README.md. Edit that file, then regenerate: python docs/portfolio/_build/generate_reference_pages.py.


An engine is one implementation of the KAP assistant. Four exist — argus, dataadk, orion, kawa — and they are deliberately not interchangeable in behaviour, which is why certify-engines exists at all.

A charter is one page saying what a given engine is for: its job, who talks to it, what it must decline, and what it must never do. Nothing stated this before; the engines were named informally and their boundaries lived in whoever had last worked on them.

WP-9 of docs/plans/20260811_documentation_system_execution.md, following docs/proposals/20260811_ai_assistant_documentation.md (A1).

The one rule that makes a charter worth reading

Every “must never” entry names the mechanism that enforces it — or is marked as having none.

A constraint with no mechanism is a wish. Writing it in the same list, in the same tone, as constraints that a test actually holds is how a document stops being evidence: a reader cannot tell which lines are guaranteed and which are merely intended. So the charters mark them, and the unenforced ones are expected to look uncomfortable. That discomfort is the point — it is a worklist, not a blemish to smooth over.

The same judgment appears elsewhere in the repo: swagger-conventions.test.ts declines to demand invented failure responses because “a test that demands invented responses stops being evidence of anything.” A charter that claims unenforced guarantees fails the same way.

Invariants — true of every engine

These hold regardless of implementation. An engine that breaks one is not a different engine; it is a broken one.

Invariant Enforced by
Answers only over data the caller may see scope row (FR-AI-08, mandatory) + CONTRACT-API-001 RLS
Refuses cleanly when unauthenticated auth-failure row (mandatory)
Emits only AG-UI events the contract defines CONTRACT-CDC-001, lint-enforced
Never emits a signed URL or storage path to the model or the user CONTRACT-CDC-001 §7.4.1 + image-browsing row
Leaves no test residue in a real dataset test-data-hygiene row (mandatory)
Says it cannot answer rather than guessing KAB — roughly half its 32 tasks are deliberately non-answerable
Survives session lifecycle (new, resume, concurrent) lifecycle row (mandatory)

An engine that fails a mandatory row must say so plainly rather than describing the intended behaviour as though it held.

But failing is not automatically a defect — it depends on the engine’s job. dataadk exists to track KavApps, which moves at its own pace, so a row KAP has added will fail there until it exists upstream and syncs. Its charter reads the matrix as distance from upstream, not as a bug list. An engine whose charter claims to lead the matrix and then fails it is a defect; an engine whose charter says it lags by construction is working. The charter is what makes the difference legible.

Charter template

# Charter: <engine>

**Status:** <Certified | Not certifiable — N mandatory rows failing>
**Runtime:** <module path> · **Backend:** <adk | kawa>
**Last certified:** <date from ENGINE_CERTIFICATION.md>

## Job
One sentence, in the user's language.

## Users
Who talks to it, in which workspace.

## In scope / Out of scope
What it must handle. What it must decline — and where that goes instead.

## Must never
| Constraint | Enforced by |
|---|---|
| … | … *or* **nothing — intent only** |

## Certification
Which rows it declares and which suites gate it, quoting the current result.

Where the facts come from

Nothing in a charter should be typed from memory:

  • Certification results — docs/evaluation/ENGINE_CERTIFICATION.md, generated by pixi run certify-engines.
  • Row definitions — ai/tests/features/matrix.py (ROW_MANIFEST).
  • Runtime and routing — docs/handbooks/content/ai/runtime-and-systems.md.
  • Registry — ai/src/kavai/systems/e2e_registry.json.

A charter that disagrees with ENGINE_CERTIFICATION.md is wrong, and the generated file wins.