Keep your agents grounded — specs, docs, and code as one knowledge graph, always in sync.
grund exists so you always know why — why your agents did what they did, why a line is the way it is: all work stays grounded in the spec that called for it (§GRUND-grund). It keeps three promises:
- The why stays known — everything in the project cites the spec point that says why it is the way it is (§GRUND-understanding).
- The project's long-term memory stays organized — every fact has a stable ID, fetched on demand in minimal tokens instead of re-read from whole files (§GRUND-structure).
- The structure stays consistent —
grund checkfails the build the moment work and memory drift apart (§GRUND-consistency).
grund is built around one workflow:
- Specify your intent. Declare the goal, spec, or decision as a
# <ID>: …heading before any code or doc cites it. - Cite as you write. Every code unit carries a
§<ID>back to the spec section it implements (§<KIND>-<slug>[.section]— full grammar in section 4). - Re-read before you edit.
grund <ID>.<section>pulls just that subsection into context — no full-file reads, no token bloat. - No dangling pointers.
grund checkvalidates that every cited ID resolves — in.md, Rust///, Java doc-comments, Python docstrings, Go//, JSDoc, every doc-comment formgrundknows about.
Off-the-shelf Markdown link checkers (lychee, markdown-link-check) only handle .md and only validate [text](url). A §-marked citation of FS-check.3.2 in crates/grund-core/src/checker/references.rs is invisible to them. That gap is what grund exists to close: Lychee checks whether Markdown links still open; grund checks whether your code still knows why it exists. Lychee is the link checker; grund is the intent checker. Both belong in CI; they guard different failure modes. §GRUND-grund.1
Before anything can be cited, the target has to exist. A declaration is a heading whose first token is the ID — grund's own reason for being lives at docs/grund.md:
# GRUND-grund: agents stay grounded in the spec
Keep agents grounded in the spec — fewer bugs, cheaper LLM context,
faster onboarding. …That heading lives in the configured home for its kind (GRUND → docs/grund.md, FS → requirements.md, GOAL → docs/goals.md, and so on — see section 4). Once it's declared, any code, doc, or test can cite §GRUND-grund and grund check will resolve it. A declaration can live in code too: drop the # in a doc-comment — grund's own architecture spec AR-checker opens with /// AR-checker: how grund validates the scanner's findings, right on the code it describes (section 4 shows the wiring).
When code realizes a named behavior, it carries a §<ID> citation — on its doc-comment for a whole behavior, or inline beside the line that enforces one clause. From grund's own source — the code implementing the missing-section check is grounded in FS-check.3.2, the spec section that defines that very check:
// crates/grund-core/src/checker/references.rs
/// The reference-resolution rule family — dangling citations (§FS-check.3.1),
/// missing sections (§FS-check.3.2), unknown project aliases (§FS-check.3.8), …
// …
// §FS-check.3.2: the ID resolves but no declaration has a heading at the
// cited section path.
if let Some(sec) = &cite.section {
let any_match = decls.iter().any(|d| d.sections.contains_key(sec));grund doesn't invent these citations — that's the contributor's call. What grund does is make sure the ones you wrote resolve. With require_grounding = true — in [reference] for every place at once, or on one [[kinds]] row for that place alone, at a grounding_level from the whole file down to every ## of it (§FS-config.3.4.8) — it also fails what carries no resolving citation; the stronger diff-aware "implementation changed with its spec or test" gate is tracked separately in §RM-cochange-gate.
Store section citations with their full ID. For example, this input inside an
FS-check declaration body contains a live local section citation:
See §2.1.
When section 2.1 exists, the citation remains navigable, but grund check reports:
local section citation §2.1; write §FS-check.2.1
grund fmt --write expands safe owned sites; protected sites need manual replacement.
A missing local section also gets the ordinary missing-section error. A site outside
a declaration is diagnosed without a guessed target and needs a full citation or an
escape: <§>2.1 is an inert illustration, with no citation diagnostic or navigation.
This is intentionally newly loud compatibility behavior for a
form that older releases silently skipped (§FS-check.3.24, §FS-fmt.2.4).
A citation is a pointer to a fact, not a file path. Resolve it without opening files:
$ grund FS-check.3.2
### 3.2 Missing section
A citation with a section suffix (`§FS-<user-login>.3.1` or, in an opted-in repository, `§FS-<user-login>.goals`) where the declaration exists but the requested section heading does not. [… remaining lead output elided …]grund <ID> returns just the useful slice — the lead prose for one section, cut at the first child section — so the agent pulls one fact into context instead of an entire file. Use grund list --size=words to measure how much prose a given slice contains. Wrappers flatten outside fenced examples. Its ladder:
grund <ID>— the lead prose, cut at the first child section; the cheap default for a bare citationgrund <ID> --toc— the lead plus the section map, for choosing the next subsectiongrund <ID> --brief— heading plus first paragraph only, for hover-sized previewsgrund <ID> --full— the full declaration body when the narrower reads are not enoughgrund <ID> --format json— for tooling
For many reads, the explicit batch form accepts ordered NDJSON and reuses one workspace scan; --all discovers every declaration and section from that same loaded catalog (§FS-show.2.6):
printf '%s\n' '{"id":"FS-check"}' '{"id":"FS-check","section":"3.2"}' \
| grund show --batch --format=json
grund show --batch --all --format=jsongrund refs <ID> --summary gives the blast radius one file per line before a full citation dump, and grund list --kind FS,AR keeps discovery scoped. When a specification feels heavy, grund list --size=words --top 10 finds the largest leads before you read them in full. That's the "cheap grounding" half of the workflow: every agent fetches the same bytes for the same ID, every time.
Repositories can opt into a warning at their own measured boundary:
[reference]
lead_size_warning = { max = 600, unit = "words" }An over-budget lead should keep its grounding: move detail into numbered child sections, or promote a child section to its own ID after checking its callers with grund refs <ID> --summary. See the point-size guide for counting rules, output fields, duplicate handling, and workspace scope (§FS-list.3.4, §FS-check.4.13).
For scripts, exit 0 is a completed refs answer even when it is empty. From
grund 0.15.0, exit 1 means the selected repository grammar rejected the ID or
its number-only shorthand was ambiguous; route that status to ID repair, and
reserve exit 2 for setup, configuration, I/O, or incomplete-scan failure.
Grund 0.14.0 keeps the former exit 2 for those two operand failures and warns
on stderr about the 0.15.0 change
(§FS-refs.4).
Renumber the heading ### 3.2 Missing section in FS-check.md and grund check flags every site that leaned on it — code and decision docs alike, in one resolver:
$ grund check
crates/grund-cli/tests/index_entry_round_trip.rs:229: error: missing section FS-check.3.2
crates/grund-core/src/checker/index.rs:152: error: missing section FS-check.3.2
crates/grund-core/src/checker/index.rs:258: error: missing section FS-check.3.2
crates/grund-core/src/checker/references.rs:2: error: missing section FS-check.3.2
crates/grund-core/src/checker/references.rs:378: error: missing section FS-check.3.2
crates/grund-core/src/checker/report.rs:85: error: missing section FS-check.3.2
crates/grund-core/src/checker/report.rs:486: error: missing section FS-check.3.2
docs/decisions/functional/DF-duplicate-section-path.md:26: error: missing section FS-check.3.2
docs/decisions/functional/DF-require-grounding.md:8: error: missing section FS-check.3.2
docs/requirements/REQ-no-wrong-citation.md:7: error: missing section FS-check.3.2
grund check <path> scans <path>; with no path it scans the canonical layout (requirements.md, docs/, e2e/, src/). In the scanned tree it enforces:
- Every cited ID resolves to a declaration. (dangling references)
- Every section coordinate (
.3.1) resolves to a heading inside the declaration. (missing sections) - No ID is declared in two places. (duplicates)
- Every deeper ATX heading inside a scanned Markdown declaration body is another declaration or carries a numeric or enabled named section coordinate. Fences, file titles, body-closing headings, source doc-comments, setext text, and bold labels are exempt. (unmarked headings — warning until it becomes an error in grund 0.15.0)
- Every stub heading
# <ID>: [<text>](<path>)points at a file containing the inline declaration. (broken stubs) - The
AGENTS.md/CLAUDE.mdentry-point block is up to date. (stale init) - Declared-but-uncited IDs are flagged. (unused — warning, not error; a configured
E2Ekind's cases are exempt) - (opt-in) With
require_grounding = true: every source file — or every file of one configured place, down to every##section or doc-comment block of it — carries at least one citation. (ungrounded source file) - (workspace) Alias-qualified citations resolve across configured sub-projects. (cross-project references — see §FS-workspace)
grund check reads what [scan] include names, so a citation in a directory the config never mentioned is invisible rather than merely unchecked — it neither resolves nor dangles. grund check --full (§FS-check.1.3) walks the whole repository past that key and reports the references that resolve to nothing out there, and only those: a directory nobody configured is never judged against conventions it never adopted. It is purely additive, so it can only turn a green run red.
A passing text check prints success and exits 0. Findings go to stdout as
<path>:<line>: error: <message>, warning:, or opt-in suggestion: lines:
errors come first, then warnings and suggestions, while the location remains the
jump-friendly prefix. grund check | … / grund check --format=json | jq work
without redirection (the linter convention — only run-level error: lines, like
an unreadable path, go to stderr). JSON output remains diagnostics-only and in
global location order, so a clean grund check --format=json prints nothing.
Exact-text consumers migrating from the former unmarked, global-location report
should use --format=json, whose bytes, object shape, and order are unchanged.
When you need a narrower answer without weakening the repository's default check,
select its stable finding codes: grund check --ignore agents-init asks whether
the remaining content report has errors, while repeatable --only <code> and
--ignore <code> compose as sets (§FS-check.1).
Selection happens only after the complete scan, and operational failures remain
visible; selected success describes only that view, not an all-findings
repository verdict (§FS-check.2).
grund does not check Markdown links, URLs, spelling, or grammar. Use lychee, vale, etc. for those.
In a monorepo, keep each sub-project as its own local namespace and let the root config orchestrate them:
project_name = "root"
[workspace]
members = ["apps/api", "packages/*"]
include_root = trueLocal citations stay short:
§FS-sessionCross-project citations add a stable alias before the ID:
§api/FS-session
§root/GOAL-compatibilitygrund check at the workspace root validates the root project and every member,
without letting root scans accidentally absorb member declarations, even if the
root [scan] include names a path inside a member. Members without
a grund.toml of their own use the canonical defaults, and a member that declares its
own [workspace] block is rejected in v1. Each project can also set a one-line
project_description next to project_name; grund init renders it beside
the alias in the generated workspace member list (see
§FS-config). Cross-repository aliases — an
alias like payments/FS-refunds resolving to a neighboring repo — are not yet
supported.
See §FS-workspace.
An independently checked project's canonical root also bounds directory
symlinks: outward directory targets are not scanned, including from inside a
workspace member, while in-root directory links, file links, and intentional
parent-relative [scan] include paths remain readable
(§FS-config.3.5.1).
A citable kind can opt its numbered fields into exact value checking:
An explicit [[kinds]] list replaces the implicit default kinds; copy the default rows from FS-config section 3.4.4 first, or existing declarations may disappear from list and check remains green because those kinds no longer exist.
[[kinds]]
kind = "CONST"
folder = "values"
index = false
format = "{kind}-{slug}"
values = true# CONST-field-price: Reference field price
## 1. 1200
The offer uses `1200.0` (§CONST-field-price.1).The backticks, one space, parentheses, marker, and positive numeric field are intentional syntax. grund check accepts exact decimal
equivalents such as 1200 and 1200.0, and reports value-mismatch if the authored component drifts.
A value can also live inside any ordinary scanned declaration without a
kind opt-in: end its numeric section heading with the exact marker, then give it
one contiguous level of numbered components (§FS-values.2.4):
# FS-pricing: Pricing rules
## 2. Regional floor <!-- grund:value -->
### 2.1. 1200
## 3. Use
The floor is `1200.0` (§FS-pricing.2.1).The marked section and component keep their ordinary dotted identities for
show, refs, completion, formatting, and editor navigation. JSON arrays at
an opted-in kind home can provide a whole declaration instead, so application
code can read the source directly. See the complete
first-class values guide and the runnable
examples/values/ repository (§FS-values).
External tickets and similar facts can use their own numeric grammar while the rest of the repository keeps slug IDs. Configure a committed snapshot home and one repository-owned fetcher, then materialize a cited fact deliberately:
[[kinds]]
kind = "TICKET"
file = "docs/tickets.md"
format = "{kind}-{number}"
resolve = "should"
fetch = "scripts/fetch-ticket"grund fetch TICKET-1234Checks, queries, formatting, completion, and the LSP never run that program;
they resolve only the committed Markdown it produced. A missing should
snapshot is a warning with the fetch command, while must remains an error.
See the external facts guide and runnable
examples/external-tickets/ repository
(§FS-fetch).
Every fact has a stable ID. The default kinds, all configurable — * marks a place rather than an ID namespace (citable = false: a home, a title and citation rules, no declarations), which is what a test is, and what any directory an agent must be told about can be. See Citation directions for the complete [citations] grammar and its rendered examples:
Repositories can also declare controlled-English constraints over declarations,
named chapters, and citations. The chapter-rules guide
lists every accepted sentence and refusal rewrite; the runnable
examples/rules/ repository demonstrates the findings and
deduplication behavior (§FS-rules).
| Kind | What it is | Where it lives |
|---|---|---|
GRUND |
Why: project motivation | docs/grund.md (one declaration, all of it inline) |
GOAL |
Where: project direction and outcomes | docs/goals.md (one file, all goals inline) |
FS |
What: behavior, requirements, and constraints | requirements.md |
AR |
How: high-level implementation, structure, and design | docs/architecture/ — or inline in a class / module doc-comment |
DF |
product behavior decisions and tradeoffs | docs/decisions/functional/ (append-only) |
DA |
architecture decisions and tradeoffs | docs/decisions/architectural/ (append-only) |
RM |
planned milestones and sequencing | docs/roadmap.md |
e2e * / integration * |
proof: the spec as a user sees it, and the parts fitting as designed | tests/e2e/ (must cite FS), tests/integration/ (should cite AR) |
ID format:
┌─────────────────── citation ───────────────────┐
┌───────────── ID ───────────────┐
[§] [alias /] KIND - [number -] slug [.section]
│ │ │ │ │ │
│ │ │ │ │ └─ dotted path of arbitrary depth (.3, .3.1, …)
│ │ │ │ └───────── [a-z0-9][a-z0-9-]* (default slug_pattern)
│ │ │ └─────────────────── optional ordinal (e.g., 001)
│ │ └─────────────────────────── GRUND│GOAL|FS│AR│DF│DA│RM│[custom]
│ └──────────────────────────────────── project alias for subprojects or monorepo
└────────────────────────────────────────── citation marker (writing only)
Three schemes are supported. [id].format selects the repository default; an
explicit [[kinds]].format may give one kind a different stable scheme, so
configured per-kind mixing is supported
(§FS-config.3.2). Each
scheme has a runnable tiny repo under examples/, maintained as a
detailed walkthrough for canonical user workflows
(§FS-examples).
| Scheme | Example | Benefit | Trade-off |
|---|---|---|---|
{kind}-{number}-{slug} (default) |
FS-014-user-login |
Number is stable; a number-only shorthand survives a slug change, while full-ID citations require deliberate updates (and canonical shorthand is reported for rewriting). | Two tokens to type; needs grund id to allocate the next number. |
{kind}-{number} (RFC-style) |
FS-014 |
Maximally stable — no slug to drift. Familiar from RFCs/PEPs/JEPs/ADRs. | Opaque at the call site: §FS-014 tells you nothing without resolving it. |
{kind}-{slug} (grund itself uses this) |
FS-user-login |
Self-describing — reads like English in prose and code. No number to allocate. | Renaming a slug rewrites every citation. Slug must be unique per kind. |
Rule of thumb: pick {kind}-{slug} until rename churn or ID count starts to hurt; switch to {kind}-{number}-{slug} when it does.
Changing that setting does not strand declarations already committed under an
older shape: their exact written IDs and exact marked citations remain readable
across the CLI and editor, while grund check points out each mismatch so you
can rename it or restore the matching format. The mismatch warns before 0.15.0
and becomes an error in 0.15.0; read compatibility remains in either case
(§FS-config.3.2).
A citation is the marker §, the ID, and an optional .<section> — with the target project's alias in front when the repo is a workspace:
§FS-user-login.3.1 # section 3.1 of FS-user-login
§api/FS-user-login.3.1 # the same section, in the `api` project of a workspace
Type $$ in a grund-aware editor and it's rewritten to § automatically. Both marker and trigger are configurable in grund.toml.
With the default {kind}-{number}-{slug} scheme, a persisted shorthand such as
§FS-042 is an error and grund fmt --write expands it to the descriptive full
ID. A project that deliberately wants both spellings may opt in
(§FS-config.3.1):
[reference]
shorthand = "accepted" # default: "canonical"Then §FS-042 and §FS-042-user-login resolve as the same citation, and
formatting preserves whichever marker form the author wrote. Typed trigger input
remains canonicalizing: $$FS-042 still becomes §FS-042-user-login
(§FS-fmt.2.4). The
tradeoff is permanent mixed-form drift while the policy is enabled: searching by
the number finds both forms, but searching by the slug misses shorthand sites,
and the short form is opaque until resolved.
The marker is the whole signal: a §-prefixed token is a live, checked citation wherever it appears — including inside Markdown backticks — except in a simple top-level Python assignment whose value is triple-quoted runtime data (§FS-check.1.1.3.1). To show an example ID that shouldn't resolve, write it without the marker (FS-user-login), inside a fenced code block (which is how the two citations above are written), or with the marker bracketed (<§>FS-user-login) — the escape grund check names in its own hint when a citation resolves to nothing. Put an intentional citation near assigned Python data in a # comment or a real docstring.
Specs can live inline in source. Declare the spec in a class or module doc-comment, then enroll it from the configured kind index with the canonical bare-ID link grund fmt --cross-refs writes — no stub file is required:
/// AR-event-bus: In-process event broadcaster
///
/// ## 1. Topology
pub struct EventBus { /* … */ }
// Kind index: - [§AR-event-bus](../../src/bus.rs)grund AR-event-bus reads the source declaration directly, strips the /// markers, and prints the Rustdoc prose. The same goes for Javadoc, JSDoc, Python docstrings, Go doc blocks, KDoc, Doxygen — every comment form enumerated in grund's scanner spec. A one-line Markdown stub remains supported when a separate pointer file is useful.
grund does this itself: §AR-checker lives only in the doc-comment of fn check in crates/grund-core/src/checker/report.rs, and its canonical row in docs/architecture/README.md enrolls it without a stub — grund AR-checker prints the source prose.
Before changing or removing a declaration, see what leans on it:
$ grund refs FS-check.3.2 --summary
crates/grund-cli/tests/index_entry_round_trip.rs: 1 (line 229)
crates/grund-core/src/checker/index.rs: 2 (lines 152, 258)
crates/grund-core/src/checker/references.rs: 2 (lines 2, 378)
crates/grund-core/src/checker/report.rs: 2 (lines 85, 486)
docs/decisions/functional/DF-duplicate-section-path.md: 1 (line 26)
docs/decisions/functional/DF-require-grounding.md: 1 (line 8)
docs/requirements/REQ-no-wrong-citation.md: 1 (line 7)Before reviewing a diff, group the citation graph by file so you can join changed files to the specs they touch:
$ grund cover --format json | jq -c 'select(.path == "crates/grund-core/src/checker/references.rs") | .citations |= map(select(.id == "FS-check" and .section == "3.2"))'
{"path":"crates/grund-core/src/checker/references.rs","citations":[{"path":"crates/grund-core/src/checker/references.rs","line":2,"column":23,"id":"FS-check","section":"3.2","marker":true,"text":"§FS-check.3.2"},{"path":"crates/grund-core/src/checker/references.rs","line":378,"column":12,"id":"FS-check","section":"3.2","marker":true,"text":"§FS-check.3.2"}]}For an agent reviewing a code change, the loop is mechanical: list the §… citations in the changed files, run grund <ID> on each, and ask "does the code still match what the spec claims?"
cargo install grundThat installs the grund binary from the grund crate on crates.io onto your PATH. npm and PyPI bindings are planned — see FS-distribution.
This README is itself under spec: §REQ-readme — every example above is captured from this repository, and the citations here are checked by grund check like any other scanned file's.
Turn a §<ID> in your terminal into something you click, landing at the exact line it cites:
grund integrations # what applies in this environment
grund integrations wezterm # read the snippet and the resolver first
grund integrations wezterm --write # install itSupported clients are codium, iterm2, kitty, tmux, vscode, and wezterm. --write is a one-time, idempotent user setup — the integration, the grund-open resolver, and a global instruction block for whichever agents you have installed. It changes no repository.
~/.local/bin must be on your PATH — that is where the resolver is installed, and it is not there by default on macOS, where a missing PATH entry makes every click silently do nothing.
Clickable citations is the full setup guide: the per-client reload each one needs, the manual step WezTerm and iTerm2 require, how to check it works, what to do when a click does nothing, and how to control the citations agents write in conversations. See also §FS-integrations.
🧑💻 Editor Support via LSP
Install the optional language server separately when you want editor diagnostics, hover previews, usage counts on declaration titles, definition jumps, document links, references, and live $$ → § formatting:
cargo install grund-lspThe server speaks LSP over stdio and has no daemon or socket. For IntelliJ
family IDEs, grund-lsp integrations lsp4ij --write <directory> generates the
LSP4IJ import template carried by the installed binary
(§FS-lsp.2.4).
The integrations subcommand is not included in published grund-lsp 0.13.1;
until the next release, install the workspace crate from source as described in
the LSP setup guide.
The setup guide has the complete import and
verification flow plus snippets for VSCode, Vim/Neovim, Emacs, Helix, Zed, and
Sublime Text. Put reusable client config in your editor's user (global)
settings, not a per-repo file, so grund-lsp works in every project rather
than only repos that ship an editor config.
Hover previews — the spec and the code that satisfies it, in one frame.
Error reporting — dangling citations are flagged inline with a "did you mean" hint.
Definitions & references — jump between a declaration and every §citation of it.
grund init # writes AGENTS.md and grund.toml in the cwd
grund init --docs # also scaffolds docs/ and tests/ trees
grund init --check # writes nothing; exits 1 if anything is still pendinginit is non-interactive and idempotent: re-running never errors on existing files. With --docs, instructional ID shapes follow the repository [id].format and any illustrated kind's [[kinds]].format override (§FS-config.3.2). For an existing repo with specs, map those homes in [[kinds]] before grund init, or run grund agent-setup-instructions for the packaged adoption workflow and decision table (§DF-skill-init-existing-specs). It also checks where it was pointed before writing anything: a target no .git, .hg, .jj, or .svn marker covers is refused unless you pass --no-vcs — use it to scaffold a directory before git init — and the home directory and the machine-global agent instruction files are refused outright. --check is the --dry-run preview taken as a verdict — same report, nothing written, exit 1 when a file is still pending — so a hook can fail on a managed block that drifted in its text while its version heading stayed current, which grund check does not see. See FS-init for the full state table.
The generated project name comes from --name when supplied, then from the target's existing project_name, and otherwise from the target directory name. This keeps the canonical AGENTS.md heading stable when grund init --force regenerates it; pass --name only when that run should override the configured identity (§FS-init.2.3.8).
This repo ships a ready-to-install .pre-commit-config.yaml — grund check for citations, grund init --check for a stale managed block, lychee for Markdown links:
pip install pre-commit && cargo install lychee && pre-commit installgrund --help is one screen; grund <command> --help is one page with flags, examples, and exit codes. The full surface is in docs/functional-spec/.
grund check— validate every reference in the tree.grund <ID>[.<section>]— print one declaration body, for pulling spec content into agent prompts.grund list— the ID catalog.grund refs <ID>— list every citation of a declaration.grund cover— group the citation graph by file, for git-diff recipes.grund fmt— normalize citation syntax ($$→§, optional Markdown link wrapping).grund fetch <ID>— explicitly materialize one configured external snapshot.grund id <KIND> "<title>"— emit the next conflict-free ID for a new declaration.grund init— scaffoldAGENTS.mdandgrund.toml.grund config— validate or print the effectivegrund.toml.grund completions— print bash, zsh, or fish completion scripts.grund agent-setup-instructions— print the guided setup workflow for AI agents.
The grounding loop, distilled to one rule for an AI agent's system prompt:
When you see
§<ID>or§<ID>.<section>in any file you are reading, rungrund <ID>[.<section>]and treat the output as the authoritative definition. Do not paraphrase or guess — quote whatshowreturned, or cite the ID and move on.
That rule plus a clean grund check is the whole contract: every reference resolves, except that a missing should snapshot is reported as a non-blocking warning, and every agent fetches the same bytes for the same ID.
grund follows its own scheme. Start at AGENTS.md, then read down through docs/:
docs/user-facing/clickable-citations.md— make citations clickable in your terminaldocs/user-facing/external-facts.md— materialize external tickets as committed offline snapshotsdocs/user-facing/point-sizes.md— measure point leads and opt into oversized-lead warningsdocs/user-facing/rules.md— write checked chapter and citation rules in controlled Englishdocs/user-facing/values.md— declare and check shared values in Markdown, JSON, prose, and code commentsdocs/grund.md— why this existsdocs/goals.md— what we measure ourselves againstdocs/roadmap.md— what's nextdocs/changelog.md— what changeddocs/functional-spec/— external behaviordocs/architecture/— internals: §AR-scanner for discovery, §AR-checker for validation, and §AR-core-module-layout for the core source layoutdocs/decisions/— how we got heretests/e2e/— executable proof that the spec holds;tests/integration/— proof that the parts fit as designed