Agent primer
AgenticMD — Agent Primer (v0.4)
Audience: software agents (LLMs, assistants, autonomous coding tools). Purpose: single-file reference. Paste this entire document into a prompt and the agent has everything it needs to read, write, and validate AgenticMD files.
You are reading this because someone wants you to operate on AgenticMD documents. By the end of this primer you should be able to: write a conformant
.amdfile, explain the rules, validate by hand, and know where to look for the canonical spec when this primer is insufficient.
0. Quick mental model
AgenticMD is a retrieval model for software-agent consumption of
documentation, expressed as a markup discipline for .md
documents. Files use the same .md extension as regular markdown —
there is no separate file format. AgenticMD is in the lineage of
Pandoc Markdown, MyST, and GitHub Flavored Markdown: a stricter
profile of CommonMark, asserted at the corpus level.
Conformance is declared at the corpus level by the presence of a
node_type: corpus_root file reachable from the directory. Within
that scope, .md files follow the discipline. (The .amd extension
was registered in v0.2 and deprecated in v0.4; it is accepted with a
warning during the v0.x window and will be removed in v1.0. See SPEC
§1.5 and DESIGN_NOTES.md “Why we dropped .amd.”)
The retrieval model is the substantive contribution. The markdown substrate is chosen for tool interoperability and human auditability, not for human authoring; other bindings (database, JSON-LD) could express the same model without breaking the spec.
Tagline: Agent-native. Human-auditable.
Audience. AgenticMD is defined, authored, and consumed by
agents. You (the agent reading this primer) own this format. You
write .amd files; other agents retrieve from them; this spec itself
was drafted by an agent under human direction, which is exactly the
authorship pattern it codifies. Humans interact with .amd files as
reviewers and arbitrators — they audit your output when trust
matters, but they are not the format’s authors. The writing rules
below are rules you apply to your own output so that
downstream agents can retrieve sections of your output safely AND so
that a human reviewing your output can do so without an intermediary
tool.
The thesis. Agents query documentation; humans read it linearly. A section retrieved as a 400-token chunk has no surrounding context — so writing that reads fine top-to-bottom often breaks under retrieval. The spec’s job is to identify the unit of retrieval (the typed section), the metadata for treating it correctly (the type and ID), and the writing constraints that make retrieval safe.
Core principles (load-bearing — keep these in mind when reasoning):
- No cross-section anaphora. This is THE writing rule. Sections must stand alone — no “as we saw above,” no bare pronouns whose referent lives elsewhere. See §0.5 for examples and how to fix.
- Codify what works, not what would be aesthetic. Every rule was extracted from a real corpus before it became normative.
- Markdown substrate is incidental, not load-bearing. The retrieval model is the contribution. Files MUST remain valid CommonMark — they render correctly in GitHub, IDEs, LLM context windows without AgenticMD-aware tooling.
- Structural conformance, not semantic. The validator checks shapes (required fields, enum membership, ID patterns); it does NOT check whether content is correct, accurate, or anaphora-free.
- Vocabularies are closed. Seven section types, three file
node_typevalues, sixstatusvalues. Adding a new value requires meeting the three-criterion gate in §1.7. - Agents treat verdicts as artifacts they OWN, not obstacles to bypass. A failing validator is signal, not friction.
0.5 The no-anaphora rule (the single load-bearing writing constraint)
Sections MUST NOT use anaphora that resolves outside the section.
This is the writing rule that makes AgenticMD work. Cross-section pronouns and back-references read fine in continuous human prose and break catastrophically when an agent retrieves one section as a chunk — the referent is gone, and the agent either hallucinates a referent or skips the chunk.
Anaphora that breaks retrieval:
- “As we saw above…”
- “Building on the previous section…”
- “The approach described earlier…”
- “This means we should…” (when “this” refers to content in another section)
- “It handles the same case…” (when “it” was named in a different section)
The fix is explicit naming and content-addressable cross-references.
Name what the section is about in the section’s own words. If a section
needs to reference another topic or section, link it with
[ref:topic-id] or [ref:topic-id#section-id], not with a pronoun.
Bad (breaks under retrieval):
## why-it-exists {#hotl-rationale node:decision}
This addresses the problem described above by inverting the iteration
mechanism. The result is what we discussed earlier — fewer interruptions
at the cost of more upfront tokens.
Good (retrieves cleanly):
## why-it-exists {#hotl-rationale node:decision}
HITL tools make the human the iteration mechanism. Every accept/reject
is a context switch costing 40s–3min. HOTL's bet is that a multi-agent
stack pays back its tokens by avoiding rework. See [ref:hotl#hotl-brief]
for the constraint this addresses.
The rule is normative on you (the writing agent) and informative on the validator. No validator can mechanically distinguish a cross- section pronoun from a within-section pronoun in arbitrary prose. If you’re writing a section, the discipline lands on you. When in doubt, ask: “if someone retrieved only this section as a chunk, would they have all the information they need to understand it?” If not, rewrite.
1. .amd specification
A .amd (or .md) file is a CommonMark document with this exact
structure, in order:
1. Frontmatter (YAML block, fenced by `---`, MUST be first)
2. Title (single `# ` ATX heading, OPTIONAL, not a node)
3. Brief section (first `##` heading, MUST be `## brief`)
4. Body (zero or more `##` typed-node sections)
5. See-also (optional terminal `##` section, untyped)
1.1 Frontmatter — required fields
| field | type | rule |
|---|---|---|
id | string | MUST match ^[a-z0-9][a-z0-9-]*$ (kebab-case). Globally unique within corpus. SHOULD match the filename stem (case-folded). |
cluster | string | Publisher-defined cluster name. MUST match ^[a-z0-9][a-z0-9-]*$. |
node_type | enum | One of: topic_root, corpus_root, reference. |
pinned | boolean | Whether this file survives long-term graph compaction. If uncertain, MUST be true. |
version | string | Per-topic semver of this document’s content. Pattern: ^v?\d+\.\d+(\.\d+)?([+-][A-Za-z0-9.+-]+)?$. Examples: 0.1, v0.18.0, v0.19.2+7. |
status | enum | One of: foundational, shipped, stable, living, evolving, in-progress. See §1.5. |
depends_on | list[string] | Topic IDs this topic depends on. MAY be empty. |
referenced_by | list[string] | Topic IDs that reference this topic. MAY be empty or the literal [all topics]. |
last_verified_against | object | {ref | sha: string, date: YYYY-MM-DD}. See §1.4. |
1.2 Frontmatter — optional fields
| field | type | meaning |
|---|---|---|
spec_version | string | number | Which AgenticMD spec version the file targets (e.g. 0.2). RECOMMENDED in v0.x, REQUIRED in v1.0. |
watches_files | list[string] | Source-artifact paths whose change should re-verify this topic. |
watches_paths | list[string] | Directory roots equivalently watched. |
drift_mode | enum | One of: silent, notify, auto. Default: notify. |
contact | object | Publisher-defined contact metadata. |
edition | string | Tolerated for backward compatibility with the AI Studio reference corpus. |
Publishers MAY add additional fields. Implementations MUST preserve unknown fields.
1.3 node_type enum
| value | meaning |
|---|---|
topic_root | Most files. The standard kind. |
corpus_root | Index files at the root of a corpus. |
reference | Pure reference documents (e.g. dictionaries, JSON Schema descriptions). |
1.4 last_verified_against
Declares the source-of-truth state against which the document was last verified.
last_verified_against:
ref: abc1234 # canonical key (or `sha:` as v0.x alias)
date: 2026-05-23 # ISO 8601 (YYYY-MM-DD)
dateis REQUIRED and MUST match^\d{4}-\d{2}-\d{2}$.refis the canonical source-identifier key — implementation-defined string (typically a short git SHA for git-backed corpora).shais accepted as a v0.x alias forref(legacy from the reference corpus). Implementations MUST accept both; v1.0+ may dropsha.
1.5 status enum
| value | meaning |
|---|---|
foundational | Load-bearing concept. Change requires restructuring. Rarely modified. |
shipped | Documents a feature present in current production builds. |
stable | Documented subject is feature-complete. Further change requires RFC. |
living | Expected to change in normal cadence by design (e.g. glossary, registry). |
evolving | Actively iterating. Expected to settle into shipped or stable. |
in-progress | Intent document ahead of implementation. Subject not yet feature-complete. |
1.6 Section marker grammar
Every ## heading that represents a graph node MUST carry a marker
of the form:
## <human title> {#<section-id> node:<node-type>}
Concrete examples:
## brief {#hotl-brief node:domain_brief}
## why-it-exists {#hotl-rationale node:decision}
## guardrail-do-not-interrupt {#hotl-guardrail-interrupt node:guardrail}
Section ID rules:
- MUST match
^[a-z0-9][a-z0-9-]*$. - MUST be prefixed with
{lowercase-kebab(frontmatter.id)}-. Example: topicid: hotlproduces IDshotl-brief,hotl-rationale,hotl-anti-mid-stream, etc. - MUST be unique within the file.
- SHOULD be unique within the corpus.
1.7 Section node-type vocabulary (CLOSED — 7 values)
The seven types are partitioned along the dimension of how each type interacts with the agent’s existing state. Each type is defined by a (purpose, retrieval, treatment) triple.
| type | purpose | retrieval | treatment |
|---|---|---|---|
domain_brief | state what the topic is | load first as cheap relevance probe | trust as authoritative summary |
architecture_note | explain how a thing works | load when implementing or modifying the thing | descriptive; summarizable |
decision | declare a choice with rationale | load when changing the thing decided | rationale is load-bearing; never discard the “why” |
guardrail | prevent a known failure mode (per task) | load whenever the topic is in scope | MUST NOT elide, summarize away, or override |
correction | declare a position has changed | load instead of older claims it overrides | invalidates prior statements on the same subject |
failure | document an anti-pattern | load when symptoms match | diagnostic, not instruction |
project_rule | declare operating posture or cross-task dispatch rule | load into persistent context, not task context | applies across all task contexts |
Dimension mapping — each type occupies a distinct region:
| relation to agent state | type |
|---|---|
| gates further loading | domain_brief |
| adds to knowledge | architecture_note |
| adds to knowledge + locks rationale | decision |
| subtracts from action space (per task) | guardrail |
| invalidates prior knowledge | correction |
| conditionally activated by symptoms | failure |
| modifies operating posture across tasks | project_rule |
guardrail vs project_rule — both are negative-on-actions but at
different scopes. guardrail narrows the action space for a specific
task (“never rm -rf in this codebase”). project_rule modifies the
agent’s operating mode across all tasks (“when in HOTL mode, prefer
non-interactive solutions”). If the rule applies to a specific action
in a specific task → guardrail. If it applies to how the agent
approaches every task → project_rule.
Agents writing .amd files MUST use exactly these seven values.
Introducing a new node: value (e.g. node:warning, node:tip) is a
spec violation — they fold into existing types:
node:warning→guardrail(if it forbids) orcorrection(if it invalidates a prior claim)node:tip→architecture_note(just write it as descriptive)node:example→ currently folds intoarchitecture_notebody (watchlist candidate for v1.0; see SPEC.md addition gate and DESIGN_NOTES.md)
If a section truly doesn’t fit one of the seven, the right move is to pick the closest match and rewrite the section to fit, not to invent a new type.
1.8 Required sections
## brief — MANDATORY first section (≤80 words)
The first ## heading in every file MUST be:
## brief {#<topic-id>-brief node:domain_brief}
The brief body MUST contain no more than 80 whitespace-separated words. This is a cheap relevance probe — it exists so an agent can pull the briefs of 20 topics for less context than pulling one full topic, decide which matters, then pull deeper. Briefs over the cap collapse the probe value and fail conformance.
Write briefs as compressed orienting statements, not as topic summaries.
## see-also — OPTIONAL terminal section
## see-also
- [ref:other-topic]
- [ref:another-topic#some-section]
NO node-type marker. Body is a bullet list of [ref:...] items.
Treated as edge-summary metadata, NOT as a graph node.
This is the only untyped ## section permitted. Any other untyped
## is a violation.
1.9 References (content-addressable)
[ref:topic-id] → resolves to topic root
[ref:topic-id#section-id] → resolves to a specific section node
- Resolution is by ID against the corpus. NOT URLs. NOT relative paths.
- References inside fenced code blocks (
```) and inline backtick spans (`…`) are STRIPPED before validation and ingestion — example refs in documentation don’t count. - References to topics that don’t exist in the corpus are not file-level
failures (a
.amdfile is valid even if it points at topics not yet written). Resolution is a corpus-level concern.
1.10 Conformance — the validator’s checks
A .amd (or .md) file is conformant v0.2 if and only if:
- Frontmatter is a valid YAML block with all §1.1 required fields.
idmatches^[a-z0-9][a-z0-9-]*$.node_typeis in §1.3 enum.statusis in §1.5 enum.versionmatches the semver-ish pattern in §1.1.last_verified_againsthasdate(ISO 8601) plus eitherreforsha.pinnedis a boolean.- Every
##section other thansee-alsocarries a marker matching{#<id> node:<type>}with<id>per §1.6 and<type>in §1.7. - The first
##section isbriefwithnode:domain_brief. - Section IDs are unique within the file and prefixed with
{frontmatter.id}-. - All
[ref:...]references in non-code body content are well-formed.
2. File extensions and versioning
2.1 Extensions
| extension | role |
|---|---|
.amd | Canonical AgenticMD document extension as of v0.2. |
.md | Legacy synonym; accepted in v0.x for backward compatibility. May be deprecated in v1.0. |
A file’s extension does NOT determine its conformance rules — the
node_type field governs validation. Extensions are filesystem-level
identity hints.
2.2 Versioning
spec_versiondeclares which AgenticMD spec version a file targets.versionis the file’s own content semver (independent of spec).- Files at
spec_version: 0.1need NOT migrate when v0.2 ships; v0.2 changes are additive.
2.3 Drift monitoring (informative)
watches_files, watches_paths, and drift_mode support an optional
pattern: a “drift monitor” process re-verifies topic correctness when
watched artifacts change.
drift_mode values:
silent— record drift in metadata; no action.notify— surface a notification to the publisher.auto— open a re-verification task automatically.
The mechanism is not mandated; field names are standardized for implementations that adopt it.
3. Canonical examples
3.1 Minimal .amd
---
id: minimal
cluster: example
node_type: topic_root
pinned: true
version: v0.1.0
status: in-progress
depends_on: []
referenced_by: []
last_verified_against:
ref: abc1234
date: 2026-05-23
---
# minimal
## brief {#minimal-brief node:domain_brief}
A minimal AgenticMD topic file. Just enough fields to pass all v0.2
conformance rules.
3.2 Full .amd
---
id: hotl
cluster: examples
node_type: topic_root
pinned: true
version: v1.0.0
spec_version: 0.2
status: foundational
depends_on: []
referenced_by: []
watches_files:
- some/source/file.dart
watches_paths: []
last_verified_against:
ref: abc1234
date: 2026-05-23
drift_mode: notify
---
# hotl
## brief {#hotl-brief node:domain_brief}
HOTL — Humans Out Of The Loop — is a design constraint for agent-first
systems.
## why-it-exists {#hotl-rationale node:decision}
HITL tools make the human the iteration mechanism. Every accept/reject
is a context switch. HOTL's bet: a multi-agent stack pays back its
tokens by avoiding rework.
## guardrail-do-not-interrupt {#hotl-guardrail-interrupt node:guardrail}
**Never intervene mid-generation unless a hard boundary is at stake.**
Interrupting mid-stream wastes the rework already paid for.
## correction-never-route-around {#hotl-correction-route node:correction}
When the system flags a verdict, the wrong move is to bypass it. The
verdicts ARE the system. **Always investigate the verdict; never route
around it.**
## anti-pattern-mid-stream {#hotl-anti-mid-stream node:failure}
**Symptom:** operator interrupts a streaming response.
**Why it fails:** the correction enters as next-turn input anyway; no
time saved, queue contention added.
**Right move:** wait for the turn, read the result, send a follow-up.
## stance {#hotl-stance node:project_rule}
Trust the verdicts. Read artifacts, not streams.
## see-also
- [ref:agenticmd]
4. How agents should USE this format
4.1 When asked to write a .amd file
- Derive
idfrom the topic name (kebab-case, no extension). - Write the frontmatter — all 9 required fields,
spec_version: 0.2. - Write
# <id>as the title (optional but conventional). - Write
## brief {#<id>-brief node:domain_brief}FIRST. One paragraph saying what the topic is. - Add 2-10 more
##sections, each with a marker. Choose the rightnode:typefrom the closed vocabulary in §1.7 — don’t invent. - Use
[ref:other-topic]to point at related topics. - End with optional
## see-also(untyped, bullet list of refs). - Verify your section IDs all start with
<id>-. - Verify your first typed section is
briefwithnode:domain_brief.
4.2 When asked to validate
Run the CLI:
agenticmd validate <path>
Paths can be files or directories. Directories are walked recursively.
All discovered files validate together so cross-file [ref:...]
resolution works.
Or use the Dart library:
import 'package:agenticmd/agenticmd.dart';
final topic = parseAmdFile('my-topic.amd');
final violations = AmdRules.runAll([topic]);
if (violations.isEmpty) print('Conformant');
else for (final v in violations) print(v);
4.3 When asked to extend or modify
- A new
node:typevalue: REJECT and explain. The vocabulary is closed. If the use case is real, the right move is to open an issue against the spec, not to inline a new value. - A new top-level frontmatter field: ACCEPT. Publishers MAY add fields; implementations MUST preserve unknown fields.
- A new
statusvalue: REJECT. Same reasoning as node types — closed enum. - A different file extension (e.g.
.adoc): REJECT. AgenticMD is CommonMark; if you want a different substrate, you want a different spec. - Bypassing a validator rule: REJECT. Validator rules pin load-bearing properties; bypassing them silently destroys the property the rule was protecting.
4.4 When YOU are validated and fail
The validator names a rule ID like amd.frontmatter.status_enum. To
fix:
- Read the rule ID. The middle segments narrow down which check.
- Read the violation message — it usually quotes the offending value.
- Fix the file, NOT the validator. The validator is the gate, not the convention.
- Re-run validation to confirm.
5. Common pitfalls (agent edition)
The most frequent ways agents writing AgenticMD go wrong.
| pitfall | symptom | fix |
|---|---|---|
| Cross-section anaphora (“as we saw above,” bare “this/that”) | NO validator check (informative rule) — but the chunk becomes useless at retrieval time | Rewrite section to stand alone. Name things explicitly. Use [ref:topic-id#section-id] instead of pronouns. See §0.5. |
| Brief longer than 80 words | amd.sections.brief_length fires | Trim. The brief is a relevance probe, not a topic summary. Compress to the orienting essentials. |
Invented node: type | amd.sections.node_type_vocab fires | Re-read §1.7. Pick from the 7 closed values. node:tip → architecture_note. node:warning → guardrail or correction. |
| Section ID doesn’t match topic prefix | amd.sections.id_prefix fires | Section IDs MUST be <frontmatter.id>-<suffix>. |
First section isn’t brief | amd.sections.brief_id fires | Reorder — ## brief {#<id>-brief node:domain_brief} MUST be first typed section. |
Numeric-looking ref value | amd.frontmatter.last_verified_against_ref fires | YAML auto-types 0000000 as int 0. Quote it ("0000000") or use alphanumeric (0a0a0a0). |
Untyped ## section other than see-also | amd.sections.untyped_only_see_also fires | Every ## other than see-also MUST carry a {#id node:type} marker. |
node_type: topic instead of topic_root | amd.frontmatter.node_type_enum fires | The enum is exactly: topic_root, corpus_root, reference. |
Free-text status | amd.frontmatter.status_enum fires | Pick from the 6 values in §1.5. |
[ref:...] to a topic that doesn’t exist in same corpus | amd.refs.topic_resolves (corpus-level) | Either write the missing topic, remove the reference, or accept the warning (it’s a corpus-level check, not file-level). |
Using guardrail for a posture (or project_rule for a per-task action) | NO validator check (semantic) — but the wrong type misroutes agents | If it’s a per-task action constraint → guardrail. If it’s a cross-task operating mode → project_rule. See §1.7. |
6. Where things live
| Thing | Location |
|---|---|
| Canonical spec (normative) | SPEC.md (this repo) |
| Design rationale (informative) | DESIGN_NOTES.md — why the dimension, alternatives considered, watchlist for example and open_question |
| JSON Schema for frontmatter | SCHEMA.frontmatter.json |
| Reference Dart library | lib/agenticmd.dart + lib/src/ |
| Reference CLI | bin/agenticmd.dart |
| Worked example | examples/hotl.amd |
| Fixture-based tests | test/amd_test.dart + test/fixtures/ |
| This primer | AGENT_PRIMER.md (you are here) |
| README + getting started | README.md |
| Changelog | CHANGELOG.md |
| Contributing guide | CONTRIBUTING.md |
Reference corpus at scale (the first adopter, where the format was
extracted from): the AI Studio project’s docs/book-ai/ directory
(~74 .amd topics).
Tri-licensed:
- Spec text (SPEC.md, README, CHANGELOG, schemas) — CC-BY-4.0
- Code (lib/, bin/, test/ excluding fixtures) — MIT
- Examples and fixtures (examples/, test/fixtures/) — CC0
7. Glossary
| term | meaning |
|---|---|
| AgenticMD | The format described in this primer. Typed markdown documents for agent corpora. |
| .amd | The canonical AgenticMD file extension. Markdown + frontmatter. |
| .md | Legacy synonym for .amd; accepted in v0.x for backward compatibility. |
| Brief section | The mandatory first ## section in every .amd file. Type: domain_brief. |
| Cluster | Publisher-defined grouping of topics. A repo MAY contain multiple clusters. |
| Conformance | A file is conformant if it passes every applicable rule in §1.10. |
| Content-addressable reference | [ref:topic-id] syntax. Resolves by ID against the corpus, not by file path. |
| Corpus | A directory tree of .amd files reachable through recursion from a corpus root. |
| Corpus root | A file with node_type: corpus_root. Typically an INDEX or hub file. |
| Drift monitoring | Optional pattern: when watched source artifacts change, re-verify the documents that describe them. |
| Frontmatter | YAML block at the top of a .amd file, fenced by ---. |
| Graph node | An atomic chunk of meaning that can be loaded into an agent’s context window in isolation. Every ## section in a .amd file is one. |
| Node-type vocabulary | The 7 closed values for the node: field in section markers. |
| Reference corpus | A real-world corpus that the spec was extracted from or that demonstrates the format at scale. |
| spec_version | Which AgenticMD spec version a file targets. |
| Topic | A single .amd file. The unit of organization. |
| Topic root | A file with node_type: topic_root. The default and most common file kind. |
| Validator | The mechanical conformance check. Implements §1.10. |
| version | The file’s own content semver, independent of spec version. |
8. The one-line summary
AgenticMD lets you write knowledge as typed, content-addressable, drift-monitored, agent-consumable markdown documents — no new parsers required.
If you forget everything else, remember that. Then come back to §1 for the details.