Installone binary
A single Rust binary — no runtime, no daemon. Install from the public GitHub repo, or drop a prebuilt release binary on your PATH.
built by aktagon.com
Keep the markdown your agents retrieve correct, current, and groundable — checked in CI on every commit.
ctxgrd is a CLI linter for the structured markdown your team and your AI both depend on. ADRs, PRDs, runbooks — every .md file with frontmatter and an ID.
Same input, same output, same exit code.
$ ctxgrd init Created ctxgrd.toml $ ctxgrd pack add agents Added pack 'agents' — 5 namespaces, 4 rule families. $ ctxgrd error[core.cross-ref]: cross-reference 'ADR-007' does not resolve to a known document --> docs/adrs/ADR-013.md:14:5 | 14 | Per ADR-007, the rule compiler is pure, so its output is cacheable. | ^^^^^^^ | help: use an existing ID, or mark retired with ~~ADR-007~~ found: 1 error · 0 warnings
Lint your context. · Markdown only. On purpose.
01 For the context engineer
ctxgrd catches broken references, tangled decision lineage, and duplicate IDs before they reach the model — and fails CI like a type error.
$ ctxgrd error[core.cross-ref]: cross-reference 'ADR-007' does not resolve to a known document --> docs/adrs/ADR-013.md:14:5 | 14 | Superseded by ADR-007, the rule compiler is pure. | ^^^^^^^ deleted in 9d7192b × 1 broken reference · exit 1
02 One contract, two readers
Every command emits --format json, keeps stdout a clean parseable stream, and returns documented exit codes. An agent can drive ctxgrd without screen-scraping — the same way your CI does.
$ ctxgrd lint --format json | jq '.diagnostics[0]' { "rule": "core.cross-ref", "severity": "error", "file": "docs/adrs/ADR-013.md", "line": 14, "message": "'ADR-007' does not resolve" } $ echo $? 1 # branch on it, no text parsing
03 Every capability
Scaffold ctxgrd.toml and your first namespaces in one command.
Check every claimed doc. Human output, or --format json for agents.
See the decision frontier — what's ready, what's blocked, what's stale.
Drop in reusable namespace bundles — agents, ops, project-docs, gdpr.
Wire ctxgrd into pre-commit, CI, or a Claude stop-hook.
Generate a correctly-structured ADR, PRD, or runbook from a template.
A single Rust binary — no runtime, no daemon. Install from the public GitHub repo, or drop a prebuilt release binary on your PATH.
One command writes a ctxgrd.toml that already passes its own validator, then lists every built-in pack — pick one to get a whole family of document types at once.
Picks the next free ID for the namespace, slugifies the title, and writes the required-heading skeleton. Prints the path so you can pipe it to your editor.
The default command. Walks the tree, lints every claimed document against its type, and points at the line. Exit 1 on errors — drop it straight into CI.
Point a run at part of the tree. `--namespace ADR` lints the ADRs and skips everything else; `--pack ops` lints every namespace that pack contributed, resolved through the stamps in your own config rather than the pack definition, so it never scopes to something you never adopted. A name the config does not declare exits 2 instead of quietly linting nothing.
A document marked accepted while the decision under it is still a draft records something that has not happened yet. The rule reads `depends_on` and names both halves: a terminal-status document may not depend on a non-terminal one. Settle the dependency, or reopen the dependent until it settles.
An instruction file that grows past the model's own limit gets truncated, and the part that falls off the end is not the part you would have chosen. The rule counts characters against a budget — 150,000 by default, Claude's own ceiling — and says how many to cut. Raise `max_chars` per namespace when the size is deliberate.
A source that exits clean without emitting anything produced a run byte-identical to one where every document passed. `[sources.<name>]` now carries a floor: `expect_min`, default 1, and falling under it warns. A namespace whose paths matched only files the walker skipped says so too, rather than counting zero and reporting green. Set `expect_min = 0` for a source that may legitimately emit nothing.
Some rules only ever lint id-less, path-claimed files - CLAUDE.md, TODO.md, DESIGN.md. Bind one to a namespace that also claims `core.id` and it is silently unreachable: `ctxgrd rules` lists it as active, the config is valid, and the check never executes. The combination is now a config error naming both halves, because a rule you believe is guarding something and is not is worse than no rule at all.
Reads `depends_on` across every document and sorts them into ready, blocked, and settled. A document is ready when everything it depends on is accepted; a blocked row names the dependency holding it up. There is no stage order to declare — the graph is the order. Add --format json for agents.
The readiness census as one row per document: id, namespace, status, whether it can be picked up, and the ids holding it back. Clean stdout, so a router chooses the next piece of work without screen-scraping a report written for a person.
The same document graph as diagram source — Mermaid `flowchart LR` or Graphviz DOT, emitted as text and never rendered. Pipe it into a docs build or a PR comment to show what is waiting on what.
A read-only local view of the governed docs — the namespace index, server-rendered markdown, clickable `depends_on` edges, and the same work queue. It binds loopback only and prints its URL as one JSON line on stdout, so an agent can discover the port it landed on. Logs go to stderr.
Release notes derived from the document graph instead of a file everyone forgets to edit. Each whitelisted document is attributed to the first release tag whose tree marks it terminal, so a shipped section is read back from the tag and cannot drift. `--check` is the CI gate, `--write` regenerates in place, `--format json` feeds an agent.
Pin a document to the commit of the code it documents. When that code moves, the doc is flagged stale — re-verify, then bless it back to green.
A pack is a reusable bundle of namespaces plus the rules they need. Adding one appends its blocks to ctxgrd.toml — it never clobbers what you already have.
Every block `pack add` writes is stamped with the pack version and a content fingerprint — `# pack: <name>@<version> sha:<hash>`. When the pack definition later evolves, or someone edits the block by hand, the fingerprint stops matching and `pack outdated` reports the divergence read-only: exit 0 when in sync, exit 1 when a block has drifted. Add --format json for agents.
Pull a pack-definition change into your config. Migrate rewrites fingerprint-clean blocks to the pack's current shape and re-stamps them; a block you have hand-edited is left untouched and surfaced as a structured diff to resolve yourself. The change is idempotent and purely structural — it introduces no new diagnostics. Preview with --dry-run, script it with --format json.
Beyond the built-in packs, ctxgrd has room for commercial packs that bundle a specialised document standard. arc42 — the 12 canonical architecture-documentation sections as required headings — is the first. Commercial license, coming soon.
Installs ctxgrd as a numbered fragment under a tracked `.githooks/pre-commit.d/` and points `core.hooksPath` at it, so a sibling linter's gate composes beside it instead of overwriting it. A lint failure aborts the commit. The same binary and exit codes drive your CI gate and editor LSP.
Wired as a Claude Code Stop hook, ctxgrd runs the moment the agent tries to finish. An error-severity diagnostic returns a block decision carrying the reason, so the agent repairs the document before handing back. Warnings never block and a clean run is silent. The hook always exits 0 — the verdict travels in the payload, not the exit code.
04 See it work
# 052-rule-compiler.md id: ADR-042 # 031-cache-policy.md id: ADR-042 ↳ Two records claim ADR-042. The agent retrieves "ADR-042" and grounds on the wrong one.
error[core.id-unique] ADR-042 declared twice 052-rule-compiler.md, 031-cache-policy.md ✓ fixed — renumber the compiler record to ADR-058. ✓ build green · exit 0 # every ID resolves to one doc
05 What it checks
Rules ship as packs — each a bundle of namespaces, one per document type. Point ctxgrd at a tree and every file is linted against its type.
ADR, PRD, ROADMAP, RFC, BUG doc types plus the TODO state file and the README front door — engineering doc lifecycle with status vocabularies, required headings, and a README that links the entry guide.
AGENTS — the AGENTS.md cross-tool instruction standard (agents.md).
CLAUDE/CLAUDESKILLS/CLAUDEAGENTS — the files proprietary to Claude Code: the CLAUDE.md instruction file,.claude/skills SKILL.md definitions, and.claude/agents subagent definitions.
CODEXSKILLS — OpenAI Codex SKILL.md definitions (.codex/skills).
GEMINI — the GEMINI.md instruction file Gemini CLI reads.
OPENCODEAGENTS — opencode agent definitions (.opencode/agent/*.md), linted via the opencode.frontmatter rule.
SPEC/TASK/PROMPT/HANDOFF — ctxgrd's harness-neutral agent-development document pipeline: a SPEC is implemented via TASKs, reusable PROMPTs are versioned, and a HANDOFF carries work to the next session.
RUN (runbooks) and PMR (postmortems) — the incident-management doc lifecycle, grounded in Google's SRE Book.
Security-document lifecycle (THREAT/VULN/RISK/SECREV/DEPAUDIT) plus neutral governance (POLICY/ASSET) — framework-neutral evidence discipline, no certification intent.
GDPR documentary artifacts (ROPA/DPIA/DPA) over the security base — Regulation (EU) 2016/679 Arts. 28/30/35. Paperwork existence/metadata/freshness only, never legal adequacy.
HIPAA Security Rule safeguard register (SAFEGUARD) and Business Associate Agreement register (BAA) over the security base — 45 CFR 164.308/310/312, Security Rule as in force 2026. Paperwork existence/metadata/freshness only, never legal adequacy.
SOC 2 control-to-evidence register (SOC2) over the security base — AICPA Trust Services Criteria (2017, rev. 2022): the mandatory Common Criteria CC1-CC9 plus the optional Availability/Confidentiality/Processing-Integrity/Privacy categories. Paperwork existence/metadata/freshness only, never operating-effectiveness adequacy.
ISO 27001 control-to-evidence register (ISO27001) over the security base — ISO/IEC 27001:2022 Annex A: 93 controls across the Organizational/People/Physical/Technological themes. Paperwork existence/metadata/freshness only, never implementation adequacy.
NIST 800-53 control-to-evidence register (NIST80053) over the security base — NIST SP 800-53 Rev 5: the 20 control families (AC-SR), family-level grain. Paperwork existence/metadata/freshness only, never implementation adequacy.
design — structural linting for the two root design-context files a design agent reads before it works: DESIGN.md (the visual system — how it looks) and PRODUCT.md (the strategy — register, platform, users, purpose, positioning, who/what/why).
SOUL.md/STYLE.md persona linting — section presence, order, and pairing
DDD — strategic Domain-Driven Design docs on the dependency graph: BOUNDEDCONTEXT (a model/language boundary with its Ubiquitous Language, aggregates, and domain events) and CONTEXTMAP (one Evans strategic-pattern relationship edge per file, riding depends_on).
C4 — architecture-diagram docs typed by the C4 model level (context/container/component/code) plus the supplementary deployment/dynamic/landscape views, each declaring its level and carrying a title.
CCPA/CPRA processing register (CCPA) and service-provider agreement register (SPA) over the security base — California Civil Code Title 1.81.5, Cal. Civ. Code §§ 1798.100/1798.140. Paperwork existence/metadata/freshness only, never legal adequacy.
CHECKLIST — turns a markdown checklist into an auditable, commit-pinned sign-off: every box checked and the sealed state pinned to a real, in-history commit.
EU AI Act obligation register (AIACT) and Art. 27 fundamental rights impact assessment register (FRIA) over the security base — Regulation (EU) 2024/1689. Paperwork existence/metadata/freshness only, never conformity or legal adequacy.
GitHub community-health files — CONTRIBUTING, CODE_OF_CONDUCT, SECURITY, SUPPORT — path-claimed as id-less docs with a warning-severity existence nudge. README stays in project-docs; LICENSE is excluded.
GitLab community-health files — CONTRIBUTING and CHANGELOG — path-claimed as id-less docs with a warning-severity existence nudge. README/LICENSE excluded; CHANGELOG is first-class on GitLab.
DEC — a program/governance decision register (docs/decisions/[0-9]*.md): one id-keyed markdown record per material program decision, carrying the decision, its rationale, cross-cutting impact, and the approving authority. First member of the RAID+ register family.
GUIDE — end-user documentation typed by the Diátaxis taxonomy (tutorial/how-to/reference/explanation) with a required title, kept discoverable from the README.
Inbound requests from downstream repos — CR (a JSM-Change-shaped, id'd, linted change request) and FEEDBACK (a light id-keyed note record: id/source/date, free-form body, on the HubSpot/Jira fields-over-headings model).
marketing — the markdown-documentable marketing-strategy artifacts on the dependency-free side of the CRM line: CAMPAIGN briefs, buyer PERSONAs, POSITIONING, and the ICP, each a structured record grounded in a named framework.
NIS2 cybersecurity risk-management register (NIS2) and Article 23 incident register (NIS2INC) over the security base — Directive (EU) 2022/2555 Arts. 20, 21(2) and 23. Paperwork existence/metadata/freshness only, never conformance to the statutory reporting clock.
TEST — a pinned Test Completion Report register (docs/tests/TEST-*.md): one id-keyed markdown record per release milestone, carrying the exit-gate verdict, the tree and contract revision it ran against, its outstanding defects, and sign-off. IEEE 829 / ISO-29119-3 completion report.
RESEARCH — deep-research reports (docs/research/**) kept evidence-honest: a sources/evidence section is required and a limitations/data-gaps section is nudged, with optional per-genre skeleton routing.
INTSTRIPE — the seven-phase Stripe web-integration checklist: a commit-pinned sign-off whose phases and @stripe.* anchors ctxgrd enumerates and wrkgrd's anchor-coverage proves.
The core tool and every built-in pack are free and MIT-licensed, forever. Commercial packs (arc42, GDPR, HIPAA) are optional add-ons.