generated from coulomb/repo-seed
162 lines
4.0 KiB
Markdown
162 lines
4.0 KiB
Markdown
# 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. Forms, context, and LLM
|
|
rubrics are represented in the contract vocabulary as extension points before
|
|
runtime adapters are added.
|
|
|
|
## 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 And Context
|
|
|
|
Field specs are the first step toward form-backed Markdown generation. Runtime
|
|
form handling should build on the same field vocabulary:
|
|
|
|
- `id`
|
|
- `type`
|
|
- `required`
|
|
- `default`
|
|
- `source`
|
|
- `path`
|
|
- `enum`
|
|
- `pattern`
|
|
- `min` / `max`
|
|
- `min_length` / `max_length`
|
|
|
|
Dynamic requiredness, visibility, calculations, and prefill should be declared
|
|
as context-aware rules in later work. The contract should remain the source of
|
|
truth, while UI and generation layers act as adapters.
|
|
|
|
## LLM Assessment Extension
|
|
|
|
LLM-assisted checks should be declared as rubrics, scoped to document or section
|
|
roles. Core Markitect should not call a provider directly. A future adapter
|
|
should accept a provider-neutral request:
|
|
|
|
- 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 <contract.md>
|
|
mkt contract check <document.md> --contract <contract.md>
|
|
mkt metrics <document.md>
|
|
```
|