# How an agent reads this manual {#root}

@status:doc/work @audience:agent

[p01] This manual is published for machines as much as for people. An agent can fetch any page as plain text, ask where a rule lives, and load the whole corpus in one file sized to its budget.

## The machine files {#the-files}

[p02]
| Address | What it is | When to read it |
| --- | --- | --- |
| `https://vibevm.org/doc/llms.txt` | the index: one line per page, the page's first paragraph | first, to choose a page |
| `https://vibevm.org/doc/<package>/<version>/<page>.md` | one page as plain Markdown, block numbers included | to answer one question |
| `https://vibevm.org/doc/<package>/<version>/<page>.xml` | the same page in its source form, with every rule address and example intact | to quote a rule or run an example |
| `https://vibevm.org/doc/llms-small.txt`, `llms-medium.txt`, `llms-full.txt` | the corpus in three sizes, stable text first | only when a task spans many pages |
| `https://vibevm.org/doc/manifest.json` | every page with its language, audiences, status and anchors | to navigate programmatically |
| `https://vibevm.org/doc/resolve/?uri=spec://…` | the resolver: an address in, the page and block out | when a message or a page cites an address |
| `https://vibevm.org/doc/ru/…` | the same files for another language | when the user reads that language |

> [p03] publish `llms.txt` (an index with one-line summaries) and `llms-full.txt` for the base corpus, plus `llms-small.txt` and `llms-medium.txt` under a token budget, all derived from the same manifest as the navigation, the full corpus ordered by the layer law (stable before mutable); the same files per language and per package; the registry `llms.txt` is a catalogue of documentations in the arXiv style — title, officiality star, publisher, language, audiences, abstract, link;
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#SEO-LLMS-FILES>

> [p04] serve every page as clean Markdown at the address with the `.md` suffix and as raw XML at the `.xml` suffix;
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#SEO-RAW-PROJECTIONS>

[p05] The site also serves the page manifest, a JSON list of every page with its statuses, languages, audiences and anchors, at `/doc/manifest.json`, and resolves a `spec://` address at `/doc/resolve/?uri=…`; `<package>` is the group and name of the manual, `org.vibevm.core/vibevm-docs`, and `<version>` is a number or `latest`.

> [p06] serve the JSON page manifest with officiality statuses, languages, audiences, genres, anchors and summaries (`/doc/manifest.json`), a resolver endpoint for `spec://` addresses (`/doc/resolve?uri=…`), and optionally an MCP server of the site;
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#SEO-MANIFEST-AND-RESOLVER>

## Without a network {#offline}

[p07] The same pages live in the machine [store](../glossary/index.xml#store) once `vibe cache add org.vibevm.core/vibevm-docs` has run. `vibe explain "spec://org.vibevm.core/vibevm-docs/<page>#<anchor>"` prints a page or a block; `vibe doc manifest --llms small` prints the page list from the store. Nothing on this path contacts the network, which is why proprietary documentation is read this way.

> [p08] The store is warmed with `vibe cache add <coordinate>` from a registry, or `vibe cache add --offline <coordinate>` from a project root whose project-local registry holds the package in-tree; the sources of `vibe-doc` are the store (`lookup`, `list_all`), the lock file (`Lockfile::read`, `slot_abs_path`), a registry (`resolve_and_fetch`) and a checkout (`LocalRegistry`).
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#LOCAL-WARMUP>

## Citing a place {#citing}

[p09] Every block on a page carries a number, `p12` and so on, assigned when the page is built and the same in the web page, the Markdown and the XML. A citation is the page address plus that number: `spec://org.vibevm.core/vibevm-docs/model/boot-lane#p7`. Headings keep their named [anchors](../glossary/index.xml#anchor) as well, and a named anchor never changes once published; a [block number](../glossary/index.xml#block-number) names the current text and may shift after an edit, like a line number.

> [p10] **Numbered blocks.** Every flow block of the pivot — paragraph, list, table, fence, quote, `example`, `rule`, `note`, `figure`, `prompt`; a heading keeps its own id and is not numbered (clarified 2026-09-12 at implementation, following `PIPE-NUMBERING`) — receives an ordinal number and the id `pNN` **at build time** in the Rust pipeline (§10), never by a client script. The number is the block's position in the **current** text of the page, counted before `when` filtering, so that `p12` names the same block in the build for any platform and agent and in every translation; gaps in the rendered output are accepted. The number appears in the HTML island, in the `.md` and `.xml` projections (as `[p12]` at the start of the block) and in `llms-full.txt`, so a human and an agent cite one place. After an edit an old `#p12` may point at a neighbouring block, as a link to a file line does after an edit; this is accepted and nothing tries to «remember» it. Headings keep their named anchors `{#id}` above the number; named anchors are immutable and renamed only by tombstone, positional `pNN` live by the current text.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#READER-NUMBERED-BLOCKS>

[p11] Rules on a page are quoted from the [specification](../glossary/index.xml#specification) by address and shown in the specification's own language. Prefer the address of the specification over the address of the manual when you tell a user what a rule says; prefer the manual's page when you explain why.

> [p12] Every `rule` yields a `documents` edge **without a pin**: the citation is live, and the page shows the fact's current text by address at every render. `vibe doc check --citations` checks one thing — that the anchor exists; a vanished anchor without a tombstone fails the build. There are no revisions, no text hashes and no «the spec moved ahead»: such checks would need a history the project does not keep by design.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#OBS-RULE-EDGE-UNPINNED>

## The procedure the skill teaches {#procedure}

[p13] 1. On an error, read the address the message names, then the page the diagnostics page maps it to.

[p14] 2. On a question, answer from one page: the first paragraph is the plain answer, the rule blocks carry the exact wording.

[p15] 3. On a task, take the page's request block as your task and substitute the user's names and paths. Run it, then run the asserts. The task is done when every assert exits zero.

[p16] 4. When choosing among documentations of one package, prefer the one marked official and name the publisher of a community one.

[p17] 5. Never load the full corpus when one page answers.

> [p18] The audience vocabulary of PROP-043 gains `agent`; `user`, `author` and `dev` stay. Text marked `audience="agent"` obeys the laws of agent text: a token budget, no narration, and **never in a boot prefix** — the site serves it in the «for agents» section and first in `llms.txt`. Audiences are not declared in the manifest; they are derived from the page markup.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#OBS-AUDIENCE-AGENT>

## The tools of the server {#the-tools}

[p19] `vibe mcp serve` offers the same operations as tools. `explain` looks at one node of the map by address; `query` finds nodes, and the two are separate verbs on purpose. `select` takes up to seven predicates, `uri:`, `symbol:`, `kind:`, `scope:`, `has:`, `lacks:` and `depth:`, whitespace separated and joined by AND, with no operators. An unknown predicate, a repeated one or an empty query is an error that names the token and lists what was expected.

> [p20] **`query` finds nodes; `explain`
> looks at one.** Until 2026-08-06 the map could only be asked about a target
> already known by name, so *«which of these exist?»* was unanswerable — not in
> the host, not in any language stack, not in the engine. `query` is that
> question, and the two are deliberately separate verbs rather than one verb with
> a mode: a point lookup and a set filter render differently, cap differently, and
> fail differently.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#MAP-QUERY-ANSWERS-A-DIFFERENT-QUESTION>

> [p21] **Seven predicates, whitespace
> separated, joined by AND, and no operators at all:** `uri:`, `symbol:`, `kind:`
> (the filter level's own), `scope:` (prefix of a spec address), `has:` / `lacks:`
> (an edge verb), `depth:` (0..3). No disjunction, no parentheses, no precedence —
> each of those is a permanent versioning liability, and a predicate can be added
> without renumbering a language that has no operator layer to renumber.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#SELECT-SEVEN-PREDICATES-JOINED-BY-AND>

> [p22] **An unknown predicate, an unknown
> verb, a repeated predicate, an out-of-range depth or an empty query is an ERROR
> that names the offending token and lists what was expected** — never a silently
> ignored clause. Same law as the markup's typed fences, for the same reason: a
> grammar that ignores what it does not understand promises everything and checks
> nothing, and whoever trusted the promise is the one who finds out. An empty query
> is refused rather than read as «everything», because that answer already exists
> one verb away.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#SELECT-AN-UNKNOWN-PREDICATE-IS-AN-ERROR>

[p23] `query_package` returns the full lock entry of an installed package. `read_subskill` returns the content of an active [subskill](../glossary/index.xml#subskill) wherever it lives, in the project tree or in the machine store. `materialise_subskill` copies a lazily pulled subskill into the project tree and refuses to overwrite without `force`; it is the one tool that writes.

> [p24] **`query_package`** — the full lockfile entry for an installed package
>   (kind, version, `content_hash`, registry, source, `files_written`,
>   features, active subskills, `describes` PURL, language). Read-only.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#TOOL-QUERY-PACKAGE>

> [p25] **`read_subskill`** — the concatenated content of an active subskill's
>   files. `eager` / `lazy-push` subskills read from the project tree;
>   `lazy-pull` subskills read from the package cache (PROP-003 §2.5.0), so
>   the agent gets bytes regardless of delivery mode. Read-only.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#TOOL-READ-SUBSKILL>

> [p26] **`materialise_subskill`** — copy a `lazy-pull` subskill's content into
>   the project tree. No-op for `eager` / `lazy-push` (already on disk);
>   refuses to overwrite without `force`. The one writing tool.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-015#TOOL-MATERIALISE-SUBSKILL>

[p27] The language packages of the `mcp` kind bring servers of their own with four tools, `tcg_validate`, `tcg_scope`, `tcg_complete` and `tcg_type`: thin adapters over the operations of the same names. Each takes a required `language`, `typescript` or `rust`, and the operation's own parameters unchanged. Each answers with the enriched result as structured content plus a short text with the findings first.

> [p28] The tools now ship in the per-language
>   `mcp`-kind packages ([PROP-027](PROP-027-mcp-packages.xml):
>   `mcp:org.vibevm.ai-native/rust-ai-native-mcp`, `…/typescript-ai-native-mcp`), each
>   serving its own language over the vendored `mcp-core` transport.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-026#TOOLS-NEW-HOME>

> [p29] `tcg_validate`, `tcg_scope`, `tcg_complete`, `tcg_type` — thin schema
> adapters over the TCG-PROTOCOL ops of the same names, each with:
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-026#FOUR-TOOLS>

> [p30] `language` (required; accepts `"typescript"` and — since the Rust
>   twin landed, exactly as this clause promised — `"rust"`; any other
>   value is a ToolError NAMING the supported set, so the next language
>   adds an enum value, not new tools);
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-026#PARAM-LANGUAGE>

> [p31] the op's own params per TCG-PROTOCOL §2 (`file`, `position`,
>   `content`, …), passed through verbatim.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-026#PARAMS-PASSTHROUGH>

> [p32] Responses return the ENRICHED protocol result (TCG-PROTOCOL §3) as
>   `structuredContent`, plus a compact human text rendering (findings
>   first).
>
> <spec://org.vibevm.core/vibevm/modules/vibe-mcp/PROP-026#ENRICHED-RESPONSES>

## Edge cases and rules {#edge-cases}

[p33] Text written for agents is never part of a project's [boot lane](../glossary/index.xml#boot-lane); this manual is fetched when needed, not read at every session start.

> [p34] **No documentation page enters `STATIC.xml`, `INDEX.md` or a boot snippet.** A `doc` package has no `[boot_snippet]`; agent-audience text is never in a boot prefix.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#INV-DOC-NEVER-BOOTS>

[p35] The boot lane itself is pure file reading: nothing in it executes, and the manual is not on it.

> [p36] Boot remains **pure file-reading** — the redirect never becomes "run `vibe`", preserving the zero-dependency cross-agent property of `VIBEVM-SPEC.md` §6.1.
>
> <spec://org.vibevm.core/vibevm/modules/vibe-workspace/PROP-009#PURE-FILE-READING>

[p37] A page that exists in the source language but not in the language you asked for is served in the source language under the address you asked for, with a note; do not treat it as missing.

> [p38] **Switching the language keeps the place.** The language selector leads to the same page in the other language **with the same fragment** (`#pNN` or `#id`), which the block-for-block mirror of §5 makes possible. When the page does not exist in the chosen language, the site serves the source language under the chosen language's address as a statically materialised fallback (`<html lang>` of the source, `rel=canonical` to the source page, `noindex`), shows a bilingual notice «this page is only in … so far» once per session, and rewrites internal links so navigation stays in the chosen language. The chosen language is remembered in the cookie `lang` for 365 days — the same name the landing uses, so the domain root and `/doc/` remember one choice.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#READER-LANGUAGE-SWITCH-KEEPS-PLACE>

