Skip to content

Read and cite product specs

MCPCLIBeginner~10 min

You want the rule that governs some behaviour, in words you can act on, and a short citation — like api:010:04 — that you can write into a ticket, a code comment or a message, and that will still point at that rule next year. Ask your agent for it in plain language; reading specs needs no terminal.

A spec corpus is a Hadron memory run like a legal code: each spec's loc is its citation, and a citation never moves. If you write or curate specs, see Maintain product specs instead, or Manage product specs with a coding agent to have an agent do the writing.

Ask your agent

What you need: an agent connected to Hadron — a chat app such as Claude Desktop, or a coding agent such as Claude Code, Codex or Cursor (see Install Hadron in Claude Desktop and its siblings) — read access to your specs memory, and that memory's name, for example acme.com:specs.

Ask about the behaviour, not the number:

In acme.com:specs, which spec governs whether a worker's name can ever be
reused? Give me its citation and the rule in two sentences, and tell me if
anything else governs it.

Or start from a citation you already have:

What does api:010:04 in acme.com:specs say? Is it still current?

What a good answer contains:

  • The citation and the rule, in the spec's own terms.
  • Whether the spec is still current. A search can surface a retired spec first — retired specs keep their citations forever. A superseded spec has a replacement, and a good answer follows it to the rule that governs now. A withdrawn spec has none: the mechanism it described is gone. A good answer says so, and names another spec only if the withdrawn one's own text points to it.
  • What else governs it. A spec often inherits a general-provisions contract that states what a group of specs share; the rule isn't complete without it.

What to check before you rely on it: that the citation in the answer is the one whose text the agent quoted, and — if the first spec it found was retired — that it followed a superseded spec to its replacement, or told you plainly that a withdrawn one no longer governs. If you're going to act on the rule, ask for its exact wording rather than a summary.

If your agent can't find the corpus, it usually needs the memory's exact name, or you need read access to it — ask whoever administers your Hadron organization.

Cite it

Cite the bare citation — api:010:04 — not a URL or a node ID. It is the permanent handle: it survives edits and relocations, and anyone with access to the corpus can resolve it, by asking their agent or with hadron spec get. The full node URN (hrn:node:acme.com:specs:api:010:04) is what generic node tools take, if you need to reach past the spec tooling.

With the hadron CLI

The rest of this page does the same with the hadron CLI — the tool a coding agent uses underneath, and the one to reach for if you'd rather search the corpus yourself.

Point the CLI at a corpus

Use the hadron CLI v0.17.0 or later. Older versions accept only numbered citations and refuse a spec named by path ("onboarding" must be 3 lowercase letters).

Every spec subcommand takes -m/--memory, which accepts a memory PK, an hrn:/urn: URN, a bare org:memory, or the memory's name. Set it once and drop the flag:

hadron spec use acme.com:specs

That default is stored separately from your active memory, so switching the memory you're working in doesn't change your spec corpus. Pass "" to clear it. The examples below omit -m and assume you've done this.

Read a citation

A citation is the spec's loc, so it can be any valid node loc. Many corpora number their specs in a legal-code style, which reads from the most general segment to the most specific:

<module>:<feature>:<rule>[:<flow>]              api:010:02
<product>:<module>:<feature>:<rule>[:<flow>]    srv:api:010:02
  • product — a shippable artifact (srv, cli, por). Three lowercase letters.
  • module — a top-level division of it (a service, a command group). Three lowercase letters.
  • feature — three digits, numbered in tens (010, 020, …).
  • rule — two digits. This is usually the thing you cite.
  • flow — two digits; a pull-on-demand sub-part of a rule.

That numbering is a convention, not a requirement. A corpus can also hold specs at named paths such as onboarding:mentor:screens:settings, or mix the two. Either way the loc tells you nothing about a spec's parent: what a spec is connected to is in its edges, which spec get prints.

Citations are never recycled and never renumbered, so a citation you write down today resolves to the same rule indefinitely. To see what a corpus holds (CLI v0.17.0 or later; older CLIs print a flat/product "scheme" report instead):

hadron spec describe
Spec corpus — acme.com::specs
  specs:     60  (deepest loc: 5 segments)
  roots:     onboarding, srv
  numbering: 58 in the legacy numbering, 2 outside it

The CLI prints the memory in the older acme.com::specs form; when you type a memory, use the single-colon acme.com:specs. roots are the first segments in use, and numbering counts how many specs follow the numbered convention above and how many sit at other locs.

Find the spec you need

Citations are opaque, so discovery rides on each spec's abstract, which the memory's vector index embeds. Search by intent rather than guessing a number:

hadron spec find "re-engage users who never finished setup"
CITATION        NAME
srv:api:010:04  srv:api:010:04 — W4 — 7-day check-in
srv:api:010:02  srv:api:010:02 — W2 — welcome nudge

spec find is semantic by default (hybrid keyword + vector) and returns 15 results unless you pass --limit. On a corpus with no vector index it falls back to keyword search and says so.

For an exact fragment — most often a citation — pass --match-exactly, which switches to literal regex matching over name/loc/description/tags. Plain keyword search is full-text ranked and stemmed rather than substring, so it won't reliably match a bare number:

hadron spec find "srv:api:010" --match-exactly

Search the prose, not the metadata

spec find ranks over name, loc, description, and tags. When you need to know where a token actually appears in the body — an identifier, a tool name, a TODO — use spec grep, which reads every spec's full text and prints each hit as citation:line: text:

hadron spec grep hadron_get_node
hadron spec grep 'hadron_[a-z_]+' --regex --prefix srv:api

It's exhaustive rather than ranked, literal unless you pass --regex, and -i folds case. Scope it with --prefix, or restrict to one field with --field content|abstract.

Read the spec

hadron spec get srv:api:010:04

You get the abstract, the node's edges, the markdown body, and a one-line lint summary. Two narrower forms are useful:

  • --abstract-only prints metadata and abstract without the body — the right size for scanning, or for stuffing many specs into an agent's context.
  • --body-only prints just the raw markdown of a single spec, with no metadata.

To pull a whole branch — one feature, one module, or an entire product — use --prefix instead of a citation:

hadron spec get --prefix srv:api:010              # a feature and its rules
hadron spec get --prefix srv:cha --abstract-only  # a module, scannable

Every spec under the prefix is fetched by default; --limit (with optional --offset) fetches a single explicit page instead.

To just see what exists without reading bodies:

hadron spec list --prefix srv:api

Check what else governs the rule

A spec is rarely the whole story. A general-provisions contract states what a group of sibling specs share, so it is written once rather than repeated in each of them. A spec that is bound by a contract has an inheritance edge to it, and spec get shows that edge:

Edges:
  → srv:api:010:00  inherits the shared contract (general provisions)
  → srv:api:010     W4 — 7-day check-in

Read that edge as "governed by these general provisions", not as "is another instance of the same kind of thing." When a spec seems to leave something undefined, the contract it inherits is where to look next. A spec overrides a provision only by saying so explicitly.

In a numbered corpus the contracts sit at reserved numbers, so you can often guess where one is before you look:

A spec at this level usually inherits which holds
a rule (srv:api:010:04) its feature's :00 (srv:api:010:00) provisions common to the feature's rules
a feature (srv:api:010) its module's :000 (srv:api:000) provisions common to the module's features
a module (srv:api) its product's :gen (srv:gen) provisions common to the product's modules

The edge is what counts, not the number. A spec with no inheritance edge inherits nothing, wherever its loc sits.

Spot a retired spec

Specs are never renumbered or deleted. When one is replaced it is superseded: it keeps its citation, gains the tag superseded, and gets a superseded-by edge pointing at its replacement. So an old citation in a commit message or a ticket still resolves — it just tells you where to go next:

hadron spec get srv:api:010:02
Tags: spec, superseded

Edges:
  → srv:api:010:07  superseded-by

Check the tag before you rely on a spec you found by citation rather than by search.