# Traceability: specs, code and the map {#root}

@status:doc/work @audience:dev

[p01] Every public piece of code in vibe points at the rule it implements, and a generated map lets you ask in either direction: which code implements this rule, which rule does this code answer to.

[p02]
```sh
vibe explain "spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET"
```

```output
spec unit spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET
  unmarked — `kind ∈ {flow, feat, stack, tool, mcp, lang, doc, app}` — eight kinds; `mcp` shipped with [PROP-027](../modules/vibe-mcp/PROP-027-mcp-packages.xml); `doc` and `app` admitted by [PROP-057](PROP-057-documentation-packages-and-site.xml) through the `VIBEVM-SPEC.md` §4.1 amendment of 2026-09-12 (pending the owner's ratification at the merge of the docs-2026-09 branch; the code learns the two kinds in that campaign's phase 2). (§Invariants `INV-VOCABULARY` in this file carries the same list.) <status stage="spec" state="done" action="continue" actionstage="impl"/> (vibevm/vibespecs/common/PROP-000.xml:75)
  hash sha256:1effee7da317e236ec9b0745d0e02f922cd93134fd731a758428dce62db2a81f
  edges in:
    documents ← `authoring::write-a-lang-package` (vibevm/vibepacks/org.vibevm.core/vibevm-docs/v1.0.0/vibevm/vibespecs/authoring/write-a-lang-package.xml:14)
    documents ← `glossary::index` (vibevm/vibepacks/org.vibevm.core/vibevm-docs/v1.0.0/vibevm/vibespecs/glossary/index.xml:107)
    documents ← `model::packages-and-kinds` (vibevm/vibepacks/org.vibevm.core/vibevm-docs/v1.0.0/vibevm/vibespecs/model/packages-and-kinds.xml:45)
```

## Marks in the code {#marks}

[p03] A Rust item that implements a rule carries an attribute naming the rule's address; a test that verifies one carries a verifying attribute; a module that serves one section as a whole declares a scope. The links live in the code, beside the thing they describe, so they travel with every refactor and every copy. The verbs are `implements`, `verifies`, `documents`, `deviates` and `informs`; a deviation must say why.

> [p04] **Edges travel with the artefacts.** Code-side links live *in the code* (attributes on items) and survive any refactor that moves the item. Spec-side links live *in the spec* (stable anchors). External sidecar maps are rejected (§5.1).
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#FORCE-EDGES-TRAVEL-WITH-THE-ARTEFACTS>

> [p05] **Verbs:** `implements`, `verifies`, `documents`, `deviates`, `informs`. `deviates` REQUIRES `reason`.
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#RULE-VERBS-AND-MANDATORY-REASON>

[p06] `implements` is a claim about code that runs. A type declaration does not carry it: an edge from a declaration is indistinguishable from coverage, and a map that counted declarations would be green about nothing.

> [p07] **`implements` is a claim about code that RUNS, and a bare declaration does not carry one.** A trait, an abstract signature or any other declared shape that no production code implements gets no `implements` edge, however faithfully it describes the requirement. The edge arrives with the implementation.
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#RULE-IMPLEMENTS-IS-A-CLAIM-ABOUT-CODE-THAT-RUNS>

## The map {#the-map}

[p08] `cargo xtask specmap` walks the crates for marks and the [specification](../glossary/index.xml#specification) tree for units, and writes `specmap.json`: nodes for every spec unit with its revision and content hash, nodes for every tagged code item, and the edges between them. The map is committed, and `cargo xtask specmap --check` fails when the tree moved and the map did not. The policy of what is scanned, which crates are gated and which are exempt lives in `specmap.toml`; the engine itself ships with the discipline package and is vendored, never edited in place.

> [p09] **Invariants are machine-checked.** Dangling references, uncovered requirements, orphan code, and — the load-bearing one — **staleness**: a spec unit carries a revision + content hash; when it changes, every edge pinned to the old revision flips to *suspect* until re-affirmed.
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#FORCE-INVARIANTS-ARE-MACHINE-CHECKED>

[p10] Three gates guard the map. The *orphan ratchet*: a public item in a gated crate without a mark fails the check, unless it is dispositioned with a debt id. The *resolve gate*: every edge into this project's own namespace must land on an existing [anchor](../glossary/index.xml#anchor). The *suspect rule*: when a spec unit's revision bumps, every edge pinned to the old revision becomes suspect and the check names it, so the code is re-read against the rule that moved.

> [p11] Spec unit `r` bumps → every edge pinned to the old `r` becomes **suspect**; CI gate lists them; each is cleared by re-affirming (updating the pin) after review.
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#INVALIDATION-SPEC-BUMP-MAKES-EDGES-SUSPECT>

[p12] Generated code is excluded from the orphan gate; the generator's input, the schema, carries the marks instead, and a schema scanner reads them.

> [p13] **Generated code** (e.g. `vibe-wire/src/generated/`) is excluded from orphan checks via a directory marker; the *generator input* (JTD schema file) is the taggable unit instead. *BUILT 2026-08-05 — both halves are now real. The exclusion half always was: `rscan` and `ratchet` skip a path containing `/generated/`. The designation half was a decision nobody could act on, because no scanner opened a `.json` at all and the edge model hangs an address off a code SYMBOL, which a JSON document has no obvious equivalent of. Both are answered: a schema's units are its ROOT and each `definitions` entry (`symbol` = `<stem>` and `<stem>::<def>`, `item_kind` = `schema` / `schema-def`), and the tag lives in JTD's own `metadata.spec` block as a verb → URI map. The scanner is opt-in per project through `schema_roots`, empty by default. Measured on the host that raised this: seven wire contracts tagged, 16 units and 7 edges in the map, and `vibe explain` now answers «what implements PROP-000 §16» with all seven, by file and line.*
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#RULE-GENERATED-CODE-IS-EXCLUDED>

## Asking the map {#asking}

[p14] The commands below run in a checkout of vibe itself, whose specifications carry a map; an installed package answers only if it shipped one. `vibe explain "spec://…#anchor"` builds the map fresh in memory and prints one target's subgraph: what implements, verifies or documents it. `vibe query` filters the map by address, symbol or kind and returns the many nodes that fit. `vibe select --where "lacks:verifies scope:spec://…"` walks the graph with a predicate: every rule with no verifier, the implementers of a rule and one hop around them. `--json` gives each answer to an agent.

[p15]
```sh
vibe select --where "uri:spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET depth:1"
```

```output
map select · grammar v1 · uri=spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET AND depth=1
4 results

  d0 spec -          `kind ∈ {flow, feat, stack, tool, mcp, lang, doc, app}` — eight kinds; `mcp` shipped with [PROP-027](../modules/vibe-mcp/PROP-027-mcp-packages.xml); `doc` and `app` admitted by [PROP-057](PROP-057-documentation-packages-and-site.xml) through the `VIBEVM-SPEC.md` §4.1 amendment of 2026-09-12 (pending the owner's ratification at the merge of the docs-2026-09 branch; the code learns the two kinds in that campaign's phase 2). (§Invariants `INV-VOCABULARY` in this file carries the same list.) <status stage="spec" state="done" action="continue" actionstage="impl"/>  vibevm/vibespecs/common/PROP-000.xml:75  spec://org.vibevm.core/vibevm/common/PROP-000#KIND-SET
  d1 code doc-page   authoring::write-a-lang-package  vibevm/vibepacks/org.vibevm.core/vibevm-docs/v1.0.0/vibevm/vibespecs/authoring/write-a-lang-package.xml:1
  d1 code doc-page   glossary::index  vibevm/vibepacks/org.vibevm.core/vibevm-docs/v1.0.0/vibevm/vibespecs/glossary/index.xml:1
  d1 code doc-page   model::packages-and-kinds  vibevm/vibepacks/org.vibevm.core/vibevm-docs/v1.0.0/vibevm/vibespecs/model/packages-and-kinds.xml:1
```

## Documentation in the map {#documentation-edges}

[p16] This manual enters the same map. Every `rule` block on a page is a `documents` edge from the page to the rule it quotes, scanned on the host side through the engine's scanner seam. The edge carries no revision pin: the citation is live, the page shows the rule's current text, and the only check is that the anchor exists. Whether the prose around a citation went stale is a human's question, not a suspect flag.

> [p17] The `rule` element is read on the **host side**: a host module scans documentation pages and injects into the traceability engine through its public `CodeScanner` seam (`build_with_scanner`, `check_with_scanner`, `write_with_scanner`, `CompositeScanner`). The engine and its vendored copies are not edited and `sync-engines` is not run. Documentation pages lie **outside** `spec_roots`, the page-scan policy lives in a host file rather than in `specmap.toml`, and the scanner is injected at both points of `xtask/src/specmap.rs` — the main pass and the resolve gate — so the coverage gate cannot be green by emptiness. The edge's tail is a `CodeItem` with the sentinel `crate_name = "<doc>"`, after the precedent of the JTD scanner's `"<schema>"`; the engine's wire schema does not change.
>
> <spec://org.vibevm.core/vibevm/common/PROP-057#PIPE-EDGES-HOST-SIDE>

> [p18] 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>

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

[p19] Units come in four kinds, and each has a default edge: a requirement is implemented and verified, a design informs, a guide documents; a proposal decides, which is not yet a verb the system carries.

> [p20] **Decision.** Four unit kinds, each with a different default edge semantics:
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#DECISION-FOUR-UNIT-KINDS>

[p21] The map is carried, not generated: a mapping between prose and code cannot be inferred, only authored and verified, which is why the marks are in the code and the gates are in the build.

> [p22] The mapping cannot be *generated*; it can only be *carried and verified*. Until M1.5's `vibe build` exists, every edge is authored metadata.
>
> <spec://org.vibevm.ai-native/core-ai-native/mechanisms/PROP-014#CONSEQUENCE-MAPPING-IS-CARRIED-NOT-GENERATED>

[p23] A package can carry its own map, `package.specmap.json`, generated by `vibe specmap` before publishing, so a consumer queries an installed package without rebuilding it.

