KB Load Contract (kb/v1)
This page is the contract between this repository and the hatlas support
pipeline. It is not a KB entry (no kb_id) — the loader skips it.
Layout
- KB root:
docs/07 - Knowledge Base/(this directory), recursive. - Entry files:
*.mdor*.mdxwhose frontmatter carries akb_id. - Non-entry files (this contract, the About page,
_category_.json) carry nokb_idand are never loaded as answers. - File names are for humans and sidebar order only; programs address
entries by
kb_id, never by file name.
Frontmatter schema
Every entry carries exactly these keys (unknown keys are allowed and ignored by the loader, so the schema can grow):
| key | type | rules |
|---|---|---|
kb_id | string | stable kebab-case slug, unique per locale. Never rename — answers cite it. |
title | string | human title; one question or concern per entry. |
summary | string | one-line plain-language answer (≤ 200 chars). Shown to classification first. |
locale | string | ISO 639-1. Only entries whose locale is on the approved reply list may be used to draft replies; every locale may ground classification. Launch list: en. |
updated | date | YYYY-MM-DD staleness stamp. Touched whenever any claim changes. |
sources | list | ≥ 1 citation. Kinds: owner-ruling:<ref>, issue:<owner>/<repo>#<n>, url:<https://…>. An entry with an uncited claim must not merge. |
tags | list | lowercase keywords, free-form. Aids claim-check recall. |
Uniqueness is the pair (kb_id, locale): the same concern in another
language is a separate file (e.g. 3 Data and account deletion.ja.mdx)
with the same kb_id and its own locale.
Frontmatter is a deliberately small YAML subset: scalar key: value
lines, block lists (- item), and flow lists ([a, b]). Nothing nested,
no multi-line scalars — the validator rejects anything else rather than
guessing.
Body rules
- One concern per entry; sections
What you might see/What's happening/What to dowhere they fit. - Plain language, short. No promises with dates. No claims beyond what the
sourceslist covers.
Staleness sweep (monthly)
The stamp is enforced mechanically: the dry-run validator below warns
when updated is older than 45 days and fails past 60 days, so stale
entries surface on every CI run, not only when someone remembers. The
upkeep cadence is a monthly sweep over all entries: re-verify each claim
against its source, refresh the stamp, delete entries whose concern is
gone (deleting > editing into something unrelated — git history keeps the
rest).
Dry-run parse
From the repo root:
python3 scripts/kb_validate.py # human report, non-zero exit on violations
python3 scripts/kb_validate.py --json # machine dump: one object per entry
tests/test_kb_contract.py runs the validator over the real entries in
CI (mise run test), so a contract violation fails the PR gate. The
--json output is the dry-run load: hatlas's production loader must
produce the same field set.