# Document Contract Framework Date: 2026-05-03 ## Purpose The contract framework makes markdown documents practically checkable. It keeps Markdown as the authoring surface and uses fenced YAML as a structured extension for rules that need machine interpretation. The first implementation is deterministic. It checks document type, fields, sections, ordering, metric bands, and text assertions. Runtime context, forms, dynamic rules, and provider-neutral assessment requests are implemented as extensions around the same contract vocabulary. ## Contract File Shape A contract is a Markdown document with optional frontmatter and one fenced YAML block marked as `yaml contract`. ````markdown --- title: ADR Contract version: "1.0" --- # ADR Contract ```yaml contract id: adr-contract-v1 document: type: adr title: Architecture Decision Record fields: status: type: string required: true sections: - id: context title: Context presence: required level: 2 metrics: document: words: min: 100 max: 1200 severity: warning ``` ```` Markdown carries the explanation. YAML carries the contract. ## Core Terms | Term | Meaning | | --- | --- | | Document contract | The machine-readable agreement for one typed Markdown artifact. | | Document type | A named kind such as `adr`, `prd`, `workplan`, or `business-letter`. | | Section spec | A semantic section role with matching headings, presence, level, order, metrics, and assertions. | | Field spec | A typed value expected in frontmatter or later external context. | | Metric band | A soft or hard size/complexity target. | | Assertion | A deterministic content expectation over document or section text. | | Diagnostic | A structured finding with severity, code, source, contract location, rule id, and guidance. | ## Section Presence Section specs support these presence values: - `required`: missing section is an error. - `recommended`: missing section is a warning. - `optional`: section is allowed but not required. - `discouraged`: present section is a warning. - `forbidden`: present section is an error. Headings are matched case-insensitively against `title`, `id`, `headings`, or `aliases`. ## Metric Bands Supported metrics are: - `characters` - `words` - `sentences` - `paragraphs` - `sections` - `headings` - `list_items` - `code_blocks` - `max_heading_depth` - `nesting_depth` Document-level bands live under `metrics.document`. Section-level bands live inside a section spec. The current metrics layer follows the parser model: every heading-led region is a section, including the document H1 title section. ## Assertions Assertions currently support: - `contains` - `contains_any` - `not_contains` - `matches` - `not_matches` Assertions are deterministic and produce the same diagnostic model as sections, fields, and metric bands. This is the bridge to later LLM rubrics: semantic checks can become additional assessments without changing how failures are reported. ## Forms, Context, And Runtime Rules Field specs are the foundation for form-backed Markdown generation and context-aware checks. Runtime form handling uses the same field vocabulary: - `id` - `type` - `required` - `default` - `source` - `path` - `enum` - `pattern` - `min` / `max` - `min_length` / `max_length` Runtime context can be supplied as local YAML or JSON: ```text mkt contract check --contract --context mkt contract form-state --contract --context ``` The runtime resolves fields in this order: document value, context source, default, missing. Document values win over context and conflicts are diagnostics. Dynamic rules support small deterministic `if` / `then` / `else` expressions for requiredness, visibility, allowed values, calculated values, context assertions, and dynamic section presence. See `docs/runtime-context-forms-assessments.md`. ## LLM Assessment Extension LLM-assisted checks are declared as rubrics, scoped to document or section roles. Core Markitect does not call a provider directly. It creates provider-neutral assessment requests for injected adapters: - contract id and rule id - document or section text - relevant fields and context - rubric criteria - cache key material It should return: - pass/fail - score - reason - model/provider metadata - diagnostics using the shared diagnostic model ## CLI ```text mkt contract validate mkt contract check --contract [--context ] mkt contract form-state --contract [--context ] mkt metrics ```