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

docs-system

Doc-first by identity; no -docs suffix.

Linux

linux-docs

Doc repo for the Linux domain.

Artificial-Intelligence

ai-docs

Short domain form (ai) plus -docs.

DevOps-Docs

devops-docs

Domain plus -docs.

Server_Programs

server-programs

Doc-first by identity; no -docs suffix.

docker-infrastructure-docs

docker-infra-docs

Tier 2 aggregation hub.

Accounting

accounting-docs

Domain plus -docs.

Entrepreneurship

entrepreneurship-docs

Domain plus -docs.

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 .rst extension.

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.