Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Human-Readable IDs (HRIDs)

Human-Readable IDs (HRIDs) are short, memorable identifiers like USR-001 or COMPONENT-SYS-042. They make requirements easy to reference in conversations, code comments, and documentation.

HRID Format

The general format is:

{NAMESPACE*}-{KIND}-{ID}

Where:

  • NAMESPACE* = Zero or more namespace segments (optional)
  • KIND = Requirement type/category
  • ID = Numeric identifier

Components

Namespace (Optional)

Zero or more segments separated by hyphens:

USR-001                          # No namespace
COMPONENT-USR-001                # One namespace level
AUTH-LOGIN-SYS-042               # Two namespace levels
PRODUCT-FEATURE-MODULE-SWR-123   # Three namespace levels

Purpose: Organize requirements in large projects or multi-component systems.

Rules:

  • Each segment must be non-empty
  • Segments are case-sensitive (by convention, use UPPERCASE)
  • No special characters (letters, numbers, underscores OK)

Kind (Required)

The requirement category or type:

USR    # User requirements
SYS    # System requirements
SWR    # Software requirements
HWR    # Hardware requirements
TST    # Test requirements

Purpose: Distinguish requirement levels in the hierarchy.

Rules:

  • Must be non-empty
  • Case-sensitive (by convention, use UPPERCASE)
  • No special characters

Common conventions:

  • USR - User requirements (what users need)
  • SYS - System requirements (technical specifications)
  • SWR - Software requirements (software-specific details)
  • HWR - Hardware requirements (hardware-specific details)
  • TST - Test requirements (test cases)

You're free to use any KIND values that make sense for your project.

ID (Required)

A positive integer:

USR-1      # Valid
USR-001    # Valid (zero-padded)
USR-42     # Valid
USR-1000   # Valid

Purpose: Unique number within the KIND (or NAMESPACE-KIND combination).

Rules:

  • Must be a positive integer (1, 2, 3, ...)
  • Zero is not allowed
  • Negative numbers are not allowed

Display format: IDs are zero-padded to a configurable width (default 3 digits):

USR-001   # 3 digits (default)
USR-042
USR-123
USR-1000  # Exceeds padding, shows all digits

Configure padding in config.toml:

digits = 3   # USR-001
# or
digits = 4   # USR-0001

Parsing Examples

Valid HRIDs

USR-001                      # Simple: KIND-ID
SYS-042                      # Different kind
USR-1                        # No leading zeros
USR-1000                     # Large ID
COMPONENT-USR-001            # One namespace
AUTH-LOGIN-SYS-042           # Two namespaces
A-B-C-D-E-KIND-123           # Five namespaces

Invalid HRIDs

USR001                       # Missing hyphen
-USR-001                     # Leading hyphen
USR-001-                     # Trailing hyphen
USR--001                     # Double hyphen
USR-                         # Missing ID
-001                         # Missing KIND
USR-abc                      # Non-numeric ID
USR-0                        # Zero ID not allowed
USR--001                     # Empty segment

Namespaces in Practice

When to Use Namespaces

Large projects: Organize by subsystem

AUTH-USR-001     # Authentication subsystem user requirements
AUTH-SYS-001
PAYMENT-USR-001  # Payment subsystem user requirements
PAYMENT-SYS-001

Product families: Distinguish shared vs. product-specific

CORE-SYS-001    # Shared by all products
MOBILE-USR-001  # Mobile app specific
WEB-USR-001     # Web app specific

Organizational structure: Match company divisions

FRONTEND-DASHBOARD-USR-001
FRONTEND-REPORTS-USR-001
BACKEND-API-SYS-001
BACKEND-DATABASE-SYS-001

When Not to Use Namespaces

Small projects: Added complexity without benefit

# Overkill for a small project
TODO-APP-CORE-STORAGE-SYS-001

# Better
SYS-001

Flat hierarchy: If you don't need organizational structure

USR-001, USR-002, SYS-001, SYS-002

Use namespaces only when they add clarity, not as a default.

HRID Assignment

Auto-Incrementing

req add automatically assigns the next available ID:

req add USR    # Creates USR-001
req add USR    # Creates USR-002
req add SYS    # Creates SYS-001
req add USR    # Creates USR-003

The next ID is determined by examining existing requirements and incrementing the highest ID found.

With Namespaces

Specify the namespace in the KIND argument:

req add AUTH-USR        # Creates AUTH-USR-001
req add AUTH-SYS        # Creates AUTH-SYS-001
req add PAYMENT-USR     # Creates PAYMENT-USR-001
req add AUTH-USR        # Creates AUTH-USR-002

Each NAMESPACE-KIND combination has its own sequence.

Gaps in Numbering

If you delete USR-002, creating a gap:

USR-001.md  # Exists
# USR-002.md deleted
USR-003.md  # Exists

The next req add USR creates USR-004, not USR-002. Requiem always uses the next number after the highest existing ID.

Rationale: Reusing deleted IDs could confuse people referring to old documentation or Git history that mentioned USR-002.

HRID Best Practices

Use Consistent Naming

Pick a convention and stick to it:

# Good (consistent)
USR-001, USR-002, SYS-001, SYS-002

# Bad (inconsistent)
USR-001, User-002, SYS-001, system-002

Keep KINDs Short

# Good
USR, SYS, SWR, TST

# Less good (too verbose)
USER_REQUIREMENTS, SYSTEM_REQUIREMENTS

Short KINDs are easier to type and read.

Use UPPERCASE

# Good
USR-001

# Works but unconventional
usr-001
Usr-001

UPPERCASE is the standard convention in requirements engineering.

Document Your KIND Meanings

Create a glossary:

# Requirements Glossary

- **USR**: User requirements (stakeholder needs)
- **SYS**: System requirements (technical specifications)
- **SWR**: Software requirements (implementation details)
- **TST**: Test requirements (test cases)

HRID Stability

HRIDs Can Change

Unlike UUIDs, HRIDs are not guaranteed stable. They might change if:

  • Requirements are renumbered
  • Namespaces are reorganized
  • Projects are merged

Correcting HRIDs

If you manually rename a requirement file, run:

req clean

This updates parent hrid fields to reflect the new names, while UUIDs keep links valid.

Example:

# Manually rename
mv USR-001.md AUTH-USR-001.md

# Update parent references
req clean

# Children that referenced USR-001 now show AUTH-USR-001

Referencing Requirements

In documentation and code, always reference by HRID for readability:

#![allow(unused)]
fn main() {
// Satisfies USR-042: Email validation
fn validate_email(email: &str) -> Result<(), ValidationError> {
    // ...
}
}

But remember that HRIDs might change. For machine processing, use UUIDs.

Namespace Configuration

Configure allowed namespaces and kinds in config.toml:

_version = "1"

# Optional: Restrict allowed kinds
allowed_kinds = ["USR", "SYS", "SWR", "TST"]

# Optional: Set ID padding
digits = 3

Note: Namespace validation is not yet implemented. You can use any namespace structure. Future versions may allow restricting namespaces.

HRID Storage Location

Important: HRIDs are stored in two places:

  1. Filename: USR-001.md, COMPONENT-SYS-042.md
  2. First Heading: # USR-001 Title, # COMPONENT-SYS-042 Title

The HRID must appear as the first token in the first markdown heading:

---
_version: '1'
uuid: ...
---
# USR-001 Plain Text Storage

Requirements are stored as plain-text files...

Not in frontmatter: The HRID is NOT stored in the YAML frontmatter. This change was made to improve compatibility with Sphinx and MdBook.

Filename Matching

Requirement filenames must match the HRID in the first heading:

USR-001.md with heading: # USR-001 Title        → Valid
COMPONENT-SYS-042.md with: # COMPONENT-SYS-042  → Valid

Mismatches cause errors:

USR-001.md with heading: # USR-002 Title → Error!

The HRID in the filename is authoritative. Requiem derives the HRID from the filename and expects the heading to match.

Next Steps

Now that you understand HRIDs, learn how to create requirements with req add.