Adopt in a repo
This walkthrough takes a fresh repository from zero to full jk-standards
gating. If you already have pre-commit, jk-standards.yaml, and a
drift map, jump straight to the Quickstart instead.
Step 1 — Pick your doc roots
Section titled “Step 1 — Pick your doc roots”Decide where your docs live. Common shapes:
docs/for a plain markdown reposite/src/content/docs/for an Astro/Starlight site- Both, if you have some raw markdown and a rendered site
Every file under a doc root will need class: frontmatter. If you have
long-frozen historical docs you don’t want to classify, list their
containing directory under exempt_dirs.
Step 2 — Write the config
Section titled “Step 2 — Write the config”Create jk-standards.yaml at the repo root. The toolkit dogfoods
itself, so its own config is the reference example:
version: 1
doc_roots:
- path: docs
extensions: [".md"]
- path: site/src/content/docs
extensions: [".mdx"]
taxonomy:
classes: [generated, gated, archived]
file_line_refs:
source_roots:
- path: src
extensions: [".py"]
# Inventory facts about the toolkit itself (how many checks, hooks, skills)
# must not be restated as numerals in the docs — they change as checks land.
# region:count-triggers
count_drift:
triggers:
- 'checks?\s+(?:in\s+total|total)'
- 'hooks?\s+(?:in\s+total|total)'
- 'skills?\s+(?:in\s+total|total)'
- 'checks?\s+ship(?:s|ped)?'
- 'hooks?\s+ship(?:s|ped)?'
- 'skills?\s+ship(?:s|ped)?'
- 'fields?\s+(?:in|of)\s+(?:the\s+)?config'
- '(?:checks?|skills?|hooks?|fields?)\s+are\s+available'
- '(?:checks?|skills?|hooks?|fields?)\s+are\s+registered'
# endregion:count-triggers
drift_map: .github/docs-drift-map.yml
behavioral_claims:
sources:
- type: pytest
path: tests
# Site JSON fixtures projected from Python source. `generated-freshness`
# runs each command, diffs against the tracked file, and restores the
# snapshot — so a source change without a regenerated fixture fails CI.
#
# coverage.json is intentionally NOT gated here: coverage numbers are
# environment-dependent (Python version, platform branches) and would drift
# between local dev and CI even with no source change. The emitter still
# runs at site-build time (site/package.json prebuild) so the site always
# shows current coverage; it just isn't diff-gated.
# region:generated-fixtures
generated:
- doc: site/src/generated/checks.json
command: jk-standards emit checks
- doc: site/src/generated/config-schema.json
command: jk-standards emit config-schema
- doc: site/src/generated/skills.json
command: jk-standards emit skills
# endregion:generated-fixturesField-by-field detail is in the Configuration reference.
Step 3 — Classify your docs
Section titled “Step 3 — Classify your docs”Frontmatter for every file under the doc roots:
---class: gatedtitle: My doc---
# ...The three canonical classes:
- gated — living, current-state doc. Linted by
status-prose,file-line-refs,count-drift, andbehavioral-claims. - archived — frozen dated record. Exempt from all linting; the content is a historical artifact.
- generated — machine-produced. Freshness-checked against its generator command, but not prose-linted.
Run jk-standards doc-taxonomy — it lists every doc missing a class or
carrying an unknown one.
Step 4 — Wire pre-commit
Section titled “Step 4 — Wire pre-commit”Add jk-standards to your .pre-commit-config.yaml, pinned to a release
tag. Every shipped hook is defined once in .pre-commit-hooks.yaml —
this is the exact definition your pre-commit install will resolve
when you enable doc-taxonomy:
- id: doc-taxonomy
name: docs carry a lifecycle class
entry: jk-standards doc-taxonomy
language: python
types_or: [markdown, mdx]
pass_filenames: falseEnable the ones that fit your repo:
- repo: https://github.com/JimAKennedy/jk-standards rev: v0.1.0 hooks: - id: doc-taxonomy - id: status-prose - id: file-line-refs # opt in when you have inventory nouns to gate: # - id: count-drift # opt in when you have a test suite to cite: # - id: behavioral-claimsThen pre-commit install and pre-commit run --all-files to catch
existing violations.
Step 5 — Wire the reusable CI workflow
Section titled “Step 5 — Wire the reusable CI workflow”doc-drift needs a git base ref (the PR merge base) and full commit
history, so it lives in CI rather than pre-commit. Consume the shipped
reusable workflow:
name: docson: [pull_request, push]
jobs: discipline: uses: JimAKennedy/jk-standards/.github/workflows/doc-discipline.yml@v0.1.0 with: toolkit-ref: v0.1.0 # pin the same version you used above config: jk-standards.yaml # path in your repoThe workflow checks out the PR with fetch-depth: 0, installs jk-standards
at the pinned ref, and runs jk-standards all. First-run failures name
the exact drift; fix by either updating the doc or adding a
Docs-Not-Affected: <reason> trailer to a commit in the range.
Step 6 (optional) — Enable inventory gating
Section titled “Step 6 (optional) — Enable inventory gating”If your prose says things like “N presets ship” or “N chapters in the
guide”, configure count_drift.triggers and interpolate the number from
a generated JSON:
count_drift: triggers: - 'factory\s+presets?' - 'chapters?\s+in\s+total'
generated: - doc: docs/counts.json command: node scripts/emit-counts.mjsThen reference it in prose as {counts.presets} rather than a numeral —
the count-drift check refuses numerals adjacent to trigger phrases,
but leaves the template literal alone.
Step 7 (optional) — Enable behavioral claims
Section titled “Step 7 (optional) — Enable behavioral claims”If you want prose to cite tests, configure a test-index source:
behavioral_claims: sources: - type: pytest # gtest | js | pytest path: testsThen in prose, add a verified: marker after each claim. The marker
wraps a key from the scraped test index in square brackets — pytest keys
look like test_module::test_name, gtest keys look like Suite.TestName.
Unresolved citations fail; the ⚠ unverified marker is allowed but
counted as an honest-state metric.
The Checks reference uses citations like these throughout — every claim about the toolkit’s behavior points at a real test.
- How to add a check — write a new check and wire it through the CLI, hooks, and emitters.
- Checks reference — every check with its rule and escape hatches.