Label Prefix Convention
Every RST label in every Documentation System repo is prefixed with the repo’s canonical project slug. This page specifies what the slug is, how labels are shaped around it, and why the convention exists.
The rule originated in ~/docker/CLAUDE.md, which required
{project-name}-{label} where project-name matched the Docker
Compose project folder. That rule doesn’t generalize — most Tier 1
doc repos are not Docker Compose projects — so this page codifies a
non-container-friendly version that works everywhere.
Why Prefixes Exist
RST cross-references (:ref:`label-name`) are resolved against a
flat, global label namespace within a Sphinx project. When two repos’
content is aggregated into a single hub build — the Tier 2 pattern
used by docker-infrastructure-docs — every label from every
aggregated repo ends up in that one namespace. Collisions produce
build warnings at best, and silently-wrong link resolution at worst.
Prefixing every label with the repo’s slug eliminates the collision
risk structurally. Any hub build, present or future, can aggregate any
combination of repos without two architecture-overview labels ever
stepping on each other, because one is linux-docs-architecture-
overview and the other is devops-docs-architecture-overview.
The Project Slug
Each repo declares a single canonical project slug that prefixes
every label it owns. The slug is declared in the repo’s conf.py
and listed in Repository Registry. The registry
is authoritative; conf.py restates it for build-time use.
Slug format
A slug is lowercase ASCII letters, digits, and hyphens only. No underscores, no uppercase, no dots.
Regex:
^[a-z][a-z0-9-]*[a-z0-9]$
That is: starts with a letter, ends with a letter or digit, internal characters are letters, digits, or hyphens.
Slug length and style
Slugs are short and domain-oriented. Doc repos that live alongside a
code repo, or whose purpose is purely documentation of a domain, carry
the -docs suffix to make the “this is documentation” signal
unambiguous inside a label. Repos whose canonical identity is already
doc-first (their name or their content is the docs) omit the
-docs suffix.
Current slug assignments
Repo |
Slug |
Notes |
|---|---|---|
Documentation_System |
|
Doc-first by identity; no |
Linux |
|
Doc repo for the Linux domain. |
Artificial-Intelligence |
|
Short domain form ( |
DevOps-Docs |
|
Domain plus |
Server_Programs |
|
Doc-first by identity; no |
docker-infrastructure-docs |
|
Tier 2 aggregation hub. |
Accounting |
|
Domain plus |
Entrepreneurship |
|
Domain plus |
Label Shape
Labels use a semi-structured shape: slug, then section directory, then the author-chosen label body.
{slug}-{section-dir}-{label-body}
Examples:
.. _docs-system-conventions-label-prefix:
.. _docs-system-reference-repo-registry:
.. _linux-docs-ssh-agent-setup:
.. _devops-docs-webhooks-endpoint-health:
The section-dir segment reveals where the section lives, which makes
labels self-documenting and keeps collisions rare across a growing
repo. Authors may add additional dashed segments after
{section-dir} to describe the section:
.. _docs-system-conventions-rst-standards-hierarchy-levels:
.. _docs-system-conventions-rst-standards-overline-underline-minimum:
Moving a section between files within the same section directory does not force a rename; moving between directories does. That is the intended trade-off — directory structure is the primary organizer, so labels should reflect it.
Index-page labels
A directory’s index.rst uses a shorter form: {slug}-{dir}.
The trailing -index segment is omitted.
.. _docs-system-conventions:
.. _docs-system-reference:
.. _docs-system-tooling:
This reads naturally in :ref: calls — :ref:`docs-system-
conventions` says “the conventions section,” which is exactly what
an index page represents.
Scope of the Rule
The prefix convention applies to every labeled section header in
every .rst file. That is, every directive of the form:
.. _some-label:
Header Text
======================================================================
must carry the prefixed form:
.. _{slug}-{section-dir}-some-label:
Header Text
======================================================================
Two exemptions:
Inline hyperlink targets. RST scopes inline targets (
.. _Brad Stancel: https://bradstancel.com/) to the file in which they are defined. They cannot collide across files, so they do not need a prefix.Footnote labels. RST scopes numeric and symbolic footnote labels to the file as well.
If you are in doubt whether a label qualifies, prefix it. The cost of an over-prefixed label is zero; the cost of a colliding un-prefixed one is a broken cross-reference.
Slug Normalization for File Names
The top-of-file label requirement in
docs-system-conventions-rst-standards-required-label uses a
{filename-slug} derived from the file’s path inside source/:
Lowercase the path.
Replace directory separators (
/) with hyphens.Replace underscores with hyphens.
Drop the
.rstextension.
So source/conventions/rst-standards.rst has filename-slug of
conventions-rst-standards, and the top-of-file label becomes:
.. _docs-system-conventions-rst-standards:
Applying the same transformation to every file in a repo produces a stable, predictable label-namespace structure.
Migration
Existing Tier 1 repos pre-date this convention and carry many unprefixed
labels. They will be brought into compliance in Phase 2 of the master
plan. Mechanical rename instructions, a safe find-and-replace workflow
across cross-repo :ref: callers, and a tracking template live in
workflows/label-migration.rst (forthcoming). Do not batch-rename
labels until that workflow is published; cross-repo refs must be
updated in the same commit as the label they point at, and the workflow
page documents how to coordinate that.
Origin
The prefix rule was first documented in ~/docker/CLAUDE.md for the
Docker Compose parent directory, where the prefix matched the Compose
project folder name. That version works for Tier 2 hubs (which are
Compose projects) but not for Tier 1 standalone doc repos (which are
not). This page is the authoritative, non-container-scoped version.
Every repo’s own CLAUDE.md defers here for slug, shape, and scope.