---
cuppy_hub: cuppy
cuppy_path: reference/standard/hub-standard.md
cuppy_section: docs
cuppy_doc: SWMJ-MF8W
cuppy_doc_uuid: 672d45c1-6c6d-499d-b7f8-717009d729db
cuppy_permalink: https://cuppy.io/cuppy/d/SWMJ-MF8W
cuppy_version: 1
cuppy_updated: 2026-10-17T06:32:45.511Z
cuppy_canonical: https://cuppy.io/cuppy/docs/reference/standard/hub-standard
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 89b2e2ff7e5f8c70019f8413b7576469c940c37786979c311049fd5e41105d98
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---

# The cuppy hub standard

This is the standard a hub on this platform is built to. It is normative for cuppy's
own hub, which is the hub you are reading it in, and it is the source of the document
half of the open standard (`reference/standard/open-standard.md`).

Three things it is not. It is not the product: the tool surface, the command registry
and the settings registry are versioned with the platform and are not standardised.
It is not a description of what is built today: where the build and this standard
disagree, the paragraph says so and names the record. And it is not a style guide; it
says where a document goes and what it must declare, never how to write prose.

Every figure below is read from the specification revision 24 named in this document's
front matter, or from the code or a record named at the figure; where a number is a
reading rather than a spec statement, the sentence says which.

## 1. The spine, and what each folder holds

A hub has one spine every hub shares, and any number of **sources** whose internal
layout it does not dictate (AE1). The spine is fixed because the boot call, the routes
generator, the catalog and the bundle composer read it by name.

| folder | what it holds |
|---|---|
| `HUB.md` | the hub's own root card: what this hub is, its facets, where an agent starts |
| `_boot/` | the first read, sorted first: `START.md`, the always-active rules, the generated routes, one `agent` document per role under `personas/` |
| `guides/` | task workflows, one per intent, each step naming its next read |
| `reference/` | facts, by domain and object; the inheritable truth. `reference/official/` holds a vendor's own documentation per release, `reference/entities/<type>/` holds dossiers |
| `examples/` | projects, each with a manifest naming the version it builds on |
| `templates/` | stubs and scaffolds |
| `patterns/` | known-good and known-bad; a promoted learned pattern lands here |
| `notes/` | the platform's view of field notes by path and context |
| `decisions/` | the platform's view of structuring assumptions and the decision log |
| `changelog/` | hub release notes and upstream-changed summaries per version |
| `raw/` | mirrors, exports, screenshots: stored, never indexed, never budgeted |

Four rules make the spine work.

- **Layers fill, never fork.** A child layer adds its own `guides/`, `reference/`
  overrides, `examples/` and `notes/`. It never copies `reference/official/`.
- **A source keeps its native tree.** A mirrored repository, an uploaded bundle or a
  crawl mounts under one spine folder with its own layout untouched, because the
  vendor's own documentation cites those paths.
- **Underscore means read first, and the platform owns the name** (D87). `_boot/` is
  the only underscore folder on the spine. `_index.md` is the generated folder card
  and `_source.md` the generated source manifest.
- **`raw/` is a holding area, not content.** Importers read from it; retrieval never
  does.

**Two of those rules are not yet enforced by the build, and both are recorded in
`tracking/updates/2026-10-15-set-065-semarchy-hub-migration.md`.** Nothing generates
`_index.md` or `_source.md`, and the write path refuses an underscore-prefixed file
name, so neither card can be authored either (finding 4). `folders.settings.indexed`
has no writer anywhere in the API source while the folder scope function honours it, so
a `raw/` folder imported today is indexed, retrieved and budgeted (finding 3). Treat
both as owed work, not as properties you can rely on.

## 2. The front-matter contract

Every document is a markdown file with YAML front matter and a body. Two fields
classify it and they are independent (AB1): **`role`** is where the document sits in
the boot ladder and answers *when an agent reads this*; **`shape`** is how the body is
built and answers *what an agent does with it*.

`role` is one of five: `boot`, `guide`, `reference`, `example`, `pattern`. `shape` is
one of seven and defaults to `markdown`. Both vocabularies are read from
`apps/api/src/shapes/markdown.ts`, which is the authority the validator uses.

### The common fields

| field | required | what it is |
|---|---|---|
| `role` | yes | one of the five above. `kind` is accepted as an alias until Phase 4 |
| `shape` | defaults to `markdown` | one of the seven below |
| `summary` | yes | the whole payload of a `lite` card, so write it for a reader deciding whether to load. Capped at 500 characters by the validator, which is a reading rather than a spec number |
| `status` | yes | `draft`, `review`, `published` or `deprecated` |
| `covers[]` | defaults to empty | the terms this document covers; a ranking signal, so a term nobody meant is worse than none |
| `facets{}` | defaults to empty | context keys whose values are a string or a list of strings, never a number |
| `depends_on[]` | defaults to empty | the stack this document needs, each entry a short id or a UUID and **never a path** |
| `short_id` | minted | assigned by the platform at creation; absent on a first write and present on every stored row |
| `freshness` | stored | the tier and its verifier. An authored write may claim `asserted` and nothing stronger |
| `token_estimate` | computed | computed on write, accepted on input and recomputed |

A hub may carry its own extra keys: the validator preserves unknown fields. What it
refuses by name is a key that belongs to another shape, because a document declaring
`shape: markdown` while carrying an `operation`'s `request` block is mis-shaped rather
than merely decorated.

### The seven shapes

| shape | the question it answers | body |
|---|---|---|
| `markdown` | what does it say | free text |
| `operation` | how do I call this | a request template, its parameters, constraints, a cost model, the success and error responses |
| `interface` | what does this API or server accept | the vendor's own OpenAPI, Swagger or MCP manifest, preserved verbatim |
| `dataset` | what does this data look like | a manifest, a few real rows per file, keys, joins, a source link |
| `workflow` | what do I do, in what order | ordered steps, each naming its documents at a depth and the outcome that proves it |
| `error` | what does this message mean and what fixes it | signatures, what it appears to say, each cause with a diagnostic, each fix with its kind and evidence |
| `agent` | what should this role read, run and avoid here | the role, its boot stack, its workflows and packs, its routing and its observed limits |

A dossier is not an eighth shape: an entity dossier is `role: reference`,
`shape: markdown` with an `entity:` block the markdown validator checks when it is
present (D101, Part AG). Dossiers are a later feature of this standard and no document
in this hub is one yet.

Two consequences of the shape split bite authors. An `operation` never carries a
resolved credential: its request template carries a placeholder, the agent supplies its
own, and the platform never executes the call. And an `interface` body is stored rather
than re-authored, so authority stays with the vendor and an `operation` cites it
instead of restating it.

## 3. Ids and paths

**The short id is the permanent address.** Every document and every folder carries one:
eight characters of Crockford base32 in `NNNN-NNNN` form, with no `I`, `L`, `O` or `U`
so it can be read aloud and typed from a screen. It is minted at creation, at random,
and is unique within its hub and against every ancestor visible at mint time. A
rename or a move does not change it; a path does not survive either. Cite the short id.

Two consequences for anything written down. A `depends_on[]` entry is a pointer, so it
is a short id or a UUID and the validator refuses a path there. And **a short id is
per hub**: the ids minted for this hub's documents are not the ids another hub mints
for the same bytes, so a record quoting one must name the hub and the run it came from.
A dry run's ids never exist at all, because it mints them inside the transaction it
rolls back (`docs/commander/RUNS/2026-10-14-private-rehearsal.md`, finding F7).

**Paths** are validated at the edge: a folder label is drawn from a restricted
alphabet, the tree is bounded by `tree.max_depth` (12) and `tree.max_nodes` (500, then
a cursor), and scope is resolved as a subtree by one function before anything else
runs, so no caller composes the predicate.

## 4. Visibility

Visibility is a property of a folder and of a document, not only of a hub (D98,
specification revision 24). `folders.settings.visibility` and
`documents.visibility_override` each take `inherit` (the default), `public`,
`unlisted`, `private` or `paid:<plan>`, and the effective value is computed down the
folder path by the same propagation that maintains folder cards.

Three rules carry the weight. A child may always be **more** restrictive than its
ancestors with no permission beyond the write. A child may be **less** restrictive only
by an owner, only while the hub's widening flag is on (default off), and the widening
is audited. And `paid:<plan>` **never hides**: the `lite` card is always served with
an upgrade hint, and only the body requires the plan.

**Build state.** This is specification revision 24 and nothing more: no
`effective_visibility` appears anywhere in the API source or in the migrations, read by
grep over `apps/api/src` and `apps/api/migrations` at the base commit this document was
written on. Write to the rules above; do not assume a document in this hub is gated by
them today.

## 5. Provenance and freshness

Freshness is the strongest evidence the hub holds for a claim, and it decays (AD2).
Four tiers, strongest first: `probed` (an attempt executed the operation and observed
the result), `sourced` (a vendor artifact with provenance), `crawled` (a vendor page
with a URL and a fetch time), `asserted` (written by a person or an agent without a
source).

**An authored write stores `asserted` and may not claim better.** A front matter
carrying a stronger tier is refused with the field named; one carrying a verifier field
has it dropped and the drop reported. A new version re-asserts, because the content that
was verified is gone. Only an attempt or a vendor artifact raises a tier, which is what
makes the tier mean anything.

Provenance in the authored sense — who wrote this, and from what — belongs in front
matter. The documents in this hub's `reference/standard/` and `guides/` folders carry a
`provenance` block naming the specification revision and the records their claims are
derived from, so a reader can check a figure without trusting the sentence quoting it.

## 6. How a document names its next read

Drilldown is the ladder (N3). `_boot/START.md` names a persona; the persona names a
guide; the guide names its reference and example documents. Each hop is one small read
that names the next one, and the validator warns when a `boot` or `guide` document
names none.

Name the next read by short id where you can, since an id survives every rename; by a
markdown link for a reader navigating by hand; by path where the ids do not exist yet.
A bundle prepared outside the hub has only the third available, which is why the
pointers in these standard documents are paths.

A `workflow` document is the strong form of the same thing: each step names the
documents it needs **and the depth it needs them at**, plus the observable outcome that
proves the step is done. That is what the pack compiler reads, and it is why a workflow
is the only document that can be compiled.

## 7. The boot document, and the three tiers

The first boot is three tiers, each with its own cap (AF7):

| tier | when | cap |
|---|---|---|
| `_hello {intent}` | the first call: a banner, an opener, three to seven routes chosen for the intent, a pointer to `_boot/`. Reads no hub content and mints nothing | `boot.hello_max_tokens` 400 |
| `session start {format: visual}` | once per session, on request: the readiness screen, the routes, the system map, the role and plan, the session handle | `boot.visual_max_tokens` 1,200 |
| `_boot/START.md` | when the persona's boot stack names it, or the agent asks | `boot.max_tokens` 20,000 |

`START.md` is **a hand-written head and a generated body** (AF8), split by one marker
line. Everything before the marker is the author's and no generator touches a byte of
it; everything from the marker on is the generator's and is rewritten whole on every
publish. One marker, not two: a generator writing between two markers would have to
parse the author's text to find its slot.

The reading order is: what this hub is; the rules that always apply; how to use the
tool; then the generated sections — how the surface works, the routes, the catalog, the
top documents by signal, the known-issues head and the freshness summary, and where to
go for everything else. The physical order differs, because one marker cannot
interleave: the three hand-written sections, then the marker, then the six generated.

**The budgets, and where each is measured.** The hand-written budget
(`boot.handwritten_max_tokens`, 4,000) is measured over the bytes before the marker;
the whole-file budget (`boot.max_tokens`, 20,000) over head and tail together. Both are
enforced identically on an authored write and on an import, because an oversized agent
entry that installed cleanly through an import is paid for by every later session.

**The 20,000 is not reachable today, and the interim is smaller.** A `_boot/` document
above `embed.max_tokens` (6,000) is split into parts at ingest, and a tail part carries
no marker, so it measures as all head and is refused above the hand-written cap. The
interim in force binds the generated body to the smaller of the two caps; the four
candidate answers are in the specification at AF8 and the question is the owner's open
decision D-5. Budget a boot catalog against the ingest cap, not against the 20,000.

**The catalog is tiered**, because a full file-level catalog does not fit a real hub:
every folder card first, then file lines ordered by the persona's workflows and the
decayed signals until the cap, with the depth reached and the listed-over-total counts
on the version line. The full catalog is one call away. The generated body is
**deterministic** — no wall clock, every list ordered by a stable key, and a catalog
digest over the ordered id-and-version pairs rather than over the rendered text — so two
runs over an unchanged hub produce identical bytes and a cached copy is detectably stale.

## 8. What to read first, and in what order

1. `_hello` with your intent: one call, the routes for that intent, a pointer to
   `_boot/`.
2. `_boot/START.md` — the head, then the routes and the catalog. Everything else in the
   hub is reachable from there.
3. The persona document for your role, if the hub has one, then the workflow it names.
4. The documents the workflow names, at the depth it pins. Ask for `lite` to decide
   whether to load, `normal` to do the work, `verbose` to learn why something keeps
   failing. Nothing you ask for is truncated; the envelope states the cost first.
5. When you hold an error, read the error documents before you search: the error call
   answers from the signatures and names what is nearest when nothing matches exactly.

And report what happened. One outcome call is the only way the hub learns which
document was right, and the ranking the next agent gets is built from it.

## Next reads

- `reference/standard/open-standard.md` — the three artifact specs, what is normative,
  and how a product other than cuppy implements them.
- `guides/connect-a-client.md` — how to connect to this hub from each client, with deep
  links.
- `guides/bootstrap-a-hub.md` — the workflow that builds a hub from public
  documentation; this hub is its worked example.
- `guides/approach-an-unknown-system.md` — the generic protocol for a system you do
  not control.
- `reference/cuppy/served-surface.md` — the surface itself, generated from the registry
  the deployment dispatches on: the tools, the command rows, the universal parameters and
  the refusals. `reference/cuppy/mcp-architecture.md` is the design blueprint beside it —
  the roadmap, not the build.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 18 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/cuppy/
<!-- /cuppy -->
