Introduction
Welcome to Requiem, a modern plain-text requirements management tool designed for software and systems engineers who value simplicity, speed, and integration with their existing workflows.
What is Requiem?
Requiem (package name: requirements-manager, CLI: req) is a spiritual successor to Doorstop, reimagined for the modern development landscape. It enables teams to:
- Manage requirements as plain text - Store requirements as markdown files with YAML frontmatter, making them human-readable, version-controllable, and diff-friendly
- Build traceable requirement hierarchies - Link requirements together to form directed acyclic graphs (DAGs) that trace from high-level user needs down to detailed specifications
- Support multiple parents - Unlike many tools, Requiem allows a single requirement to satisfy multiple parent requirements, reflecting real-world complexity
- Integrate seamlessly - Works alongside documentation tools like Sphinx and MdBook, fitting naturally into your existing documentation workflow
- Scale with performance - Built in Rust with parallel processing, Requiem is designed to be much, much faster than its predecessors
When to Use Requirements Management
Requirements management is essential when:
- Traceability is critical - Regulated industries (aerospace, medical devices, automotive) often require proof that each requirement is implemented and tested
- Teams need alignment - Multiple stakeholders (users, developers, testers, managers) need a shared understanding of what's being built
- Systems are complex - Large projects with many interconnected components benefit from formal requirement tracking
- Change management matters - Understanding the impact of requirement changes across dependent systems is crucial
- Documentation must be maintained - Requirements serve as the foundation for design documents, test plans, and user manuals
Project Status
Requiem is in early development and not yet ready for production use. Current status:
Implemented:
- ✅ Manage requirements, specifications, and documents in plain text
- ✅ Create and link requirements with human-readable IDs
- ✅ Support multiple parent relationships
- ✅ Content fingerprinting for change detection
- ✅ Integration with MdBook and Sphinx
- ✅ Parallel loading for performance
Planned:
- 🚧 Detect cycles in requirement graphs
- 🚧 Trigger reviews when dependent requirements change
- 🚧 Generate coverage reports (requirement → implementation → test)
- 🚧 Import and export in standard formats
Contributions are welcome! See the GitHub repository for more information.
Design Philosophy
Requiem is built on several core principles:
- Plain text first - Requirements are markdown files that can be read, edited, and reviewed without special tools
- Git-friendly - Every requirement change creates a meaningful diff that's easy to review in pull requests
- Dual identifiers - Stable UUIDs for machine processing, human-readable IDs (like
USR-001) for people - Fast by default - Parallel processing and efficient data structures mean Requiem scales to large projects
- Composable - Works alongside your existing documentation tools rather than replacing them
- Documentation tool friendly - HRIDs are stored in markdown headings (e.g.,
# USR-001 Title) for seamless integration with Sphinx and MdBook
Who This Guide Is For
This guide is designed for:
- Requirements engineers managing formal requirement sets
- Technical writers documenting software systems
- Developers working in regulated environments
- Project managers needing traceability and impact analysis
- QA engineers mapping requirements to test cases
You should be comfortable with:
- Command-line tools
- Text editors
- Basic version control (Git)
- Markdown formatting
What's in This Guide
This guide includes:
- User Guide: Learn how to use Requiem effectively
- Reference: Detailed CLI and file format specifications
- Example Project: See Requiem managing its own requirements as a real-world example
The Example Project contains all 21 requirements that define what Requiem does, demonstrating traceability, proper structure, and best practices.
Let's get started!
Getting Started
This section will help you install Requiem and create your first requirements project. By the end, you'll understand the basic workflow and be ready to manage your own requirements.
The following chapters cover:
- Installation - How to install Requiem on your system
- Quick Start Tutorial - A 5-minute introduction to basic commands
- Your First Requirements Project - Creating a complete requirements hierarchy from scratch
If you're eager to dive in, start with the Quick Start Tutorial. If you prefer a more thorough understanding, read through all three chapters in order.
Installation
Requiem is distributed as a Rust crate and can be installed using Cargo, Rust's package manager.
Prerequisites
You'll need Rust installed on your system. If you don't have it yet:
Installing Rust
Visit rustup.rs or run:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
After installation, verify Rust is available:
rustc --version
cargo --version
Installing Requiem
From crates.io
Once Rust is installed, install Requiem using Cargo:
cargo install requirements-manager
This will download, compile, and install the req command-line tool.
From Source
To install the latest development version from the GitHub repository:
cargo install --git https://github.com/danieleades/requirements-manager
Verify Installation
Confirm Requiem is installed correctly:
req --version
You should see output like:
req 0.1.0
Getting Help
To see all available commands:
req --help
For help with a specific command:
req add --help
req link --help
Updating Requiem
To update to the latest version:
cargo install requirements-manager --force
The --force flag tells Cargo to reinstall even if a version is already present.
Uninstalling
To remove Requiem:
cargo uninstall requirements-manager
Next Steps
Now that Requiem is installed, proceed to the Quick Start Tutorial to learn the basic commands.
Quick Start Tutorial
This 5-minute tutorial introduces Requiem's basic workflow. You'll create a simple set of requirements and link them together.
Creating a Requirements Directory
First, create a directory for your requirements:
mkdir my-requirements
cd my-requirements
Requiem works with any directory - there's no special initialization needed. Requirements are simply markdown files with YAML frontmatter.
Adding Your First Requirement
Let's create a user requirement using the add command:
req add USR
This creates a file named USR-001.md with automatically generated metadata. Output:
Added requirement USR-001
The file contains:
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001
The YAML frontmatter includes:
_version: Format version for future compatibilityuuid: A globally unique, stable identifiercreated: Timestamp of creation
The heading includes:
# USR-001: The HRID as the first token in the first heading- Followed by the title text (currently empty)
The body (currently empty) is where you'll write the requirement text.
Editing the Requirement
Open USR-001.md in your text editor and add content:
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001 Plain Text Requirements
The system shall support plain-text requirements that can be edited with any text editor.
Notice the HRID (USR-001) appears as the first token in the first heading, followed by the title. Save the file. That's it! You've created your first requirement.
Adding More Requirements
Create a few more user requirements:
req add USR # Creates USR-002
req add USR # Creates USR-003
Edit these files to add meaningful content. For example:
USR-002.md:
---
_version: '1'
uuid: ...
created: ...
---
# USR-002 Version Control Integration
The system shall integrate with version control systems like Git.
USR-003.md:
---
_version: '1'
uuid: ...
created: ...
---
# USR-003 Requirement Traceability
The system shall support requirement traceability and linkage.
Creating System Requirements
Now let's create system-level requirements that satisfy the user requirements:
req add SYS # Creates SYS-001
Linking Requirements
Link SYS-001 to its parent USR-001:
req link SYS-001 USR-001
Output:
Linked SYS-001 to USR-001
Now if you open SYS-001.md, you'll see the parent relationship in the frontmatter and the HRID in the heading:
---
_version: '1'
uuid: 81e63bac-4035-47b5-b273-ac13e47a2ff6
created: 2025-07-22T13:14:40.510075462Z
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
---
# SYS-001 Markdown File Format
Each requirement shall be stored as a markdown file with YAML frontmatter.
The parents section contains:
uuid: The stable identifier of the parenthrid: The human-readable ID (for your convenience)fingerprint: A hash of the parent's content (for change detection)
Creating Requirements with Multiple Parents
You can link a requirement to multiple parents when creating it:
req add SYS --parents USR-001,USR-002
This creates SYS-002 already linked to both USR-001 and USR-002.
Viewing Requirements
Requirements are just markdown files, so you can view them with any tool:
ls *.md
cat USR-001.md
Or use your favorite text editor, IDE, or markdown viewer.
Summary
You've learned the three core commands:
req add <KIND>- Create a new requirementreq link <CHILD> <PARENT>- Link two requirementsreq add <KIND> --parents <PARENT1>,<PARENT2>- Create with parents
These commands form the foundation of requirements management with Requiem.
Next Steps
Continue to Your First Requirements Project to build a complete requirement hierarchy and learn more advanced techniques.
Your First Requirements Project
In this chapter, we'll build a complete requirements hierarchy for a simple project: a task management application. You'll learn how to structure requirements across multiple levels and establish traceability.
Planning the Hierarchy
A typical requirements hierarchy has multiple levels:
- User Requirements (USR) - High-level needs from the user's perspective
- System Requirements (SYS) - Technical specifications that satisfy user needs
- Software Requirements (SWR) - Detailed implementation requirements (optional)
- Test Requirements (TST) - Test cases that verify requirements (optional)
For our task app, we'll use USR and SYS levels.
Setting Up the Project
Create and enter a new directory:
mkdir task-app-requirements
cd task-app-requirements
Creating User Requirements
User requirements describe what users need, not how it's implemented.
req add USR # USR-001
req add USR # USR-002
req add USR # USR-003
Edit each file to add content:
USR-001.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
---
# USR-001 Create Tasks
Users shall be able to create tasks with a title and description.
USR-002.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
---
# USR-002 Mark Tasks Complete
Users shall be able to mark tasks as complete.
USR-003.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
---
# USR-003 Filter Tasks
Users shall be able to filter tasks by completion status.
Creating System Requirements
System requirements break down user requirements into technical specifications.
For USR-001 (creating tasks), we need:
req add SYS --parents USR-001 # SYS-001
req add SYS --parents USR-001 # SYS-002
SYS-001.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
parents:
- uuid: <USR-001 uuid>
fingerprint: <auto-generated>
hrid: USR-001
---
# SYS-001 Task Data Structure
The system shall provide a Task data structure with fields: id, title, description, completed, created_at.
SYS-002.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
parents:
- uuid: <USR-001 uuid>
fingerprint: <auto-generated>
hrid: USR-001
---
# SYS-002 Task Title Validation
The system shall validate that task titles are non-empty strings with maximum 100 characters.
For USR-002 (marking complete):
req add SYS --parents USR-002 # SYS-003
SYS-003.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
parents:
- uuid: <USR-002 uuid>
fingerprint: <auto-generated>
hrid: USR-002
---
# SYS-003 Toggle Task Completion
The system shall provide a method to toggle the completed status of a task.
For USR-003 (filtering):
req add SYS --parents USR-003 # SYS-004
SYS-004.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
parents:
- uuid: <USR-003 uuid>
fingerprint: <auto-generated>
hrid: USR-003
---
# SYS-004 Filter Tasks by Status
The system shall provide a method to filter tasks returning only those matching the specified completion status.
Creating Cross-Cutting Requirements
Some requirements affect multiple user needs. For example, persistence:
req add SYS --parents USR-001,USR-002,USR-003 # SYS-005
SYS-005.md:
---
_version: '1'
uuid: <auto-generated>
created: <auto-generated>
parents:
- uuid: <USR-001 uuid>
fingerprint: <auto-generated>
hrid: USR-001
- uuid: <USR-002 uuid>
fingerprint: <auto-generated>
hrid: USR-002
- uuid: <USR-003 uuid>
fingerprint: <auto-generated>
hrid: USR-003
---
# SYS-005 Task Persistence
The system shall persist all tasks to disk and load them on startup.
This requirement has three parents because it affects creating, completing, and filtering tasks.
Reviewing Your Requirements Structure
Your directory now contains:
task-app-requirements/
├── USR-001.md (Create tasks)
├── USR-002.md (Mark complete)
├── USR-003.md (Filter tasks)
├── SYS-001.md → USR-001 (Task data structure)
├── SYS-002.md → USR-001 (Title validation)
├── SYS-003.md → USR-002 (Toggle completed)
├── SYS-004.md → USR-003 (Filter method)
└── SYS-005.md → USR-001, USR-002, USR-003 (Persistence)
Version Control Integration
Requirements are plain text, so they work great with Git:
git init
git add *.md
git commit -m "Initial requirements for task management app"
Every requirement change will now show up in your Git history with clear diffs:
--- a/USR-001.md
+++ b/USR-001.md
@@ -4,4 +4,4 @@
created: 2025-07-22T12:19:56.950194157Z
---
-Users shall be able to create tasks with a title and description.
+Users shall be able to create tasks with a title, description, and due date.
Best Practices Demonstrated
This example shows several best practices:
- Start high-level - Begin with user requirements before diving into technical details
- One concept per requirement - Each requirement addresses a single, testable concept
- Use clear language - Requirements use "shall" to indicate mandatory behavior
- Establish traceability - Every system requirement traces to at least one user requirement
- Support multiple parents - Cross-cutting concerns can satisfy multiple needs
Next Steps
Now that you understand the basics, explore:
- Core Concepts - Deeper dive into requirements management principles
- Working with Requirements - Advanced features and techniques
- Configuration - Customizing Requiem for your project
Continue reading to learn how Requiem supports advanced requirements management practices.
Core Concepts
Requirements management is a discipline with well-established principles and practices. This chapter explores these concepts and shows how Requiem implements them.
Understanding these principles will help you:
- Structure requirements effectively
- Maintain traceability throughout the development lifecycle
- Manage changes systematically
- Collaborate effectively with stakeholders
Chapters
- Requirements Management Principles - Foundational concepts that underpin effective requirements management
- Traceability - How to track relationships between requirements, design, implementation, and tests
- Change Management - Managing requirement evolution and detecting impact
- How Requiem Supports These Principles - Requiem's design decisions and how they enable best practices
Whether you're new to requirements management or an experienced practitioner, these chapters will ground you in the "why" behind Requiem's features.
Requirements Management Principles
Effective requirements management is built on several foundational principles. Understanding these helps you structure your requirements for maximum value.
What is a Requirement?
A requirement is a documented statement of a need, constraint, or capability that a system must satisfy. Requirements answer the question: "What must the system do or be?"
Good requirements are:
- Clear - Unambiguous and understandable by all stakeholders
- Testable - You can verify whether the system satisfies the requirement
- Necessary - The requirement addresses a genuine need
- Feasible - The requirement can realistically be implemented
- Traceable - The requirement can be tracked through the development lifecycle
Requirement Levels
Requirements typically exist at multiple levels of abstraction:
User Requirements
High-level statements of user needs and goals. Written in user terminology, these describe what users need to accomplish, not how.
Example: "Users shall be able to export data in multiple formats."
System Requirements
Technical specifications derived from user requirements. These describe how the system will satisfy user needs.
Example: "The system shall provide export functionality supporting CSV, JSON, and XML formats."
Software/Hardware Requirements
Detailed requirements for specific subsystems or components.
Example: "The export module shall use the serde library for JSON serialization."
Requirement Attributes
Each requirement should have metadata:
- Unique Identifier - A stable reference (e.g., USR-001)
- Status - Draft, approved, implemented, verified, etc.
- Priority - Critical, high, medium, low
- Owner - Person or team responsible
- Rationale - Why this requirement exists
- Source - Where the requirement came from
Note: Requiem currently stores identifiers and timestamps. Status, priority, and other attributes can be added as tags or in the requirement body.
Traceability
Traceability is the ability to track relationships between requirements and other artifacts (design documents, code, tests). There are two types:
- Forward traceability - From requirements to design, code, and tests
- Backward traceability - From code and tests back to requirements
Traceability enables:
- Impact analysis (what breaks if we change this requirement?)
- Coverage analysis (are all requirements implemented and tested?)
- Compliance verification (can we prove we met all requirements?)
Requirement Dependencies
Requirements rarely exist in isolation. They form a directed graph where:
- Parent (upstream) requirements - Higher-level needs that must be satisfied
- Child (downstream) requirements - Detailed specifications that satisfy parents
Example:
USR-001: "Users shall authenticate securely"
└─ SYS-001: "System shall use OAuth 2.0"
└─ SWR-001: "Use the oauth2-rs library"
The V-Model
The V-Model visualizes how requirements flow through development:
User Requirements ←→ Acceptance Tests
↓ ↑
System Requirements ←→ Integration Tests
↓ ↑
Software Requirements ←→ Unit Tests
↓ ↑
Implementation
Each level of requirements corresponds to a level of testing that verifies those requirements.
Requirements vs. Design
A common challenge is distinguishing requirements from design:
- Requirement - WHAT the system must do
- Design - HOW the system will do it
Example:
- ❌ Requirement: "The system shall use a PostgreSQL database" (This is design)
- ✅ Requirement: "The system shall persist data reliably across restarts" (This is a requirement)
- ✅ Design: "We'll use PostgreSQL to satisfy the persistence requirement" (This is design)
However, in some contexts (particularly lower levels), the line blurs. "System shall use OAuth 2.0" might be a legitimate requirement if it's mandated by stakeholders or regulations.
Change Management
Requirements change. Good requirements management accepts this and provides mechanisms to:
- Track changes - Know what changed, when, and why
- Analyze impact - Understand what's affected by a change
- Trigger reviews - Ensure dependent requirements and tests are updated
- Maintain history - Preserve the evolution of requirements
Validation vs. Verification
Two distinct but related concepts:
- Validation - Are we building the right thing? (Do requirements match user needs?)
- Verification - Are we building the thing right? (Does implementation match requirements?)
Validation often involves stakeholder reviews. Verification involves testing and inspection.
Why These Principles Matter
Following these principles provides:
- Clarity - Everyone understands what's being built
- Accountability - Clear ownership and traceability
- Quality - Testable requirements lead to better testing
- Agility - Understanding impact enables confident change
- Compliance - Proof that requirements are met
Requiem's Approach
Requiem embodies these principles through:
- Plain-text markdown for clarity and accessibility
- YAML frontmatter for metadata and relationships
- UUID-based traceability with human-readable aliases
- Content fingerprinting for change detection
- Multiple parent support for complex dependencies
Continue to Traceability to see how Requiem implements these concepts in practice.
Traceability
Traceability is the cornerstone of requirements management. It's the ability to track relationships between requirements and other artifacts throughout the development lifecycle.
Why Traceability Matters
Traceability enables:
- Impact Analysis - If requirement X changes, what else is affected?
- Coverage Analysis - Are all requirements implemented? Tested?
- Compliance - Prove that every requirement has been satisfied
- Root Cause Analysis - Trace bugs back to requirements
- Change Management - Understand dependencies before making changes
Types of Traceability
Vertical Traceability
Tracks relationships between levels of requirements:
Stakeholder Needs
↓
User Requirements (USR)
↓
System Requirements (SYS)
↓
Software Requirements (SWR)
Example:
- Stakeholder: "We need to reduce data entry errors"
- USR-042: "Users shall receive validation feedback"
- SYS-078: "Form inputs shall validate on blur events"
- SWR-123: "Use the validator.js library for email validation"
Horizontal Traceability
Tracks relationships within the same level:
USR-001 ← USR-005
USR-001 ← USR-012
Example: USR-005 and USR-012 might both depend on USR-001's authentication requirement.
Forward Traceability
From requirements downstream to:
- Design documents
- Source code
- Test cases
- User documentation
Example: USR-001 → SYS-042 → test_authentication.rs
Backward Traceability
From implementation artifacts upstream to requirements:
test_login.py → SYS-042 → USR-001
This answers: "Why does this test exist?" or "Which requirement does this code satisfy?"
Traceability in Requiem
Parent-Child Links
Requiem implements vertical traceability through explicit parent-child relationships:
---
_version: '1'
uuid: ccdbddbe-d5d2-4656-b4fe-85e61c02cf63
created: 2025-07-22T13:15:27.996136510Z
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
---
The system shall validate user credentials using bcrypt hashing.
This SYS requirement explicitly traces to its parent USR-001.
Stable Identifiers (UUIDs)
Each requirement has a UUID that never changes, even if the requirement is renumbered or renamed. This enables reliable traceability over time.
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a # Stable forever
hrid: USR-001 # Might change
Human-Readable IDs (HRIDs)
While UUIDs are stable, HRIDs like USR-001 make traceability human-friendly:
- Easy to reference in conversations: "Did you implement USR-042?"
- Clear in code comments:
// Satisfies SYS-078 - Readable in reports: "Coverage: 45 of 52 SYS requirements implemented"
Multiple Parents
Unlike many tools, Requiem supports multiple parent requirements:
parents:
- uuid: <uuid-1>
hrid: USR-001
- uuid: <uuid-2>
hrid: USR-003
- uuid: <uuid-3>
hrid: USR-007
This reflects reality: a single implementation often satisfies multiple needs.
Example: A logging system might satisfy requirements for debugging, auditing, and compliance - three different parent needs.
Traceability Beyond Requiem
Requiem manages requirement-to-requirement traceability. For complete lifecycle traceability, you need:
Requirement → Code
Manual approach: Add requirement IDs in comments:
#![allow(unused)] fn main() { // Satisfies: SYS-042, SYS-043 fn validate_email(email: &str) -> Result<(), ValidationError> { // ... } }
Automated approach: Use code analysis tools to extract these tags and build traceability matrices.
Requirement → Tests
Manual approach: Reference requirements in test names or docstrings:
#![allow(unused)] fn main() { #[test] fn test_usr_042_email_validation() { // Verifies USR-042: Email validation feedback } }
Automated approach: Tools can parse test names and generate coverage reports.
Requirement → Documentation
When using Requiem with MdBook or Sphinx, you can embed requirements directly in user documentation:
## Plain Text Storage
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001 Plain Text Storage
## Statement
The tool shall store requirements as plain-text files that can be read and edited with any text editor.
## Rationale
Plain text storage enables:
- Version control integration with Git and other VCS tools
- Human review without specialized software
- Long-term archival and accessibility
- Integration with existing text-based workflows
## Acceptance Criteria
- Requirements are stored as `.md` (Markdown) files
- Files can be opened and edited in any text editor
- No proprietary or binary formats are required
- Files are compatible with standard version control systems
Requirements are stored as simple markdown files.
This ensures documentation stays synchronized with requirements.
Traceability Challenges
Maintaining Links
Manual traceability is prone to drift:
- Code changes but requirement IDs in comments aren't updated
- Tests are renamed and traceability is lost
Mitigation: Automate checks in CI. Use tools to validate that referenced requirement IDs exist.
Granularity
How fine-grained should traceability be?
- Too coarse: "This module satisfies USR-001 through USR-050" (not helpful)
- Too fine: "This line satisfies requirement X clause 2.3.1.4" (maintenance nightmare)
Balance: Trace at the function/class level for code, at the test case level for tests.
Many-to-Many Relationships
Real systems have complex relationships:
- One requirement satisfied by multiple components
- One component satisfying multiple requirements
Requiem's multiple-parent support helps, but complete traceability requires additional tooling.
Traceability Reports
Note: Automated report generation is planned but not yet implemented in Requiem.
Common traceability reports include:
Coverage Matrix
| Requirement | Designed | Implemented | Tested | Status |
|---|---|---|---|---|
| USR-001 | ✓ | ✓ | ✓ | Complete |
| USR-002 | ✓ | ✓ | ✗ | Missing Tests |
| USR-003 | ✓ | ✗ | ✗ | Not Implemented |
Dependency Graph
Visual representation of requirement relationships, showing the complete hierarchy from stakeholder needs down to implementation.
Impact Report
Given a changed requirement, list all downstream requirements, design documents, code, and tests that might be affected.
Best Practices
- Link early - Establish traceability when creating requirements, not as an afterthought
- Use consistent formats - Standardize how you reference requirements in code and tests
- Automate verification - Add CI checks that validate traceability links
- Review regularly - Periodically audit traceability to catch drift
- Keep it simple - Traceability is valuable only if maintained; avoid overly complex schemes
Next Steps
Understanding traceability enables effective change management. Continue to Change Management to learn how Requiem helps you manage evolving requirements.
Change Management
Requirements change. Users discover new needs, technology evolves, regulations update, and understanding deepens. Effective requirements management doesn't fight change - it embraces and manages it.
Why Requirements Change
Common drivers of change:
- Evolving understanding - Stakeholders clarify needs as they see prototypes
- External factors - New regulations, competitor features, market shifts
- Technical discoveries - Implementation reveals previously unknown constraints
- Scope refinement - Priorities shift as the project progresses
- Error correction - Requirements contained mistakes or ambiguities
Change Management Goals
Effective change management aims to:
- Track changes - Know what changed, when, and why
- Analyze impact - Understand ripple effects before committing
- Notify stakeholders - Alert affected parties
- Trigger reviews - Ensure dependent artifacts are updated
- Maintain history - Preserve the evolution for audit and learning
Requiem's Change Management Features
Content Fingerprinting
Every requirement has a fingerprint - a SHA256 hash of its content:
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
When a parent requirement changes, its fingerprint changes. This allows child requirements to detect that their parent has been modified.
How Fingerprinting Works
The fingerprint is computed from:
- The requirement's text content (markdown body)
- Any tags on the requirement
It does not include:
- UUID (never changes)
- HRID (might be renumbered)
- Creation timestamp
- Parent relationships
This means fingerprints change only when meaningful content changes.
Detecting Changes
When a parent requirement is edited, its fingerprint becomes stale in child requirements:
# Parent USR-001 was edited, fingerprint is now abc123...
# But child still references old fingerprint:
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda # Old!
hrid: USR-001
Note: Automated detection of stale fingerprints and triggering reviews is planned but not yet implemented.
Version Control Integration
Requiem's plain-text format provides powerful change management through Git:
Viewing Changes
git diff USR-001.md
Shows exactly what changed:
-Users shall be able to create tasks with a title and description.
+Users shall be able to create tasks with a title, description, and due date.
Change History
git log --follow USR-001.md
Shows complete history of a requirement, including:
- Who changed it
- When it changed
- Why (from commit messages)
Blame/Annotate
git blame USR-001.md
Shows who last modified each line, useful for finding the source of specific clauses.
Change Workflow
A typical requirement change workflow:
1. Propose Change
Create a branch:
git checkout -b update-authentication-requirements
Edit the requirement:
# USR-001.md
-Users shall authenticate using username and password.
+Users shall authenticate using username and password, or via OAuth providers (Google, GitHub).
2. Analyze Impact
Identify affected requirements:
# Find requirements that reference USR-001
grep -r "USR-001" *.md
Review child requirements to see if they need updates:
- SYS-042: "System shall hash passwords with bcrypt" - Still valid
- SYS-043: "System shall rate-limit login attempts" - Needs OAuth rate limiting too!
3. Update Dependent Requirements
Update child requirements to reflect the change:
# SYS-043.md
-The system shall rate-limit password login attempts to 5 per minute.
+The system shall rate-limit authentication attempts to 5 per minute, including both password and OAuth flows.
4. Review and Approve
Create a pull request:
git add USR-001.md SYS-043.md
git commit -m "Add OAuth authentication to USR-001 and update rate limiting in SYS-043"
git push origin update-authentication-requirements
The PR shows:
- Exact changes (diff)
- Affected requirements
- Commit message explaining rationale
Stakeholders review and approve.
5. Merge and Notify
After approval, merge the PR. Git history preserves:
- What changed
- When it changed
- Who approved it
- Why it changed (commit message)
Change Impact Analysis
Understanding the impact of a change is crucial. Requiem helps through:
Parent-Child Relationships
If requirement X changes, all child requirements may be affected. Review each to determine if updates are needed.
Multiple Parents
When a requirement has multiple parents and one changes, evaluate:
- Does the change conflict with other parents?
- Do child requirements still satisfy all parents?
Example:
USR-001: "Fast performance"
USR-002: "Strong encryption"
└─ SYS-042: "Use AES-256 encryption"
If USR-001 changes to require sub-millisecond response times, SYS-042's encryption choice might need reconsideration (encryption adds latency).
Review Triggers
Note: Automated review triggering is planned but not yet implemented.
In the future, Requiem will support:
Automatic Review Flags
When a requirement changes:
- Its fingerprint updates
- Child requirements detect stale fingerprints
- Those requirements are flagged for review
- Reviews can be assigned to stakeholders
- Requirements are approved or updated
- Fingerprints are refreshed
Review States
Possible states:
- Current - Fingerprint matches parent
- Suspect - Parent changed, review needed
- Under Review - Assigned for review
- Approved - Reviewed and still valid despite parent change
Best Practices
1. Write Meaningful Commit Messages
# Bad
git commit -m "Update requirements"
# Good
git commit -m "Add due date support to USR-001 per stakeholder feedback from 2025-10-15 meeting"
2. Link Changes to Issues
Reference issue trackers in commits:
git commit -m "Update authentication requirements (resolves #42)"
3. Review Dependent Requirements
When changing a requirement, always:
- Search for references to its HRID
- Review child requirements
- Check related documentation
- Update tests
4. Use Branches for Changes
Never modify requirements directly on main:
- Create a branch
- Make changes
- Get review
- Merge
This creates an audit trail and enables discussion before commitment.
5. Batch Related Changes
If changing USR-001 requires updating SYS-042 and SYS-043, do it in one commit:
git add USR-001.md SYS-042.md SYS-043.md
git commit -m "Extend authentication to support OAuth (USR-001, SYS-042, SYS-043)"
This preserves the logical relationship between changes.
Change Metrics
Useful metrics for requirement stability:
- Churn rate - How often requirements change
- Ripple effect - Average number of requirements affected by a change
- Review latency - Time from change to review completion
- Approval rate - Percentage of proposed changes accepted
High churn in high-level requirements (USR) may indicate poor initial understanding. High churn in low-level requirements (SWR) may be normal as implementation details evolve.
Handling Breaking Changes
Some changes invalidate child requirements:
Example: USR-001 requires "single-user application," but later changes to "multi-user application."
SYS requirements assuming single-user (no authentication, shared global state) are now invalid.
Process:
- Mark affected requirements as "obsolete" or delete them
- Create new requirements for multi-user scenario
- Update traceability links
- Document the change rationale
Next Steps
Now that you understand how requirements change, see how Requiem's design supports these practices: How Requiem Supports These Principles
How Requiem Supports These Principles
Now that you understand requirements management principles, let's explore how Requiem's design choices support these practices.
Plain Text: The Foundation
Requiem's most fundamental decision is storing requirements as plain text (Markdown with YAML frontmatter).
Benefits
Human Readable: Anyone with a text editor can read and edit requirements. No specialized tools required.
---
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
---
Users shall be able to export data in CSV format.
This is instantly understandable to developers, managers, and stakeholders alike.
Version Control Native: Plain text integrates seamlessly with Git, providing:
- Line-by-line diffs showing exactly what changed
- Complete history with blame and log
- Pull request workflows for review
- Branching and merging for parallel development
Tool Agnostic: Requirements aren't locked into proprietary formats. You can:
- Search with grep/ripgrep
- Process with scripts (Python, Bash, etc.)
- View in any text editor or IDE
- Preview as rendered Markdown
- Process with static site generators
Future Proof: Plain text files from 1970 are still readable today. Your requirements will outlive any proprietary tool.
Trade-offs
No GUI: Requiem doesn't provide a graphical interface. Users must be comfortable with text editors and the command line.
No Real-time Collaboration: Unlike cloud-based tools, Requiem doesn't support simultaneous editing. Use Git workflows instead.
Dual Identifiers: Stability and Usability
Requiem uses both UUIDs and Human-Readable IDs (HRIDs).
UUIDs: Stable References
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
Purpose: Permanent, globally unique identifier that never changes.
Enables:
- Renumbering requirements without breaking links
- Merging requirement sets from different sources
- Machine processing and indexing
Example: You can rename USR-001 to AUTH-001 without breaking any parent references, because they use the UUID.
HRIDs: Human Communication
hrid: USR-001
Purpose: Short, memorable identifier for human use.
Enables:
- Easy verbal communication: "Did you implement USR-042?"
- Clear code comments:
// Satisfies SYS-078 - Intuitive filenames:
USR-001.md
Example: In a meeting, saying "UUID 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a" is impractical. "USR-001" is clear and concise.
Best of Both Worlds
Parent relationships use UUIDs but store HRIDs for convenience:
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a # For machine processing
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001 # For human readers
The req clean command corrects HRIDs if requirements are renumbered, maintaining human-readability while UUIDs ensure correctness.
Content Fingerprinting: Change Detection
Every requirement's content is hashed to create a fingerprint:
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
How It Works
The fingerprint is a SHA256 hash of:
- The requirement text (markdown body)
- Any tags
This means:
- ✓ Changing the requirement text → new fingerprint
- ✓ Adding/removing tags → new fingerprint
- ✗ Changing HRID → same fingerprint (HRID is just a label)
- ✗ Adding parents → same fingerprint (relationships are separate)
Enables Change Detection
When a parent requirement changes:
- Parent's fingerprint updates
- Children still have old fingerprint
- Children are "suspect" - they might need review
Note: Automatic detection is planned but not yet implemented. Currently, you detect stale fingerprints manually or via scripts.
Future: Review Workflows
Planned features:
- Automatically flag requirements with stale parent fingerprints
- Assign reviews to stakeholders
- Track review status (current, suspect, under review, approved)
- Generate reports of suspect requirements
Multiple Parents: Modeling Reality
Many requirements management tools force a strict tree hierarchy. Requiem supports multiple parents because that's how real systems work.
Why Multiple Parents Matter
Example: A logging system might satisfy:
- USR-042: "Debugging capability"
- USR-078: "Audit trail for compliance"
- USR-091: "Performance monitoring"
Representing this as a tree forces artificial choices:
# Tree (artificial)
USR-042 (Debugging)
└─ SYS-123 (Logging) # Also satisfies USR-078 and USR-091, but structure doesn't show this
With multiple parents:
SYS-123 (Logging)
├─ USR-042 (Debugging)
├─ USR-078 (Audit trail)
└─ USR-091 (Performance monitoring)
This accurately models the requirement's purpose.
Implementation
parents:
- uuid: <uuid-1>
hrid: USR-042
- uuid: <uuid-2>
hrid: USR-078
- uuid: <uuid-3>
hrid: USR-091
Trade-off: Cycles
Multiple parents enable cycles (requirement A depends on B depends on A). Cycles are usually errors.
Note: Cycle detection is planned but not yet implemented.
Namespace Support: Scaling to Large Projects
HRIDs support optional namespaces:
USR-001 # Simple
COMPONENT-USR-001 # One namespace level
AUTH-LOGIN-SYS-042 # Multiple namespace levels
Use Cases
Large projects: Partition requirements by subsystem
AUTH-USR-001 # Authentication user requirements
AUTH-SYS-001
PAYMENT-USR-001 # Payment user requirements
PAYMENT-SYS-001
Product families: Distinguish product-specific vs. shared requirements
CORE-SYS-001 # Shared across all products
MOBILE-USR-001 # Mobile app specific
WEB-USR-001 # Web app specific
Acquisitions/Mergers: Integrate requirement sets without renumbering
LEGACY-SYS-001 # From acquired company
NEW-SYS-001 # Newly created
Implementation
Namespaces are part of the HRID format:
#![allow(unused)] fn main() { // Format: {NAMESPACE*}-{KIND}-{ID} NAMESPACE-NAMESPACE-KIND-042 }
Configure allowed namespaces in config.toml (optional).
Configuration and Flexibility
Requiem provides sane defaults but allows customization:
config.toml
_version = "1"
# Restrict to specific requirement kinds
allowed_kinds = ["USR", "SYS", "SWR", "TST"]
# Digits in HRID numbering (e.g., 001 vs 0001)
digits = 3
# Allow markdown files that aren't requirements
allow_unrecognised = false
# Allow requirements with invalid format
allow_invalid = false
This balances flexibility (customize as needed) with safety (defaults prevent common errors).
Integration Philosophy: Compose, Don't Replace
Requiem integrates with existing tools rather than replacing them:
Documentation Tools
Use with MdBook or Sphinx to embed requirements in user documentation:
# User Guide - Data Export
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001 Plain Text Storage
## Statement
The tool shall store requirements as plain-text files that can be read and edited with any text editor.
## Rationale
Plain text storage enables:
- Version control integration with Git and other VCS tools
- Human review without specialized software
- Long-term archival and accessibility
- Integration with existing text-based workflows
## Acceptance Criteria
- Requirements are stored as `.md` (Markdown) files
- Files can be opened and edited in any text editor
- No proprietary or binary formats are required
- Files are compatible with standard version control systems
To export data, click the Export button...
Requirements stay synchronized with documentation automatically.
Version Control
Works naturally with Git workflows:
- Feature branches for requirement changes
- Pull requests for review
- Merge commits for approval
- Tags for releases/versions
Static Analysis
Plain-text enables custom tooling:
# Find all USR requirements not linked by any SYS requirement
comm -23 \
<(ls USR-*.md | sort) \
<(grep -oh "USR-[0-9]*" SYS-*.md | sort -u)
CI/CD Integration
Add requirement validation to CI:
# .github/workflows/requirements.yml
- name: Validate requirements
run: req clean --dry-run # Check HRIDs are correct
Performance: Built for Scale
Requiem is written in Rust and uses parallelism for operations on large requirement sets.
Parallel Loading
When loading a directory with thousands of requirements:
#![allow(unused)] fn main() { // Uses rayon for parallel iteration let requirements: Vec<_> = md_paths .par_iter() .map(|path| load_requirement(path)) .collect(); }
This means Requiem scales to large projects (1000s of requirements) without becoming sluggish.
Efficient Indexing
Requirements are indexed by UUID in a HashMap, enabling O(1) lookups:
#![allow(unused)] fn main() { let req = tree.requirement(uuid); // Constant time }
Design Trade-offs
Every design involves trade-offs. Requiem prioritizes:
Over graphical interfaces: Plain text and CLI
- Pro: Version control, scripting, no vendor lock-in
- Con: Steeper learning curve for non-technical users
Over centralized databases: Distributed files
- Pro: Works offline, natural with Git, simple deployment
- Con: No real-time collaboration, requires file system access
Over strict tree hierarchies: Multiple parents (DAGs)
- Pro: Models reality accurately
- Con: Enables cycles (requires detection)
Over comprehensive built-in features: Composability
- Pro: Integrate with existing tools, stay focused
- Con: Some features require external tools or scripts
Summary: Why Requiem?
Requiem's design supports requirements management principles through:
- Plain text - Readable, versionable, future-proof
- Dual identifiers - Stable UUIDs + usable HRIDs
- Fingerprinting - Detect changes, enable reviews
- Multiple parents - Model complex dependencies accurately
- Namespace support - Scale to large, multi-component projects
- Composable - Works with Git, MdBook, Sphinx, custom tools
- Fast - Parallel processing for large requirement sets
These choices make Requiem a powerful tool for teams that value:
- Version control integration
- Plain-text workflows
- Speed and scalability
- Flexibility and composability
Ready to dive deeper into practical usage? Continue to Working with Requirements.
Working with Requirements
This chapter covers the practical aspects of using Requiem day-to-day. You'll learn the requirement file format, how to create and link requirements, and how to manage complex requirement relationships.
Chapters
- Requirement File Format - Understanding the YAML frontmatter and markdown structure
- Human-Readable IDs (HRIDs) - Deep dive into HRID syntax and best practices
- Creating Requirements - Using
req addeffectively - Linking Requirements - Establishing parent-child relationships
- Managing Relationships - Working with complex dependency graphs
By the end of this chapter, you'll be proficient in all core Requiem operations.
Requirement File Format
Requiem requirements are stored as markdown files with YAML frontmatter. This chapter explains the format in detail.
File Structure
A requirement file has three parts:
- YAML Frontmatter - Metadata enclosed in
---delimiters - HRID Title - The HRID as the first token in the first markdown heading
- Markdown Body - The requirement text
Example
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
parents:
- uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
hrid: USR-001
---
# SYS-001 Email Validation
The system shall validate user email addresses according to RFC 5322.
Email validation must occur before account creation.
HRID in Title
Important: The HRID (Human-Readable ID) must appear as the first token in the first markdown heading:
# USR-001 Plain Text Storage
# SYS-042 Email Validation System
# AUTH-LOGIN-SYS-001 Password Hashing
Key points:
- The HRID is the first token (word) in the heading
- Followed by a space and then the title text
- The HRID is NOT in the YAML frontmatter
- This format ensures compatibility with Sphinx and MdBook
Why this matters: This change was made to improve compatibility with documentation tools like Sphinx and MdBook, which can use the heading as the page title naturally.
YAML Frontmatter
The frontmatter contains structured metadata.
Required Fields
_version
_version: '1'
Purpose: Format version for future compatibility.
Value: Currently always '1' (quoted string).
Why it matters: If Requiem's file format evolves, this field allows newer versions to handle older files correctly.
uuid
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
Purpose: Globally unique, stable identifier.
Value: UUIDv4 (automatically generated by req add).
Why it matters: This never changes, even if the requirement is renumbered. Parent-child relationships use UUIDs, ensuring links remain valid.
created
created: 2025-07-22T12:19:56.950194157Z
Purpose: Timestamp of requirement creation.
Value: ISO 8601 format with timezone (always UTC).
Why it matters: Provides audit trail and helps understand requirement evolution.
Optional Fields
parents
parents:
- uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
hrid: USR-001
- uuid: 7a8f9e2b-1c3d-4e5f-6a7b-8c9d0e1f2a3b
fingerprint: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
hrid: USR-003
Purpose: Links to parent (upstream) requirements.
Value: List of parent objects, each containing:
uuid- Parent's stable identifierfingerprint- SHA256 hash of parent's contenthrid- Parent's human-readable ID (for convenience)
Why it matters: Establishes traceability. Multiple parents are supported.
Note: This field is absent if the requirement has no parents (e.g., top-level user requirements).
tags (planned)
tags:
- security
- authentication
- high-priority
Purpose: Categorize and filter requirements.
Status: The data structure supports tags, but there are no CLI commands to manage them yet. You can manually add tags to the YAML.
Future: Commands like req tag add USR-001 security will manage tags.
Markdown Body
The body contains the actual requirement text, written in Markdown.
Best Practices
Use Clear Language
# Good
The system shall validate email addresses before account creation.
# Less clear
Email validation is performed.
Use "shall" for mandatory requirements, "should" for recommended, "may" for optional.
One Concept Per Requirement
# Bad (multiple concepts)
The system shall validate emails and passwords and usernames.
# Good (split into separate requirements)
# USR-001.md
The system shall validate email addresses.
# USR-002.md
The system shall validate passwords for minimum strength.
# USR-003.md
The system shall validate usernames for uniqueness.
Be Testable
# Bad (not testable)
The system shall be fast.
# Good (testable)
The system shall respond to login requests within 200ms at the 95th percentile.
Include Context
The system shall hash passwords using bcrypt with a cost factor of 12.
Rationale: Bcrypt is resistant to GPU-based attacks. Cost factor 12 provides
security while maintaining acceptable login performance (< 200ms).
Markdown Features
You can use any Markdown syntax:
Headings
The first heading must contain the HRID. Subsequent headings are free-form:
# USR-001 User Authentication
## Rationale
The requirement exists because...
## Acceptance Criteria
- Criterion 1
- Criterion 2
Lists
The system shall support the following authentication methods:
1. Username and password
2. OAuth (Google, GitHub)
3. SAML SSO
Code Blocks
Example API response:
\`\`\`json
{
"user_id": "4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a",
"email": "user@example.com"
}
\`\`\`
Emphasis
The system **shall** validate emails. It *should* provide helpful error messages.
Filename Convention
Filenames must match the requirement's HRID:
USR-001.md
SYS-042.md
COMPONENT-SUBCOMPONENT-SWR-123.md
Case sensitive: USR-001.md and usr-001.md are different files (though the latter won't be recognized as a requirement).
Extension: Must be .md.
HRID Consistency: The HRID in the filename should match the HRID in the first heading. For example, USR-001.md should contain # USR-001 Title. The filename is authoritative for determining the HRID.
If the filename doesn't match the HRID format, Requiem will:
- Ignore the file (if
allow_unrecognised = truein config) - Return an error (if
allow_unrecognised = false, the default)
Parsing Rules
Frontmatter Delimiters
The YAML frontmatter must:
- Start with
---on the first line - End with
---on a line by itself - Contain valid YAML
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
Requirement text here...
Whitespace
- Leading/trailing whitespace in the body is preserved
- Empty lines between frontmatter and body are ignored
---
...frontmatter...
---
This is the first line of the body (empty lines above are ignored).
Editing Requirements
Manual Editing
You can edit requirements with any text editor:
vim USR-001.md
code SYS-042.md
nano TST-003.md
Caution: Don't modify the uuid field! This would break traceability.
Safe to edit:
- The markdown body (requirement text)
- Tags (if present)
Requiem manages (don't edit manually):
createdtimestamp- Parent
fingerprintfields (updated by linking commands)
Using Scripts
Since requirements are plain text, you can process them with scripts:
# Add a tag to all USR requirements
import re
import glob
for filename in glob.glob("USR-*.md"):
with open(filename, 'r') as f:
content = f.read()
# Add tag to frontmatter
content = content.replace(
"---\n",
"---\ntags:\n- user-facing\n",
1 # Only first occurrence
)
with open(filename, 'w') as f:
f.write(content)
Caution: Ensure scripts preserve YAML validity. Invalid YAML will cause parsing errors.
Validation
Requiem validates requirements when loading:
req clean # Loads all requirements, reports errors
Common validation errors:
- Invalid YAML: Syntax errors in frontmatter
- Missing required fields: No
uuid,created, or_version - Invalid UUID: Malformed UUID string
- Invalid timestamp: Malformed ISO 8601 date
- Duplicate UUIDs: Two requirements with the same UUID (serious error!)
File Format Evolution
The _version field allows future format changes:
Version 1 (current):
- Fields:
_version,uuid,created,parents,tags - Parents include UUID, fingerprint, and HRID
Version 2 (hypothetical future):
- Might add:
status,priority,owner - Older Requiem versions can still read V1 files
Real-World Examples
Want to see actual requirement files following this format? Browse the Example Project which contains 21 real requirements used by Requiem itself:
- USR-001: Plain Text Storage - Simple user requirement
- SYS-001: Markdown File Format with YAML Frontmatter - System requirement with parent link
These demonstrate the file format in practice with proper frontmatter, parent links, and well-structured content.
Next Steps
Now that you understand the file format, learn about Human-Readable IDs (HRIDs) and their syntax rules.
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/categoryID= 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:
- Filename:
USR-001.md,COMPONENT-SYS-042.md - 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.
Creating Requirements
The req add command creates new requirements with automatically generated metadata.
Basic Usage
req add <KIND>
This creates a requirement with the next available ID for the specified KIND.
Examples
# Create USR-001
req add USR
# Create USR-002
req add USR
# Create SYS-001
req add SYS
Output:
Added requirement USR-001
Added requirement USR-002
Added requirement SYS-001
Command Options
Specify Parent Requirements
Create a requirement already linked to parents:
req add <KIND> --parents <PARENT1>,<PARENT2>,...
Alias: -p for --parents
Examples
# Create SYS-001 linked to USR-001
req add SYS --parents USR-001
# Create SYS-002 linked to both USR-001 and USR-002
req add SYS --parents USR-001,USR-002
# Using short form
req add SYS -p USR-001,USR-002
Specify Root Directory
By default, req operates in the current directory. Use --root to specify a different directory:
req --root /path/to/requirements add USR
Alias: -r for --root
This is useful when running Requiem from outside the requirements directory:
# Run from project root
req --root ./docs/requirements add USR
# Using short form
req -r ./docs/requirements add USR
Verbosity
Control log output:
req -v add USR # INFO level
req -vv add USR # DEBUG level
req -vvv add USR # TRACE level
More v's = more verbose. Useful for troubleshooting.
Generated Content
When you run req add USR, a file USR-001.md is created with:
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001
Generated fields:
_version: Always'1'(current format version)uuid: A random UUIDv4created: Current timestamp in ISO 8601 format (UTC)# USR-001: First heading with HRID (title text is initially empty)
Empty body: You need to add the requirement title and text yourself.
Adding Content
After creating a requirement, edit it to add content:
req add USR
# Output: Added requirement USR-001
# Edit the file
vim USR-001.md
# or
code USR-001.md
Add your requirement title and text:
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001 CSV Export
Users shall be able to export data in CSV format.
## Rationale
CSV is a universally supported format for data interchange.
Note that the HRID (USR-001) is the first token in the heading, followed by the title. Save the file. Your requirement is now complete.
Creating with Parents
When you specify parents, they're included in the frontmatter:
req add SYS --parents USR-001
Creates SYS-001.md:
---
_version: '1'
uuid: 81e63bac-4035-47b5-b273-ac13e47a2ff6
created: 2025-07-22T13:14:40.510075462Z
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
---
# SYS-001
Generated parent fields:
uuid: Copied from USR-001's UUIDfingerprint: Computed from USR-001's current contenthrid: USR-001 (for human readability in frontmatter)
Generated heading:
# SYS-001: First heading with HRID (you'll add the title text when editing)
Multiple Parents
req add SYS --parents USR-001,USR-002,USR-003
Creates SYS-001.md with three parent entries:
parents:
- uuid: <USR-001 UUID>
fingerprint: <USR-001 fingerprint>
hrid: USR-001
- uuid: <USR-002 UUID>
fingerprint: <USR-002 fingerprint>
hrid: USR-002
- uuid: <USR-003 UUID>
fingerprint: <USR-003 fingerprint>
hrid: USR-003
Using Namespaces
Create requirements with namespaces by including them in the KIND:
# Create AUTH-USR-001
req add AUTH-USR
# Create AUTH-LOGIN-SYS-001
req add AUTH-LOGIN-SYS
# Create PAYMENT-API-SWR-001
req add PAYMENT-API-SWR
The filename matches the full HRID:
AUTH-USR-001.md
AUTH-LOGIN-SYS-001.md
PAYMENT-API-SWR-001.md
Workflow Recommendations
Create High-Level First
Start with user requirements:
req add USR
req add USR
req add USR
Edit them to add content. Then create system requirements that satisfy them:
req add SYS --parents USR-001
req add SYS --parents USR-001
req add SYS --parents USR-002
This top-down approach ensures traceability from the start.
Create in Batches
If you know you need five user requirements:
for i in {1..5}; do req add USR; done
This creates USR-001 through USR-005. Then edit each file to add content.
Use Version Control
After creating requirements, commit them:
req add USR
req add USR
git add USR-001.md USR-002.md
git commit -m "Add initial user requirements (placeholders)"
# Edit the files, then commit again
git add USR-001.md USR-002.md
git commit -m "Add content to USR-001 and USR-002"
This creates a clear history of requirement evolution.
Error Conditions
Parent Not Found
req add SYS --parents USR-999
If USR-999.md doesn't exist, you'll get an error:
Error: Failed to load requirement USR-999
Solution: Ensure parent requirements exist before linking to them.
Invalid HRID Format
req add usr-001 # Trying to specify ID manually (not supported)
The KIND should not include the ID. Use:
req add USR # Correct - ID is auto-assigned
Malformed Parent List
req add SYS --parents USR-001, USR-002 # Space after comma
Don't include spaces in the parent list:
req add SYS --parents USR-001,USR-002 # Correct
Advanced: Scripting Requirement Creation
For bulk creation with structured content, use shell scripts:
#!/bin/bash
# Create and populate multiple user requirements
requirements=(
"Users shall authenticate via username and password"
"Users shall reset forgotten passwords via email"
"Users shall enable two-factor authentication"
)
for i in "${!requirements[@]}"; do
req add USR
hrid="USR-$(printf '%03d' $((i+1)))"
# Append requirement text to the file
echo "${requirements[$i]}" >> "$hrid.md"
done
This creates USR-001, USR-002, and USR-003 with predefined content.
Next Steps
Once you've created requirements, you'll often need to link them together. Learn how in Linking Requirements.
Templates
Templates provide default body content when creating new requirements, helping maintain consistency across your requirements documentation.
Overview
When you create a new requirement using req add <KIND>, the tool looks for a template file in the .req/templates/ directory. If found, the template content is used as the body of the new requirement. The HRID is automatically generated, and the title can be provided via the --title flag or edited after creation.
Template Location
Templates are stored as markdown files in the .req/templates/ directory:
your-requirements/
├── .req/
│ └── templates/
│ ├── USR.md # Template for USR requirements
│ ├── SYS.md # Template for SYS requirements
│ └── AUTH-USR.md # Template for AUTH-USR requirements
├── config.toml
├── USR-001.md
└── SYS-001.md
Template Matching
When creating a requirement, templates are matched in order of specificity:
- Full prefix match: If creating
AUTH-USR-001, looks for.req/templates/AUTH-USR.md - KIND-only match: If not found, looks for
.req/templates/USR.md - No template: If neither exists, creates empty content
This allows you to:
- Define general templates for kinds (e.g.,
USR.mdfor all user requirements) - Override with namespace-specific templates (e.g.,
AUTH-USR.mdfor auth user requirements)
Creating Templates
Templates should contain body content only, starting with level-2 headings (##). The level-1 heading with HRID and title is automatically generated by the tool.
Simple Text Template
The simplest template is just plain text:
[Describe the requirement here]
Save this as .req/templates/USR.md.
Structured Template
For more structure, use markdown sections starting with level-2 headings:
## Description
[Detailed description]
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
## Notes
[Additional notes]
Important: Do not include a level-1 heading (#) in templates. The tool automatically generates the heading with the HRID.
Namespace-Specific Template
Create specialized templates for namespaced requirements:
## Security Considerations
[Describe security implications]
## Implementation
[Authentication mechanism details]
## Test Strategy
[How to verify this auth requirement]
Save this as .req/templates/AUTH-USR.md.
Using Templates
Automatic Template Application
When you create a requirement without content flags, the template body is automatically used:
# Without title - creates requirement with empty title and template body
req add USR
# With title - creates requirement with specified title and template body
req add USR --title "User Registration"
The generated file will have this structure:
---
_version: '1'
uuid: ...
created: ...
---
# USR-001 User Registration
[Template body content starts here]
Overriding Templates
Templates are ignored when you provide content via CLI flags:
# Template ignored - uses title and body from flags
req add USR -t "Custom Title" -b "Custom content"
# Template ignored - uses title from flag
req add USR -t "Custom Title"
# Template ignored - uses body from flag
req add USR -b "Custom content"
Examples
Software Project Templates
.req/templates/USR.md:
## Statement
[Describe the user-facing requirement]
## User Value
[Why does the user need this?]
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
.req/templates/SYS.md:
## Statement
[Describe the system-level implementation requirement]
## Technical Notes
[Implementation details]
## Testing
[How to verify]
Aerospace Project Templates
.req/templates/URQT.md (User Requirements):
## Description
[User requirement description]
## Rationale
[Justification]
## Verification Method
[Test, Analysis, Inspection, or Demonstration]
.req/templates/SRQT.md (Software Requirements):
## Specification
[Detailed technical specification]
## Derived From
[Parent URQT reference]
## Verification Method
[Test method]
## Criticality
[DAL level]
Best Practices
Keep Templates Simple
Templates should provide structure without being overly prescriptive:
✓ Good: [Describe the requirement]
✗ Too prescriptive: The system SHALL [verb] [object] [condition]
Use Placeholders
Use square brackets for clear placeholders:
[Describe the requirement here]
**Rationale**: [Why is this needed?]
Team Conventions
Document your team's template conventions:
## Description
[One paragraph summary]
## Details
[Detailed specification with sub-sections as needed]
## Testing
[How to verify this requirement]
Version Control
Commit templates to version control alongside your requirements:
git add .req/templates/
git commit -m "Add requirement templates"
Updating Templates
Templates only affect new requirements. To update existing requirements:
- Update the template file
- Manually edit existing requirements to match (if desired)
- Or use the template as a guide for new requirements only
Common Patterns
Minimal Templates
For projects that prefer freeform text:
[Requirement description]
Structured Templates
For projects requiring specific sections:
## Specification
[Technical details]
## Rationale
[Why this is needed]
## Verification
[How to test]
Compliance Templates
For regulated industries:
## Requirement
[Requirement text]
## Compliance
**Standard**: [e.g., DO-178C]
**Criticality**: [e.g., DAL A]
## Verification
**Method**: [Test, Analysis, Inspection, Demonstration]
**Criteria**: [Pass/fail criteria]
Troubleshooting
Template Not Being Used
Problem: Created requirement is empty even though template exists.
Check:
- Template file is in
.req/templates/directory - Template filename matches KIND exactly (case-sensitive)
- Template file has
.mdextension - You didn't use
-tor-bflags (which override templates)
Wrong Template Being Used
Problem: Expected namespace-specific template but got general template.
Reason: Namespace-specific template file doesn't exist.
Solution: Create .req/templates/<NAMESPACE>-<KIND>.md
Example: For AUTH-USR-001, create .req/templates/AUTH-USR.md
Real-World Example
Want to see templates in action? Check out the templates used by the Requiem project itself:
- USR Template - User requirements template with Statement, Rationale, and Acceptance Criteria sections
- SYS Template - System requirements template with Statement, Implementation Notes, and Verification sections
These templates are used to create all requirements in the Example Project, demonstrating professional structure and best practices.
Linking Requirements
The req link command establishes parent-child relationships between requirements, creating traceability throughout your requirement hierarchy.
Basic Usage
req link <CHILD> <PARENT>
This adds PARENT to CHILD's parent list.
Example
req link SYS-001 USR-001
Output:
Linked SYS-001 to USR-001
Now SYS-001.md contains:
---
_version: '1'
uuid: 81e63bac-4035-47b5-b273-ac13e47a2ff6
created: 2025-07-22T13:14:40.510075462Z
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
---
...requirement content...
Multiple Parents
You can link a child to multiple parents by running req link multiple times:
req link SYS-001 USR-001
req link SYS-001 USR-002
req link SYS-001 USR-003
Now SYS-001.md has three parents:
parents:
- uuid: <USR-001 UUID>
fingerprint: <USR-001 fingerprint>
hrid: USR-001
- uuid: <USR-002 UUID>
fingerprint: <USR-002 fingerprint>
hrid: USR-002
- uuid: <USR-003 UUID>
fingerprint: <USR-003 fingerprint>
hrid: USR-003
Linking at Creation Time
Instead of linking after creation, you can specify parents when creating:
# Instead of:
req add SYS
req link SYS-001 USR-001
req link SYS-001 USR-002
# Do:
req add SYS --parents USR-001,USR-002
This is more efficient and ensures traceability from the start.
What Gets Updated
When you run req link CHILD PARENT:
- CHILD file is modified: The parent entry is added to the YAML frontmatter
- PARENT file is NOT modified: Parent doesn't know about its children
This is a directed relationship: children point to parents, not vice versa.
Finding Children
To find all children of a requirement, search files:
grep -l "hrid: USR-001" *.md
This shows all requirements that list USR-001 as a parent.
Parent Information
Each parent entry contains three fields:
UUID (Required)
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
The stable, unique identifier of the parent. This is the canonical reference that enables reliable traceability even if the parent is renumbered.
Fingerprint (Required)
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
A SHA256 hash of the parent's content at the time of linking. This enables change detection:
- Parent content changes → fingerprint changes
- Child still has old fingerprint → signals that parent has changed
- Child should be reviewed to ensure it's still valid
HRID (Required)
hrid: USR-001
The human-readable ID of the parent. This is for convenience when reading the YAML. The actual relationship is based on the UUID.
If the parent is renumbered, the HRID can be corrected with req clean (covered in Maintaining Requirements).
Linking Across Namespaces
You can link requirements with different namespaces:
req link PAYMENT-SYS-001 CORE-USR-001
The namespaces don't need to match. Links are based on UUIDs, which are globally unique across all namespaces.
Error Conditions
Child Not Found
req link SYS-999 USR-001
If SYS-999.md doesn't exist:
Error: Failed to load requirement SYS-999
Parent Not Found
req link SYS-001 USR-999
If USR-999.md doesn't exist:
Error: Failed to load requirement USR-999
Duplicate Link
Linking a child to the same parent twice:
req link SYS-001 USR-001
req link SYS-001 USR-001
This creates duplicate entries in the parent list. Avoid this by checking existing links before adding new ones.
Note: Duplicate detection is not currently implemented but may be added in future versions.
Typical Linking Patterns
One-to-Many (Parent → Children)
One user requirement satisfied by multiple system requirements:
USR-001
├─ SYS-001
├─ SYS-002
└─ SYS-003
req add USR
req add SYS --parents USR-001
req add SYS --parents USR-001
req add SYS --parents USR-001
Many-to-One (Parents → Child)
One system requirement satisfying multiple user requirements:
USR-001 ─┐
USR-002 ─┼─ SYS-001
USR-003 ─┘
req add USR
req add USR
req add USR
req add SYS --parents USR-001,USR-002,USR-003
Many-to-Many
Complex dependencies:
USR-001 ─┬─ SYS-001
└─ SYS-002
USR-002 ─┬─ SYS-002
└─ SYS-003
req add SYS --parents USR-001
req add SYS --parents USR-001,USR-002
req add SYS --parents USR-002
Best Practices
Link During Creation When Possible
# Preferred
req add SYS --parents USR-001
# Works but requires two commands
req add SYS
req link SYS-001 USR-001
Establish Traceability Early
Link requirements as you create them, not as an afterthought. This ensures your hierarchy is always traceable.
Document Linking Rationale
In the requirement body, explain why each parent link exists:
---
parents:
- hrid: USR-001
...
- hrid: USR-003
...
---
The system shall provide OAuth authentication.
Satisfies USR-001 (secure login) and USR-003 (third-party integration).
Validate Links in Code Review
When reviewing requirement changes, check that:
- New requirements link to appropriate parents
- Links are not duplicated
- Parent requirements actually exist
Unlinking (Not Yet Supported)
Currently, there's no req unlink command. To remove a parent link, manually edit the child file:
# Before
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
- uuid: 7a8f9e2b-1c3d-4e5f-6a7b-8c9d0e1f2a3b
fingerprint: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
hrid: USR-002
# After (removed USR-002)
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
Be careful to preserve valid YAML syntax.
Visualizing Links
Since links aren't bidirectional in the files, you may want to generate visual representations:
# Simple script to list parent-child relationships
for file in *.md; do
hrid=$(basename "$file" .md)
parents=$(grep "hrid:" "$file" | awk '{print $2}')
for parent in $parents; do
echo "$parent -> $hrid"
done
done
Output:
USR-001 -> SYS-001
USR-001 -> SYS-002
USR-002 -> SYS-002
You can pipe this to graph visualization tools like Graphviz.
Next Steps
Learn how to work with complex requirement relationships in Managing Relationships.
Managing Relationships
As your requirements grow, the dependency graph becomes complex. This chapter covers strategies for managing intricate requirement relationships.
Understanding Requirement Graphs
Requirements form a directed acyclic graph (DAG):
- Directed: Parent-child relationships have a direction (child → parent)
- Acyclic: No circular dependencies (requirement A → B → C → A)
- Graph: Nodes (requirements) connected by edges (parent-child links)
Note: Cycle detection is planned but not yet implemented. Currently, you must avoid cycles manually.
Hierarchical Levels
A typical hierarchy has 3-5 levels:
Stakeholder Needs
↓
User Requirements (USR)
↓
System Requirements (SYS)
↓
Software Requirements (SWR) / Hardware Requirements (HWR)
↓
Test Requirements (TST)
Each level derives from the one above and is verified by the one below.
Complex Relationships
Cross-Cutting Requirements
Some requirements affect multiple areas:
USR-001 (Login feature) ─┐
USR-002 (Data export) ├─ SYS-042 (Logging)
USR-003 (Admin panel) ┘
Logging satisfies needs from login (debug), export (audit), and admin (monitoring).
Implementation:
req add SYS --parents USR-001,USR-002,USR-003
Derived Requirements
One parent spawns many children:
USR-001 (Secure authentication)
├─ SYS-001 (Password hashing)
├─ SYS-002 (Rate limiting)
├─ SYS-003 (Session management)
└─ SYS-004 (OAuth support)
Implementation:
req add USR
req add SYS --parents USR-001 # SYS-001
req add SYS --parents USR-001 # SYS-002
req add SYS --parents USR-001 # SYS-003
req add SYS --parents USR-001 # SYS-004
Composite Requirements
Multiple parents combine into one child:
SYS-010 (User data API) ─┐
SYS-015 (Auth middleware) ─┼─ SWR-042 (Protected endpoint implementation)
SYS-022 (JSON serialization)─┘
Implementation:
req add SWR --parents SYS-010,SYS-015,SYS-022
Traceability Queries
Finding relationships in a large requirement set:
Find All Children of a Requirement
grep -l "hrid: USR-001" *.md
Lists all files that have USR-001 as a parent.
Find All Parents of a Requirement
grep "hrid:" SYS-042.md | awk '{print $2}'
Extracts parent HRIDs from SYS-042.
Find Requirements Without Parents
for file in SYS-*.md; do
if ! grep -q "^parents:" "$file"; then
echo "$file has no parents"
fi
done
Identifies top-level requirements at a given level (might be an error).
Find Requirements Without Children
for usr in USR-*.md; do
hrid=$(basename "$usr" .md)
if ! grep -q "hrid: $hrid" SYS-*.md; then
echo "$hrid has no children"
fi
done
Finds user requirements not satisfied by any system requirements (coverage gap).
Avoiding Common Problems
Circular Dependencies
Problem: A → B → C → A creates a cycle.
req link B A
req link C B
req link A C # Creates cycle!
Detection (manual): Trace parent chains to ensure they terminate.
Prevention: Enforce strict hierarchy levels (USR → SYS → SWR → TST, never backward).
Note: Automatic cycle detection is planned.
Orphaned Requirements
Problem: Requirements with no parents or children.
USR with no children: Unimplemented user needs (coverage gap).
SYS with no parents: Requirements without justification (why does this exist?).
Detection: Use the scripts above to find orphans.
Wrong-Level Links
Problem: Skipping levels in the hierarchy.
USR-001 → SWR-042 # Skips SYS level!
Prevention: Enforce that USR links only to SYS, SYS links only to SWR, etc.
Exception: Sometimes justified in small projects, but generally avoided.
Excessively Granular Links
Problem: Too many fine-grained requirements with complex links.
SYS-001 (Email validation)
├─ SWR-001 (Regex pattern)
├─ SWR-002 (Error message)
├─ SWR-003 (UI feedback)
├─ SWR-004 (Logging)
└─ SWR-005 (Internationalization)
Solution: Combine related low-level requirements or accept coarser traceability.
Refactoring Requirements
As understanding evolves, you may need to restructure:
Splitting a Requirement
Original:
USR-001: Users shall authenticate and manage their profiles.
Split into:
USR-001: Users shall authenticate securely.
USR-002: Users shall manage their profile information.
Process:
- Create new requirement (USR-002)
- Update child requirements to link to appropriate parent
- Update original requirement text
- Mark as obsolete or delete if no longer needed
Merging Requirements
Two requirements are redundant:
USR-001: Users shall export data.
USR-003: Users shall download reports.
Process:
- Choose one to keep (USR-001)
- Update its text to cover both concepts
- Relink children of USR-003 to USR-001
- Delete USR-003
Reorganizing Hierarchy
Moving requirements between levels or namespaces:
Before:
SYS-042: OAuth integration
After:
AUTH-SYS-042: OAuth integration
Process:
- Rename file:
mv SYS-042.md AUTH-SYS-042.md - Run
req cleanto update HRIDs in child requirements - Manually update any external references (documentation, code comments)
Documentation Strategies
Requirement Specification Documents
Generate human-readable specs from requirements:
# Simple concatenation
cat USR-*.md > user-requirements.md
cat SYS-*.md > system-requirements.md
Traceability Matrices
Create tables showing parent-child relationships:
| User Req | System Reqs |
|---|---|
| USR-001 | SYS-001, SYS-002, SYS-003 |
| USR-002 | SYS-002, SYS-004 |
| USR-003 | SYS-005 |
Generate with scripts:
for usr in USR-*.md; do
hrid=$(basename "$usr" .md)
children=$(grep -l "hrid: $hrid" SYS-*.md | sed 's/.md//' | paste -sd,)
echo "| $hrid | $children |"
done
Visual Dependency Graphs
Use Graphviz to visualize relationships:
echo "digraph requirements {"
for file in *.md; do
child=$(basename "$file" .md)
grep "hrid:" "$file" | awk -v child="$child" '{print " " $2 " -> " child}'
done
echo "}"
Output:
digraph requirements {
USR-001 -> SYS-001
USR-001 -> SYS-002
USR-002 -> SYS-002
USR-002 -> SYS-003
}
Render with:
./generate-graph.sh | dot -Tpng > requirements-graph.png
Scalability Considerations
Large Projects (100s of requirements)
- Use namespaces to partition by component
- Generate indexes and matrices automatically
- Consider directory structure:
auth/USR-*.md,payment/USR-*.md
Very Large Projects (1000s of requirements)
- Parallel loading (Requiem does this automatically)
- External database for complex queries
- Dedicated requirements management integration tools
Multi-Product Families
- Shared requirements in
CORE-* - Product-specific in
MOBILE-*,WEB-*, etc. - Cross-reference shared requirements from product-specific ones
Best Practices Summary
- Maintain strict hierarchy - USR → SYS → SWR → TST
- Document cross-cutting concerns - Explain why a requirement has many parents
- Avoid cycles - Keep relationships acyclic
- Review orphans regularly - Find requirements without links
- Refactor thoughtfully - Restructure as understanding evolves
- Automate traceability checks - Use scripts in CI
- Visualize complex graphs - Generate diagrams for stakeholder review
Real-World Example
See traceability in action in the Example Project, where you can explore:
- USR-006 (Requirement Templates) traces to 5 system requirements (SYS-011 through SYS-015)
- USR-004 (Graph Analysis) traces to 5 system requirements (SYS-004, 005, 008, 009, 010)
- Multiple requirements with single parents, demonstrating various relationship patterns
Browse the User Requirements page to see the complete traceability tree visualized.
Next Steps
Learn how to configure Requiem for your project in Configuration.
Configuration
Requiem provides sensible defaults but allows customization through configuration files and directory structure.
This chapter covers:
- Configuration File - The
config.tomlformat and options - Directory Structure - Organizing requirements on disk
- Namespaces - Using namespaces for large projects
Proper configuration helps Requiem adapt to your project's needs.
Configuration File
Requiem uses a TOML configuration file named config.toml in the root of your requirements directory to customize behavior.
Location
The configuration file must be named config.toml and placed in the root directory where your requirements are stored:
my-requirements/
├── config.toml ← Configuration file
├── USR-001.md
├── USR-002.md
└── SYS-001.md
If no configuration file exists, Requiem uses sensible defaults and continues without error.
File Format
The configuration file is written in TOML (Tom's Obvious Minimal Language), a simple, human-readable format.
Minimal Example
The simplest valid configuration:
_version = "1"
This accepts all defaults. The _version field is required for future format compatibility.
Complete Example
A configuration using all available options:
_version = "1"
# Restrict requirement kinds
allowed_kinds = ["USR", "SYS", "SWR", "TST"]
# Number of digits in HRID numbering
digits = 3
# Allow non-requirement markdown files
allow_unrecognised = false
# Allow requirements with invalid formatting
allow_invalid = false
Configuration Options
_version (required)
_version = "1"
Type: String (quoted)
Default: N/A (required field)
Purpose: Specifies the configuration format version. This enables future format changes while maintaining backward compatibility.
Current version: "1" (as a string, not a number)
Example:
_version = "1" # Correct
Invalid:
_version = 1 # Wrong: must be a quoted string
allowed_kinds (optional)
allowed_kinds = ["USR", "SYS", "SWR", "TST"]
Type: Array of strings
Default: [] (empty array = all kinds allowed)
Purpose: Restricts which requirement kinds (the KIND component of HRIDs) are permitted in your project.
When to use:
- Enforce project standards (e.g., only USR, SYS, TST requirements allowed)
- Prevent typos (USR-001 vs. UST-001)
- Document your requirement taxonomy
Behavior:
- Empty array (default): Any kind is accepted
- Non-empty array: Only listed kinds are valid
Example - Aerospace project:
allowed_kinds = ["URQT", "SRQT", "SWRQT", "HWRQT", "TEST"]
# User Requirements (URQT), System Requirements (SRQT), etc.
Example - Software project:
allowed_kinds = ["USR", "SYS", "SWR", "TST", "DOC"]
Enforcement:
When allowed_kinds is non-empty, attempting to create a requirement with a disallowed kind will fail:
$ req add INVALID
Error: Kind 'INVALID' is not in the allowed list
digits (optional)
digits = 3
Type: Unsigned integer
Default: 3
Purpose: Specifies the minimum number of digits used in HRID numbering. IDs are zero-padded to this width.
Valid values: Any positive integer, though 3 or 4 are most common.
Behavior:
With digits = 3:
USR-001
USR-002
...
USR-099
USR-100 # Exceeds 3 digits when needed
With digits = 4:
USR-0001
USR-0002
...
USR-9999
USR-10000 # Exceeds 4 digits when needed
Choosing a value:
digits = 3: Projects with < 1000 requirements per kinddigits = 4: Projects with 1000+ requirements per kinddigits = 5: Very large projects
Note: This setting affects display format only. Parsing accepts any number of digits:
USR-1,USR-01,USR-001all parse as ID 1- Display format uses the configured padding
Example - Large project:
digits = 4
# Requirements display as USR-0001, USR-0002, etc.
allow_unrecognised (optional)
allow_unrecognised = false
Type: Boolean
Default: false
Purpose: Controls whether markdown files that don't match the HRID pattern are allowed in the requirements directory.
Behavior:
false (default - strict mode):
- Only files matching the HRID pattern (e.g.,
USR-001.md) are allowed - Any other
.mdfile causes an error during loading - Ensures clean, requirements-only directory
true (permissive mode):
- Files with non-HRID names are silently ignored
- Useful when requirements live alongside other documentation
When to use true:
Integration with documentation tools:
docs/
├── config.toml ← allow_unrecognised = true
├── introduction.md ← Ignored (not an HRID)
├── architecture.md ← Ignored
├── USR-001.md ← Loaded as requirement
└── USR-002.md ← Loaded as requirement
Mixed content repositories:
project-docs/
├── README.md ← Ignored
├── CHANGELOG.md ← Ignored
├── requirements/
│ ├── USR-001.md ← Loaded
│ └── SYS-001.md ← Loaded
When to use false (default):
- Dedicated requirements directory
- Strict separation between requirements and other docs
- Catch typos (e.g.,
US-001.mdinstead ofUSR-001.md)
Error example with allow_unrecognised = false:
$ req clean
Error: Unrecognised file: README.md
allow_invalid (optional)
allow_invalid = false
Type: Boolean
Default: false
Purpose: Controls whether requirement files with invalid YAML frontmatter or formatting errors are allowed.
Behavior:
false (default - strict mode):
- Requirements must have valid YAML frontmatter
- Missing required fields cause errors
- Ensures data integrity
true (permissive mode):
- Invalid requirements are skipped with warnings
- Partial loading allows working with partially correct data
- Useful during migration or recovery
Validation checks:
- Valid YAML syntax
- Required fields present (
_version,uuid,created) - Valid UUID format
- Valid timestamp format
- Valid parent structure (if present)
When to use true:
- Migrating from another tool (gradual fix-up)
- Recovering from manual editing errors
- Development/debugging
When to use false (default):
- Production use
- Ensure data quality
- Catch errors early
Error example with allow_invalid = false:
$ req clean
Error: Invalid requirement USR-001.md: missing required field 'uuid'
Warning example with allow_invalid = true:
$ req clean
Warning: Skipping invalid requirement USR-001.md: missing required field 'uuid'
Successfully loaded 42 requirements (1 skipped)
Configuration Strategy
Start Simple
Begin with minimal configuration:
_version = "1"
Add constraints as your project matures.
Recommended Settings
Small project (< 100 requirements):
_version = "1"
digits = 3
allow_unrecognised = false
allow_invalid = false
Large project (> 1000 requirements):
_version = "1"
allowed_kinds = ["USR", "SYS", "SWR", "HWR", "TST", "DOC"]
digits = 4
allow_unrecognised = false
allow_invalid = false
Integrated documentation project:
_version = "1"
allowed_kinds = ["USR", "SYS"]
digits = 3
allow_unrecognised = true # Mixed with other docs
allow_invalid = false
Migration project:
_version = "1"
digits = 3
allow_unrecognised = true
allow_invalid = true # Temporarily permissive during migration
Validation
Validate your configuration by running:
req clean
This loads all requirements and reports configuration-related errors.
Successful validation:
$ req clean
# No output = success
Configuration error:
$ req clean
Error: Failed to parse config file: missing field '_version'
Configuration Examples
Regulated Industry (Aerospace)
_version = "1"
# DO-178C levels: User, System, Software, Hardware, Test
allowed_kinds = ["URQT", "SRQT", "SWRQT", "HWRQT", "TRQT"]
# Large project
digits = 4
# Strict validation
allow_unrecognised = false
allow_invalid = false
Agile Software Project
_version = "1"
# User stories, system reqs, tests
allowed_kinds = ["USR", "SYS", "TST"]
# Small/medium project
digits = 3
# Allow flexibility
allow_unrecognised = false
allow_invalid = false
Multi-Component System
_version = "1"
# Component-prefixed kinds
allowed_kinds = [
"USR", # Cross-cutting user requirements
"AUTH-SYS", # Authentication subsystem
"PAY-SYS", # Payment subsystem
"REPORT-SYS", # Reporting subsystem
]
digits = 3
allow_unrecognised = false
allow_invalid = false
Troubleshooting
Config file not recognized
Problem: Changes to config.toml don't take effect.
Solution: Ensure the file is named exactly config.toml (lowercase, no extra extensions) and is in the requirements root directory.
Parse errors
Problem: Error: Failed to parse config file
Solution: Validate TOML syntax:
- Strings must be quoted:
_version = "1", not_version = 1 - Arrays use square brackets:
allowed_kinds = ["USR", "SYS"] - Check for typos in field names
Use a TOML validator or linter if needed.
Unexpected behavior
Problem: Requirements are rejected unexpectedly.
Solution:
- Check
allowed_kinds- ensure the kinds you're using are listed - Check
allow_unrecognised- set totrueif mixing requirements with other docs - Check
allow_invalid- consider temporarily enabling for debugging
Future Configuration Options
Planned configuration options (not yet implemented):
namespace_separator: Customize the separator in namespaced HRIDsrequire_namespaces: Enforce namespace usagemax_parents: Limit number of parent requirementstag_validation: Restrict allowed tag valuesreview_policies: Configure review workflow behavior
Next Steps
- Learn about Directory Structure for organizing requirements
- Understand Namespaces for large projects
Directory Structure
Requiem is flexible about how you organize requirements on disk. This chapter explains directory organization options and best practices.
Directory Structure Modes
Requiem supports two fundamental modes for organizing requirements, controlled by the subfolders_are_namespaces configuration option:
1. Filename-Based Mode (Default)
Configuration: subfolders_are_namespaces = false (or omitted)
In this mode, the full HRID is encoded in the filename, and directory structure is purely organizational:
my-requirements/
├── USR-001.md → HRID: USR-001
├── SYS-002.md → HRID: SYS-002
├── auth-USR-003.md → HRID: auth-USR-003
└── custom/folder/
└── system-REQ-004.md → HRID: system-REQ-004
Use when: You want maximum flexibility in folder organization without affecting requirement namespaces.
2. Path-Based Mode
Configuration: subfolders_are_namespaces = true
In this mode, subfolders encode the namespace, and the filename contains only KIND-ID:
my-requirements/
├── REQ-001.md → HRID: REQ-001 (no namespace)
├── system/
│ └── auth/
│ ├── REQ-002.md → HRID: system-auth-REQ-002
│ └── USR/
│ └── 003.md → HRID: system-auth-USR-003 (KIND from parent)
The filename format is automatically inferred:
- Numeric only (e.g.,
003.md) → KIND taken from parent folder - KIND-ID (e.g.,
REQ-002.md) → KIND and ID from filename
Use when: You want folder structure to directly mirror requirement namespaces.
Basic Structure
At minimum, you need a directory containing requirement markdown files:
my-requirements/
├── USR-001.md
├── USR-002.md
├── SYS-001.md
└── SYS-002.md
That's it! No initialization or hidden directories required.
With Configuration
Add a config.toml for project-specific settings:
my-requirements/
├── config.toml ← Configuration
├── USR-001.md
├── USR-002.md
├── SYS-001.md
└── SYS-002.md
The configuration file is optional but recommended for projects with specific needs.
Using Subdirectories
Requiem recursively searches subdirectories, enabling hierarchical organization.
Organize by Requirement Kind
requirements/
├── config.toml
├── user/
│ ├── USR-001.md
│ ├── USR-002.md
│ └── USR-003.md
├── system/
│ ├── SYS-001.md
│ ├── SYS-002.md
│ └── SYS-003.md
└── test/
├── TST-001.md
└── TST-002.md
Advantages:
- Clear separation of requirement levels
- Easy to navigate
- Natural for large projects
Note: In filename-based mode (default), directory names don't affect requirement behavior. user/USR-001.md and system/USR-001.md would create a filename conflict (both have HRID USR-001), so use different kinds. In path-based mode, these would have different HRIDs: user-USR-001 and system-USR-001.
Organize by Feature
requirements/
├── config.toml
├── authentication/
│ ├── USR-001.md # User login
│ ├── SYS-001.md # Auth service
│ └── TST-001.md # Auth tests
├── payment/
│ ├── USR-002.md # Payment processing
│ ├── SYS-002.md # Payment gateway
│ └── TST-002.md # Payment tests
└── reporting/
├── USR-003.md # Report generation
└── SYS-003.md # Report engine
Advantages:
- Groups related requirements
- Mirrors feature structure
- Good for feature-based development
Organize by Component
requirements/
├── config.toml
├── frontend/
│ ├── WEB-USR-001.md
│ ├── WEB-SYS-001.md
│ ├── MOBILE-USR-001.md
│ └── MOBILE-SYS-001.md
└── backend/
├── API-SYS-001.md
├── DB-SYS-001.md
└── CACHE-SYS-001.md
Advantages:
- Aligns with system architecture
- Clear ownership boundaries
- Natural for microservices
Note: Consider using namespaces in HRIDs (e.g., WEB-USR-001) to avoid conflicts.
Deep Hierarchies
Requiem supports arbitrary nesting:
requirements/
├── config.toml
└── product/
├── core/
│ ├── auth/
│ │ ├── USR-001.md
│ │ └── SYS-001.md
│ └── data/
│ ├── USR-002.md
│ └── SYS-002.md
└── plugins/
├── export/
│ └── USR-003.md
└── import/
└── USR-004.md
Caution: Deep hierarchies can be harder to navigate. Consider flat or shallow structures unless your project naturally requires depth.
Flat vs. Hierarchical
Flat Structure
requirements/
├── config.toml
├── USR-001.md
├── USR-002.md
├── ...
├── USR-050.md
├── SYS-001.md
├── SYS-002.md
├── ...
└── SYS-100.md
Advantages:
- Simple and straightforward
- Easy to understand
- Works well for small/medium projects (< 100 requirements)
Disadvantages:
- Directory listing can become unwieldy with many requirements
- Harder to navigate in file browser with 100+ files
Best for: Small to medium projects, single-component systems.
Hierarchical Structure
requirements/
├── config.toml
├── user-requirements/
│ └── (50 files)
├── system-requirements/
│ └── (100 files)
└── test-requirements/
└── (150 files)
Advantages:
- Scalable to large projects (1000+ requirements)
- Natural organization
- Easier to navigate
Disadvantages:
- Slightly more complex
- Must decide on hierarchy scheme
Best for: Large projects, multi-component systems.
Best Practices
1. Start Flat, Refactor When Needed
Begin with a flat structure:
requirements/
├── config.toml
├── USR-001.md
└── SYS-001.md
Introduce subdirectories when you have 50+ requirements or natural groupings emerge.
2. Use Consistent Naming
If using subdirectories, name them consistently:
requirements/
├── 1-user-requirements/
├── 2-system-requirements/
├── 3-software-requirements/
└── 4-test-requirements/
Or:
requirements/
├── user/
├── system/
├── software/
└── test/
Avoid: Mixing naming schemes (user_reqs/, system-requirements/, Tests/).
3. Keep Shallow (2-3 Levels Max)
Prefer:
requirements/
└── user/
└── USR-001.md
Over:
requirements/
└── level1/
└── level2/
└── level3/
└── level4/
└── USR-001.md
Deep hierarchies are hard to navigate and remember.
4. Align with Team Structure
Organize to match how your team works:
Team by feature:
requirements/
├── login-team/
├── payment-team/
└── reporting-team/
Team by layer:
requirements/
├── product-managers/ (USR requirements)
├── architects/ (SYS requirements)
└── developers/ (SWR requirements)
5. Don't Encode Information in Paths
Bad:
requirements/
└── high-priority/
└── USR-001.md # Priority encoded in directory
Good:
requirements/
└── USR-001.md
# USR-001.md content:
---
tags:
- high-priority
---
The requirement text...
Use tags or content for metadata, not directory structure. Directories are for organization only.
Special Cases
Mixed Content (Requirements + Documentation)
If requirements live alongside other documentation:
docs/
├── config.toml
├── introduction.md ← Not a requirement
├── architecture.md ← Not a requirement
├── requirements/
│ ├── USR-001.md ← Requirement
│ └── SYS-001.md ← Requirement
└── user-guide.md ← Not a requirement
Set allow_unrecognised = true in config.toml to allow non-requirement markdown files.
Integration with MdBook
MdBook projects:
docs/
├── book.toml ← MdBook config
├── src/
│ ├── SUMMARY.md ← MdBook table of contents
│ ├── chapter1.md ← Documentation
│ ├── USR-001.md ← Requirement (can be in SUMMARY.md)
│ └── USR-002.md ← Requirement
└── config.toml ← Requiem config (allow_unrecognised = true)
See Integration > Using with MdBook for details.
Integration with Sphinx
Sphinx projects:
docs/
├── conf.py ← Sphinx config
├── index.md
├── requirements/
│ ├── config.toml ← Requiem config
│ ├── USR-001.md ← Requirement
│ └── SYS-001.md ← Requirement
└── other-content.md
See Integration > Using with Sphinx for details.
Monorepo Structure
Large monorepos with multiple products:
monorepo/
├── products/
│ ├── web-app/
│ │ └── requirements/
│ │ ├── config.toml
│ │ └── WEB-USR-001.md
│ └── mobile-app/
│ └── requirements/
│ ├── config.toml
│ └── MOBILE-USR-001.md
└── shared/
└── requirements/
├── config.toml
└── CORE-SYS-001.md
Each product/component has its own independent requirements directory with separate config.toml.
File System Considerations
Case Sensitivity
Linux/Mac: Filenames are case-sensitive
USR-001.mdandusr-001.mdare different files- Requiem only recognizes
USR-001.md(uppercase HRID)
Windows: Filenames are case-insensitive
USR-001.mdandusr-001.mdrefer to the same file- Use consistent casing to avoid issues
Recommendation: Always use uppercase HRIDs to avoid cross-platform issues.
Symbolic Links
Requiem follows symbolic links when scanning for requirements:
requirements/
├── current -> v2.0/ ← Symlink
├── v1.0/
│ └── USR-001.md
└── v2.0/
└── USR-001.md
Caution: Ensure symlinks don't create cycles or duplicate requirements.
Hidden Files and Directories
Files and directories starting with . are typically ignored by Requiem (following standard Unix convention):
requirements/
├── .git/ ← Ignored
├── .DS_Store ← Ignored (Mac)
├── config.toml
└── USR-001.md
Performance Considerations
Large Directories
Requiem uses parallel loading for performance:
requirements/
├── USR-001.md
├── USR-002.md
├── ...
└── USR-5000.md # 5000 files loads quickly due to parallelism
Performance: Requiem can handle thousands of requirements efficiently. Directory structure has minimal performance impact.
Network File Systems
If requirements are on a network drive:
- Initial loading may be slower
- Consider using subdirectories to localize access patterns
- Parallel loading helps mitigate network latency
Choosing Between Modes
When to Use Filename-Based Mode (Default)
Advantages:
- Maximum flexibility - organize folders however you want
- Easy to move files between folders without changing HRIDs
- Works well with arbitrary organizational schemes (by feature, by team, etc.)
- Explicit namespaces visible in every filename
Best for:
- Projects where folder structure is organizational, not semantic
- Teams that reorganize folders frequently
- Mixed organizational schemes
- When you want full control over namespaces
Example:
requirements/
├── team-a/
│ └── auth-USR-001.md → HRID: auth-USR-001
└── team-b/
└── auth-SYS-002.md → HRID: auth-SYS-002
When to Use Path-Based Mode
Advantages:
- Cleaner filenames (shorter, less redundant)
- Folder structure enforces namespace consistency
- Natural for hierarchical component structures
- Automatic namespace creation from folders
Best for:
- Projects with stable, hierarchical component structures
- When folder structure mirrors system architecture
- Microservices or multi-component systems
- When you want enforced namespace-folder alignment
Example:
requirements/
├── auth/
│ ├── USR-001.md → HRID: auth-USR-001
│ └── SYS-002.md → HRID: auth-SYS-002
└── payment/
├── USR-001.md → HRID: payment-USR-001
└── SYS-002.md → HRID: payment-SYS-002
Comparison Table
| Aspect | Filename-Based | Path-Based |
|---|---|---|
| Filename contains | Full HRID | KIND-ID only |
| Namespace from | Filename | Folder path |
| Folder flexibility | High | Low (tied to namespace) |
| File move impact | None | Changes HRID |
| Filename length | Longer | Shorter |
| Default mode | Yes | No |
Migration Between Modes
Converting from Filename-Based to Path-Based
- Update configuration:
# config.toml
_version = "1"
subfolders_are_namespaces = true
- Reorganize files to match namespace structure:
# Before (filename-based):
# requirements/
# ├── auth-USR-001.md
# └── payment-USR-002.md
# Create namespace folders
mkdir -p auth payment
# Move and rename files
mv auth-USR-001.md auth/USR-001.md
mv payment-USR-002.md payment/USR-002.md
# After (path-based):
# requirements/
# ├── auth/
# │ └── USR-001.md
# └── payment/
# └── USR-002.md
- Verify:
req clean
Converting from Path-Based to Filename-Based
- Flatten files and encode namespace in filename:
# Before (path-based):
# requirements/
# ├── auth/
# │ └── USR-001.md (HRID: auth-USR-001)
# └── payment/
# └── USR-002.md (HRID: payment-USR-002)
# Move and rename with full HRID
mv auth/USR-001.md auth-USR-001.md
mv payment/USR-002.md payment-USR-002.md
# Remove now-empty folders
rmdir auth payment
# After (filename-based):
# requirements/
# ├── auth-USR-001.md
# └── payment-USR-002.md
- Update configuration:
# config.toml
_version = "1"
subfolders_are_namespaces = false
- Verify:
req clean
Note: When converting between modes, the HRID (and thus UUID) remains the same, preserving all links and history.
Migration and Refactoring
Reorganizing Files
To reorganize directory structure in filename-based mode:
- Move requirement files:
mkdir system
mv SYS-*.md system/
- Verify:
req clean
- Commit:
git add -A
git commit -m "Organize system requirements into subdirectory"
Safe because: Requirements are identified by HRID (filename), not path. Moving files doesn't break links.
Splitting Directories
To split a large flat directory:
# Before
requirements/
├── USR-001.md (100 files)
# After
requirements/
├── user/
│ └── USR-001.md (100 files)
└── system/
└── SYS-001.md (100 files)
Steps:
mkdir user system test
mv USR-*.md user/
mv SYS-*.md system/
mv TST-*.md test/
req clean # Verify
Summary
Key Takeaways:
- Flexible: Flat or hierarchical, your choice
- Recursive: Subdirectories are automatically scanned
- Simple: Directory names don't affect requirement behavior
- Scalable: Supports small projects (10s) to large (1000s)
- Reorganizable: Safe to move files (links use UUIDs, not paths)
Recommendations:
- Start flat, add structure as needed
- Keep shallow (2-3 levels max)
- Organize by kind, feature, or component
- Use consistent naming conventions
- Align with team structure
Next Steps
- Understand Namespaces for large multi-component projects
- Learn about Version Control Best Practices
Namespaces
Namespaces extend HRIDs with prefixes to organize requirements in large, multi-component projects. This chapter explains when and how to use them.
What Are Namespaces?
A namespace is an optional prefix in an HRID that provides additional context:
USR-001 # No namespace
AUTH-USR-001 # One namespace level: AUTH
AUTH-LOGIN-USR-001 # Two namespace levels: AUTH, LOGIN
A-B-C-USR-001 # Three namespace levels: A, B, C
HRID Format with Namespaces
Complete format:
{NAMESPACE-}*{KIND}-{ID}
Where:
NAMESPACE: Zero or more namespace segmentsKIND: Requirement kind (e.g., USR, SYS)ID: Numeric identifier
Examples:
USR-001 # KIND=USR, ID=001, namespace=[]
COMPONENT-USR-001 # KIND=USR, ID=001, namespace=[COMPONENT]
AUTH-LOGIN-SYS-042 # KIND=SYS, ID=042, namespace=[AUTH, LOGIN]
When to Use Namespaces
Large Projects
Projects with many requirements benefit from namespacing:
# Without namespaces (confusion)
USR-001 # Which component?
USR-002 # Auth or payment?
USR-003 # Mobile or web?
# With namespaces (clarity)
AUTH-USR-001 # Authentication user requirement
PAY-USR-002 # Payment user requirement
MOBILE-USR-003 # Mobile app user requirement
Multi-Component Systems
Systems with distinct components or subsystems:
FRONTEND-USR-001
FRONTEND-SYS-001
BACKEND-USR-001
BACKEND-SYS-001
DATABASE-SYS-001
CACHE-SYS-001
Product Families
Related products sharing requirements:
CORE-USR-001 # Shared across all products
CORE-SYS-001
MOBILE-USR-001 # Mobile-specific
MOBILE-SYS-001
WEB-USR-001 # Web-specific
WEB-SYS-001
Team Boundaries
Map namespaces to team ownership:
TEAM-ALPHA-USR-001 # Team Alpha's requirements
TEAM-BETA-USR-001 # Team Beta's requirements
SHARED-USR-001 # Cross-team requirements
Acquisitions and Mergers
Integrate acquired codebases without renumbering:
LEGACY-USR-001 # From acquired company (existing numbering)
NEW-USR-001 # Newly created requirements
When NOT to Use Namespaces
Small Projects
Projects with < 100 requirements rarely need namespaces:
# Simple project (no namespace needed)
USR-001
USR-002
SYS-001
SYS-002
Namespaces add complexity without benefit for small projects.
Single Component
If your project is a single cohesive unit:
# Single-component app
USR-001
SYS-001
TST-001
No need for namespaces unless planning for future growth.
Shallow Hierarchy
If requirements naturally form a flat or shallow structure, namespaces may be overkill.
Namespace Strategies
Strategy 1: By Component
Organize by system architecture:
AUTH-USR-001 # Authentication component
AUTH-SYS-001
API-USR-001 # API gateway
API-SYS-001
DB-SYS-001 # Database layer
CACHE-SYS-001 # Cache layer
Advantages:
- Mirrors system architecture
- Clear component ownership
- Natural for microservices
When to use: Systems with well-defined component boundaries.
Strategy 2: By Layer
Organize by architectural layer:
UI-USR-001 # User interface layer
UI-SYS-001
BL-SYS-001 # Business logic layer
DATA-SYS-001 # Data layer
Advantages:
- Aligns with layered architectures
- Clear layer separation
When to use: Traditional n-tier applications.
Strategy 3: By Feature
Organize by product feature:
LOGIN-USR-001 # Login feature
LOGIN-SYS-001
LOGIN-TST-001
PAYMENT-USR-001 # Payment feature
PAYMENT-SYS-001
PAYMENT-TST-001
REPORTING-USR-001 # Reporting feature
REPORTING-SYS-001
Advantages:
- Groups related requirements
- Feature-based development
- Easy feature scoping
When to use: Feature-driven development, agile teams.
Strategy 4: Hybrid
Combine multiple levels:
MOBILE-AUTH-USR-001 # Mobile app, auth feature, user requirement
MOBILE-PAY-SYS-001 # Mobile app, payment feature, system requirement
WEB-AUTH-USR-001 # Web app, auth feature, user requirement
WEB-PAY-SYS-001 # Web app, payment feature, system requirement
Advantages:
- Maximum organization
- Clear context at a glance
When to use: Very large, multi-product systems.
Caution: Deep hierarchies can make HRIDs verbose. Balance clarity with brevity.
Namespace Depth
Single Level
COMPONENT-USR-001
Typical: 5-10 namespaces per project
Best for: Medium projects with distinct components
Two Levels
PRODUCT-COMPONENT-USR-001
Typical: 3-5 top-level namespaces, 3-7 sub-namespaces each
Best for: Large projects, product families
Three+ Levels
ORG-PRODUCT-COMPONENT-USR-001
Typical: Very large enterprises
Best for: Massive systems, multi-organization projects
Caution: HRIDs become long and unwieldy. Consider if truly necessary.
Namespace Naming Conventions
Use Descriptive Names
# Good
AUTH-USR-001 # Clear: authentication
PAYMENT-SYS-001 # Clear: payment processing
# Less clear
A-USR-001 # What is "A"?
MOD1-SYS-001 # What is "MOD1"?
Keep Short
# Good
AUTH-USR-001 # 4 characters
PAY-USR-001 # 3 characters
# Too long
AUTHENTICATION-USR-001 # 14 characters
PAYMENT-PROCESSING-USR-001 # 18 characters
Aim for 3-8 characters per namespace segment.
Use Consistent Casing
# Good (all uppercase)
AUTH-USR-001
PAYMENT-SYS-001
# Inconsistent (avoid)
auth-USR-001
Payment-SYS-001
Convention: Use uppercase to match KIND and ID conventions.
Avoid Special Characters
# Good
AUTH-USR-001
PAYMENT-SYS-001
# Bad (don't use)
AUTH_USR-001 # Underscore confuses parsing
AUTH.USR.001 # Periods not supported
AUTH/USR/001 # Slashes not supported
Only use hyphens as separators.
Implementation
Creating Namespaced Requirements
Use the namespace in the KIND argument:
# Single namespace
req add AUTH-USR
# Output: Added requirement AUTH-USR-001
# Two namespace levels
req add MOBILE-AUTH-SYS
# Output: Added requirement MOBILE-AUTH-SYS-001
Linking Namespaced Requirements
Linking works identically:
req link MOBILE-AUTH-SYS-001 AUTH-USR-001
Namespaces don't affect link functionality.
File Naming
Filenames match HRIDs exactly:
requirements/
├── AUTH-USR-001.md
├── AUTH-SYS-001.md
├── PAYMENT-USR-001.md
└── MOBILE-AUTH-USR-001.md
Namespace Organization with Directories
Combine namespaces with directory structure:
Option 1: Match Namespace to Directory
requirements/
├── auth/
│ ├── AUTH-USR-001.md
│ └── AUTH-SYS-001.md
└── payment/
├── PAYMENT-USR-001.md
└── PAYMENT-SYS-001.md
Advantages:
- Reinforces namespace structure
- Easy to navigate
Disadvantage:
- Redundancy (namespace in filename and path)
Option 2: Namespace Without Matching Directory
requirements/
├── AUTH-USR-001.md
├── AUTH-SYS-001.md
├── PAYMENT-USR-001.md
└── PAYMENT-SYS-001.md
Advantages:
- Simpler structure
- No redundancy
Disadvantage:
- Large directories if many components
Option 3: Hybrid
requirements/
├── mobile/
│ ├── MOBILE-AUTH-USR-001.md
│ └── MOBILE-PAY-USR-001.md
└── web/
├── WEB-AUTH-USR-001.md
└── WEB-PAY-USR-001.md
Advantages:
- Top level organized by directory
- Sub-level by namespace
Configuration
Restricting Namespaces
Currently, Requiem doesn't restrict namespaces via configuration. Any valid namespace is accepted.
Workaround: Use allowed_kinds to restrict full namespaced kinds:
_version = "1"
allowed_kinds = [
"AUTH-USR",
"AUTH-SYS",
"PAYMENT-USR",
"PAYMENT-SYS",
]
This allows:
AUTH-USR-001✓PAYMENT-SYS-001✓
This blocks:
INVALID-USR-001✗USR-001✗ (no namespace)
Limitation: Doesn't enforce namespace structure for multi-level namespaces.
Future Configuration
Planned configuration options (not yet implemented):
# Planned (not implemented)
[namespaces]
required = true # Require all HRIDs to have namespaces
allowed = ["AUTH", "PAYMENT", "REPORTING"]
separator = "-" # Customize separator (default: "-")
max_depth = 2 # Limit namespace depth
Migration to Namespaces
Adding Namespaces to Existing Project
Challenge: Existing requirements lack namespaces:
USR-001.md
USR-002.md
SYS-001.md
Goal: Add namespaces:
AUTH-USR-001.md
PAYMENT-USR-002.md
AUTH-SYS-001.md
Steps:
-
Plan namespace scheme: Decide which requirements belong to which namespace
-
Rename files:
mv USR-001.md AUTH-USR-001.md
mv USR-002.md PAYMENT-USR-002.md
mv SYS-001.md AUTH-SYS-001.md
-
Update HRIDs in frontmatter: Edit each file to update the HRID references
-
Fix parent links: Run
req cleanto correct parent HRIDs
req clean
- Verify:
req clean # Should succeed with no errors
- Commit:
git add -A
git commit -m "Add namespaces to requirements"
Note: UUIDs remain unchanged, so relationships are preserved.
Examples
Example 1: E-commerce Platform
# Customer-facing requirements
CUSTOMER-USR-001.md # Customer account management
CUSTOMER-USR-002.md # Product browsing
# Cart and checkout
CART-USR-001.md # Shopping cart
CHECKOUT-USR-001.md # Checkout process
# Payment processing
PAYMENT-SYS-001.md # Payment gateway integration
PAYMENT-SYS-002.md # PCI compliance
# Order management
ORDER-SYS-001.md # Order processing
ORDER-SYS-002.md # Order fulfillment
# Inventory
INVENTORY-SYS-001.md # Stock management
Example 2: Aerospace System
# Aircraft levels (DO-178C)
AIRCRAFT-URQT-001.md # Aircraft-level user requirement
# System level
AVIONICS-SRQT-001.md # Avionics system requirement
ENGINES-SRQT-001.md # Engine system requirement
# Software level
AVIONICS-FCS-SWRQT-001.md # Flight control software
AVIONICS-NAV-SWRQT-001.md # Navigation software
# Hardware level
AVIONICS-FCS-HWRQT-001.md # Flight control hardware
Example 3: Mobile and Web Apps
# Shared requirements
CORE-USR-001.md # Cross-platform user requirement
CORE-SYS-001.md # Backend API
# Mobile-specific
MOBILE-IOS-USR-001.md # iOS-specific requirement
MOBILE-ANDROID-USR-001.md # Android-specific
# Web-specific
WEB-USR-001.md # Web app requirement
WEB-ADMIN-USR-001.md # Admin panel requirement
Best Practices
1. Design Namespace Scheme Early
Define your namespace strategy before creating many requirements:
# Document in config.toml comments
_version = "1"
# Namespace scheme:
# - AUTH: Authentication and authorization
# - PAYMENT: Payment processing
# - REPORTING: Report generation
# - ADMIN: Administration features
allowed_kinds = ["AUTH-USR", "AUTH-SYS", "PAYMENT-USR", "PAYMENT-SYS"]
2. Keep Namespaces Shallow
Prefer 1-2 levels over 3+:
# Good
AUTH-USR-001
# Still good
MOBILE-AUTH-USR-001
# Getting long
COMPANY-PRODUCT-MOBILE-AUTH-USR-001
3. Document Namespace Meanings
Create a README or documentation page:
# Namespace Guide
- **AUTH**: Authentication and authorization
- **PAYMENT**: Payment processing
- **REPORT**: Report generation
- **ADMIN**: Administration and configuration
4. Consistent Abbreviations
Use consistent abbreviations across namespaces:
# Good (consistent)
AUTH-USR-001
AUTH-SYS-001
PAYMENT-USR-001
PAYMENT-SYS-001
# Inconsistent (avoid)
AUTH-USR-001
AUTHENTICATION-SYS-001
PAY-USR-001
PAYMENT_PROCESSING-SYS-001
5. Consider Future Growth
Choose namespaces that won't become obsolete:
# Flexible
MOBILE-USR-001 # Can add MOBILE-IOS, MOBILE-ANDROID later
# Inflexible
IPHONE-USR-001 # What about iPads? Android?
Summary
Key Takeaways:
- Optional: Namespaces are optional; use when beneficial
- Hierarchical: Support multiple levels (1-3 typical)
- Flexible: Choose strategy that fits your project
- Scalable: Essential for large, multi-component systems
- Format:
{NAMESPACE-}*{KIND}-{ID}
When to use:
- Large projects (> 100 requirements)
- Multi-component systems
- Product families
- Team boundaries
- Acquisitions
When NOT to use:
- Small projects (< 100 requirements)
- Single-component systems
- When simplicity is priority
Best practices:
- Design namespace scheme early
- Keep shallow (1-2 levels)
- Use descriptive, short names
- Document namespace meanings
- Consider future growth
Next Steps
- Review Directory Structure for organizing namespaced requirements
- Learn about Creating Requirements with namespaces
Maintaining Requirements
Requirements evolve throughout a project's lifecycle. This chapter covers maintenance tasks that keep your requirements accurate and consistent.
Overview
Requiem provides tools for:
- Correcting HRIDs - Fixing parent references after renaming requirements
- Fingerprints and Change Detection - Understanding how Requiem tracks content changes
- Review Workflows - Managing reviews when requirements change (planned feature)
Common Maintenance Tasks
Regular Cleanup
Run req clean periodically to ensure consistency:
req clean
This command:
- Loads all requirements
- Validates frontmatter and format
- Corrects parent HRIDs if requirements were renamed
- Reports any errors or inconsistencies
Frequency: Run after major reorganizations or before releases.
After Renaming Requirements
If you rename requirement files (change HRIDs):
- Rename the file:
mv USR-001.md USR-100.md
- Update parent references:
req clean
- Verify changes:
git diff
The clean command updates all parent HRIDs automatically.
After Editing Content
When requirement text changes:
- Edit the markdown body
- Save the file
- Commit with a descriptive message:
git add USR-001.md
git commit -m "Update USR-001: clarify email validation requirement"
The fingerprint updates automatically when content changes, enabling change detection.
Managing Requirements at Scale
For projects with hundreds of requirements:
Use scripts: Automate repetitive tasks
# Example: Add a tag to all USR requirements
for file in USR-*.md; do
# Add tag via sed or Python script
done
Use version control: Track changes over time
# See what requirements changed this sprint
git log --since="2 weeks ago" --name-only -- "*.md"
Use traceability: Understand impact of changes
# Find all children of a requirement
grep -r "uuid: <parent-uuid>" *.md
Maintenance Best Practices
1. Validate Before Committing
Always run req clean before committing changes:
req clean && git add -A && git commit -m "Update requirements"
This catches errors before they enter the repository.
2. Use Descriptive Commit Messages
Bad:
git commit -m "Update reqs"
Good:
git commit -m "Add USR-042: user data export requirement
Related to feature request #123. Establishes requirements
for CSV and JSON export formats."
3. Review Changes Carefully
Before committing requirement changes, review diffs:
git diff USR-001.md
Ensure:
- UUID hasn't changed (breaking traceability)
- Metadata is valid
- Content changes are intentional
4. Keep Requirements Current
Regular reviews: Schedule periodic requirement reviews
Update as needed: Don't let requirements become stale documentation
Archive obsolete requirements: Move to archived/ subdirectory rather than deleting
5. Document Maintenance Procedures
Create a CONTRIBUTING.md or similar:
# Requirements Maintenance
## Before Committing
1. Run `req clean`
2. Review diffs carefully
3. Don't modify UUIDs manually
## Renaming Requirements
1. Rename file
2. Run `req clean` to update parent references
3. Commit changes
## Adding Tags
Use YAML syntax in frontmatter...
Tools and Automation
Pre-commit Hooks
Automate validation with Git hooks:
#!/bin/bash
# .git/hooks/pre-commit
echo "Validating requirements..."
req clean
if [ $? -ne 0 ]; then
echo "Error: Requirements validation failed"
exit 1
fi
CI/CD Integration
Add requirement validation to CI:
# .github/workflows/requirements.yml
name: Validate Requirements
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Requiem
run: cargo install requirements-manager
- name: Validate requirements
run: req clean
working-directory: ./requirements
Scripts for Common Tasks
Find requirements without tests:
#!/bin/bash
# List USR requirements not linked by any TST requirement
comm -23 \
<(ls USR-*.md | sed 's/.md//' | sort) \
<(grep -oh "USR-[0-9]*" TST-*.md | sort -u)
Generate traceability report:
#!/bin/bash
# Show parent-child relationships
for file in *.md; do
hrid=$(basename "$file" .md)
parents=$(grep "hrid:" "$file" | awk '{print $2}')
if [ -n "$parents" ]; then
echo "$hrid -> $parents"
fi
done
Error Recovery
Corrupted Frontmatter
If YAML becomes invalid:
- Check syntax:
req clean # Reports specific error
- Fix manually or restore from Git:
git checkout HEAD -- USR-001.md
- Use online YAML validator if needed
Duplicate UUIDs
If two requirements have the same UUID (serious error):
- Requiem will panic with error message
- Identify files with duplicate UUIDs
- Manually assign new UUID to one:
uuidgen # Generate new UUID
# Edit file, replace UUID
- Verify:
req clean
Missing Parents
If a parent requirement is deleted but children still reference it:
- Requiem reports error during
req clean - Options:
- Restore deleted parent
- Remove parent reference from child
- Link child to different parent
Merge Conflicts
When merging Git branches with requirement changes:
-
Resolve conflicts in frontmatter carefully:
- UUIDs should never conflict (unique per requirement)
- Timestamps: keep newer
- Parents: merge both sets if both added parents
-
Resolve markdown body conflicts normally
-
After resolving:
req clean # Validate merged result
Monitoring and Reporting
Requirement Statistics
Count requirements by kind:
ls USR-*.md | wc -l # User requirements
ls SYS-*.md | wc -l # System requirements
Change Tracking
Requirements changed in last month:
git log --since="1 month ago" --name-only --pretty=format: -- "*.md" | \
sort -u | grep -E "^[A-Z]+-[0-9]+\.md$"
Coverage Analysis
Find requirements without children (potential gaps):
# Find USR requirements not referenced by any SYS requirement
comm -23 \
<(ls USR-*.md | sed 's/.md//' | sort) \
<(grep -roh "USR-[0-9]*" SYS-*.md | sort -u)
Next Steps
Dive deeper into specific maintenance topics:
- Correcting HRIDs - Using the
req cleancommand - Fingerprints - How change detection works
- Review Workflows - Managing reviews (planned)
Correcting HRIDs
The req clean command corrects outdated parent HRIDs in requirement files. This chapter explains when and how to use it.
The Problem
Requirements reference their parents using HRIDs for human readability:
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001 # Human-readable reference
If you rename the parent file (USR-001.md → USR-100.md), the HRID in child requirements becomes outdated:
# Child still says:
parents:
- hrid: USR-001 # Wrong! File is now USR-100.md
The UUID remains correct (traceability is preserved), but the HRID shown to humans is misleading.
The Solution: req clean
The req clean command:
- Loads all requirements
- For each requirement, checks parent HRIDs against actual parent files
- Corrects any mismatches
- Saves updated requirements
Basic Usage
req clean
Run in your requirements directory. No output means success (all HRIDs were correct or have been fixed).
With Custom Root
req --root /path/to/requirements clean
Specify a different requirements directory.
Verbose Output
req -v clean
Shows what's being corrected:
INFO Corrected parent HRID in SYS-001: USR-001 → USR-100
INFO Corrected parent HRID in SYS-002: USR-001 → USR-100
When to Run req clean
After Renaming Requirements
Scenario: You renamed a requirement file.
Steps:
- Rename the file:
mv USR-001.md USR-100.md
- Correct parent references:
req clean
- Verify changes:
git diff
You'll see parent HRIDs updated in child requirements.
After Reorganization
Scenario: Major restructuring with many renamed files.
Steps:
- Perform renames:
mv USR-001.md AUTH-USR-001.md
mv USR-002.md PAYMENT-USR-002.md
# ... many more
- Fix all references at once:
req clean
- Verify:
git status # See all modified files
git diff # Review changes
Before Committing
Best practice: Run req clean before every commit involving requirement changes.
req clean && git add -A && git commit -m "Reorganize requirements"
This ensures the repository always has correct HRIDs.
Regular Maintenance
Frequency: Run periodically (e.g., before releases) to catch any drift.
req clean
If requirements are managed carefully, this should show no changes.
How It Works
Step 1: Load All Requirements
Requiem scans the requirements directory recursively, loading all .md files with valid HRID names.
Step 2: Build Index
Creates a UUID-to-requirement mapping:
UUID 4bfeb7d5-... → USR-100 (actual current HRID)
UUID 3fc6800c-... → SYS-001
...
Step 3: Check Each Parent Reference
For each requirement, examines parent references:
# Child requirement SYS-001.md
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
hrid: USR-001 # Check if this matches actual HRID for this UUID
Step 4: Correct Mismatches
If the HRID doesn't match:
- Look up the UUID in the index
- Find the actual current HRID
- Update the parent reference
- Save the requirement file
Step 5: Report Results
With verbose logging (-v), reports each correction. Otherwise, silent success.
Examples
Example 1: Simple Rename
Before:
requirements/
├── USR-001.md
└── SYS-001.md
SYS-001.md links to USR-001:
# SYS-001.md
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
hrid: USR-001
Rename parent:
mv USR-001.md USR-100.md
Run clean:
req clean
After:
SYS-001.md now shows correct HRID:
# SYS-001.md
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
hrid: USR-100 # Corrected!
Example 2: Multiple Children
Scenario: One parent with multiple children.
Before:
requirements/
├── USR-001.md
├── SYS-001.md (parent: USR-001)
├── SYS-002.md (parent: USR-001)
└── SYS-003.md (parent: USR-001)
Rename parent:
mv USR-001.md USR-050.md
Run clean:
req -v clean
Output:
INFO Corrected parent HRID in SYS-001: USR-001 → USR-050
INFO Corrected parent HRID in SYS-002: USR-001 → USR-050
INFO Corrected parent HRID in SYS-003: USR-001 → USR-050
All three children are updated in one command.
Example 3: Adding Namespaces
Scenario: Migrating to namespaced HRIDs.
Before:
requirements/
├── USR-001.md
├── USR-002.md
├── SYS-001.md (parent: USR-001)
└── SYS-002.md (parent: USR-002)
Rename with namespaces:
mv USR-001.md AUTH-USR-001.md
mv USR-002.md PAYMENT-USR-002.md
mv SYS-001.md AUTH-SYS-001.md
mv SYS-002.md PAYMENT-SYS-002.md
Run clean:
req clean
Result: All parent references updated to namespaced HRIDs.
Edge Cases
Requirement Not Found
Scenario: Child references a parent UUID that doesn't exist.
Example:
# SYS-001.md
parents:
- uuid: 00000000-0000-0000-0000-000000000000 # No requirement with this UUID
hrid: USR-999
Behavior: req clean panics with error message:
Error: Parent requirement 00000000-0000-0000-0000-000000000000 not found!
Resolution:
- Restore the missing parent requirement, or
- Manually remove the invalid parent reference from the child
Self-Referential Parent
Scenario: Requirement lists itself as a parent (should never happen).
Example:
# SYS-001.md
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a # Same as own UUID!
hrid: SYS-001
Behavior: req clean panics with error message:
Error: Requirement 4bfeb7d5-... is its own parent!
Resolution: Manually remove the self-reference from the frontmatter.
Circular Dependencies
Scenario: Requirement A depends on B, B depends on C, C depends on A.
Current behavior: req clean doesn't detect cycles (cycle detection is planned but not implemented).
Impact: HRIDs will be corrected, but the circular dependency remains undetected.
Workaround: Manually audit requirement relationships or use external tools.
Integration with Workflows
Pre-commit Hook
Automatically correct HRIDs before every commit:
#!/bin/bash
# .git/hooks/pre-commit
echo "Correcting requirement HRIDs..."
req clean
if [ $? -ne 0 ]; then
echo "Error: Failed to correct HRIDs"
exit 1
fi
# Stage any changes made by req clean
git add -u
Benefit: Never commit incorrect HRIDs.
Caution: Automatically stages changes. Review carefully.
CI Pipeline
Validate HRIDs in CI:
# .github/workflows/requirements.yml
- name: Validate HRIDs
run: |
req clean
if [ -n "$(git status --porcelain)" ]; then
echo "Error: HRIDs are out of sync"
git diff
exit 1
fi
Benefit: Catches incorrect HRIDs before merging.
Manual Review Workflow
For critical projects, manually review HRID corrections:
# Run clean
req clean
# Review changes
git diff
# If acceptable, commit
git add -A
git commit -m "Correct parent HRIDs after reorganization"
Performance
req clean loads all requirements in parallel, making it fast even for large projects:
- 100 requirements: < 1 second
- 1000 requirements: ~2-3 seconds
- 10000 requirements: ~15-20 seconds
Scales well due to Rust's performance and parallel processing.
Limitations
No Dry-Run Mode
Currently, req clean modifies files immediately. There's no preview mode.
Workaround: Use Git to preview changes:
req clean # Make changes
git diff # Preview
git checkout -- . # Undo if needed (before committing)
No Selective Correction
Can't correct only specific requirements; it's all-or-nothing.
Workaround: Use Git to selectively stage changes:
req clean
git add SYS-001.md SYS-002.md # Stage only specific files
Requires All Parents Present
If a parent requirement is missing, req clean fails. Can't correct partial sets.
Workaround: Ensure all requirements are present, or manually fix references.
Best Practices
1. Run Before Committing
req clean && git add -A && git commit
Make it a habit.
2. Review Changes
Always review what req clean changed:
req clean
git diff # See what was corrected
3. Use Verbose Mode for Learning
When first using req clean, run with -v to understand what it's doing:
req -v clean
4. Combine with Validation
Use req clean as a validation step:
req clean
if [ $? -eq 0 ]; then
echo "Requirements are consistent"
else
echo "Errors found"
fi
5. Document in Team Processes
Include in your team's documentation:
## Renaming Requirements
1. Rename the file
2. Run `req clean`
3. Review changes with `git diff`
4. Commit
Troubleshooting
Command Not Found
Error: req: command not found
Solution: Install Requiem:
cargo install requirements-manager
Permission Denied
Error: Error: Permission denied
Solution: Ensure you have write permissions to requirement files.
Configuration Parse Error
Error: Error: Failed to parse config file
Solution: Check config.toml syntax. Remove or fix if invalid.
Unexpected Changes
Issue: req clean makes unexpected modifications.
Diagnosis:
- Run with verbose:
req -v clean - Examine which HRIDs are being corrected
- Check if requirement files were renamed
Resolution: Review changes with git diff. Revert if incorrect.
Summary
Key points:
- Purpose: Correct outdated parent HRIDs after renaming requirements
- Usage:
req cleanin requirements directory - When: After renaming files, before committing, regular maintenance
- How: Loads all requirements, checks parent HRIDs, corrects mismatches
- Safe: Uses UUIDs for correctness; HRIDs are display-only
Best practice: Run req clean before every commit involving requirements.
Limitation: No dry-run or selective correction (yet).
Next Steps
- Learn about Fingerprints for change detection
- Understand Review Workflows (planned feature)
Fingerprints and Change Detection
Requiem uses content fingerprints to detect when requirements change. This chapter explains how fingerprints work and enable change management.
What is a Fingerprint?
A fingerprint is a cryptographic hash (SHA256) of a requirement's semantic content. It's stored in parent references:
# SYS-001.md
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
The fingerprint represents the state of USR-001 when SYS-001 was last reviewed or updated.
How Fingerprints Work
Creation
When you link a child to a parent:
req link SYS-001 USR-001
Requiem:
- Computes the fingerprint of
USR-001's content - Stores it in
SYS-001's parent reference
Updates
Fingerprints update in two scenarios:
1. When creating the link:
req link SYS-001 USR-001
# Fingerprint captured at link time
2. When the parent's content changes:
- The parent's fingerprint is recomputed automatically
- Child references keep the OLD fingerprint
- This creates a mismatch, indicating the child may need review
What's Included in the Fingerprint
Fingerprints hash:
- ✓ Markdown body: The requirement text
- ✓ Tags: Any tags in the frontmatter
Fingerprints do NOT include:
- ✗ HRID (just a label)
- ✗ UUID (stable identifier, not content)
- ✗ Created timestamp (metadata, not content)
- ✗ Parent relationships (separate from content)
Example
Requirement USR-001:
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
tags:
- authentication
- security
---
The system shall validate user email addresses according to RFC 5322.
Fingerprint computation:
Content: "The system shall validate user email addresses according to RFC 5322."
Tags: ["authentication", "security"]
→ Encode with Borsh
→ Hash with SHA256
→ Fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
Use Cases
Change Detection
Problem: A parent requirement changes. Which child requirements are affected?
Solution: Compare fingerprints.
Example:
- Initial state:
# SYS-001.md links to USR-001
parents:
- uuid: 4bfeb7d5-...
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
hrid: USR-001
- Someone edits
USR-001:
# USR-001.md
The system shall validate user email addresses according to RFC 5322.
Email validation must occur before account creation. # ← New sentence
- USR-001's fingerprint changes:
New fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
- SYS-001 still has the old fingerprint:
# SYS-001.md
parents:
- fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda # Old!
- Mismatch detected: SYS-001 needs review because its parent changed.
Impact Analysis
Question: If I change this requirement, what else is affected?
Answer: Use the req suspect command after making changes to find affected children.
Workflow:
# 1. Edit a parent requirement
vim USR-001.md # Make your changes
# 2. Check for suspect links
req suspect
# Output shows all affected children:
# SYS-001 → USR-001
# SYS-002 → USR-001
# ... (fingerprint mismatches)
# 3. Review each affected child
vim SYS-001.md
vim SYS-002.md
# 4. Accept fingerprints after review
req accept SYS-001 USR-001
req accept SYS-002 USR-001
# Or accept all at once
req accept --all
Manual process (if needed):
# 1. Get UUID of the requirement you're changing
grep "uuid:" USR-001.md
# 2. Find all requirements that reference this UUID
grep -r "uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a" *.md
# 3. Those requirements may need review after your change
Review Tracking
Goal: Track which requirements need review after upstream changes.
Current state: Basic suspect link detection implemented via req suspect and req accept commands.
Available now:
- Detect fingerprint mismatches with
req suspect - Accept individual links with
req accept <child> <parent> - Accept all suspect links with
req accept --all - CI/CD integration via exit codes
Future: Advanced review workflows with status tracking and assignments (planned feature).
Computing Fingerprints
Viewing a Requirement's Fingerprint
No built-in command yet, but you can compute it manually:
Option 1: Link to a temporary requirement
# Create temp requirement
req add TEMP
# Link to target
req link TEMP-001 USR-001
# View fingerprint in TEMP-001.md
grep "fingerprint:" TEMP-001.md
# Clean up
rm TEMP-001.md
Option 2: Use Rust/Python script
Not currently exposed via CLI. Requires custom scripting.
Comparing Fingerprints
Problem: Is my child requirement's parent reference current?
Solution: Use the req suspect command:
req suspect
This automatically:
- Loads all requirements
- Compares stored parent fingerprints with current parent fingerprints
- Lists all mismatched fingerprints (suspect links)
Example output:
Found 2 suspect link(s):
SYS-001 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-002 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
If no suspect links exist:
No suspect links found.
Exit codes:
0: All fingerprints current1: Suspect links found (useful for CI/CD)
Manual process (if needed):
- Find parent UUID and stored fingerprint in child:
# SYS-001.md
parents:
- uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
fingerprint: e533784ff58c16cbf08e436cb06f09e0076880fd707baaf55aa0f45dc4a6ccda
-
Compute current fingerprint of parent (see above)
-
Compare:
- Match: Child is current
- Mismatch: Child needs review
What Changes Affect Fingerprints
Changes that Update Fingerprints
Editing requirement text:
# Before
The system shall validate emails.
# After
The system shall validate emails according to RFC 5322.
→ Fingerprint changes
Adding/removing tags:
# Before
tags:
- authentication
# After
tags:
- authentication
- security
→ Fingerprint changes
Modifying tags:
# Before
tags:
- high-priority
# After
tags:
- medium-priority
→ Fingerprint changes
Whitespace changes in content:
# Before
The system shall validate emails.
# After
The system shall validate emails.
→ Fingerprint changes (trailing whitespace added)
Changes that DON'T Affect Fingerprints
Renaming the requirement:
mv USR-001.md USR-100.md
→ Fingerprint unchanged (HRID is not part of content)
Changing UUID (don't do this!):
# Before
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
# After
uuid: 00000000-0000-0000-0000-000000000000
→ Fingerprint unchanged (but breaks traceability!)
Changing created timestamp:
# Before
created: 2025-07-22T12:19:56Z
# After
created: 2025-08-01T10:00:00Z
→ Fingerprint unchanged
Adding/removing parents:
# Before
parents:
- uuid: ...
# After
parents:
- uuid: ...
- uuid: ... # Added parent
→ Fingerprint unchanged
Fingerprint Algorithms
Current Algorithm
Encoding: Borsh (Binary Object Representation Serializer for Hashing)
- Deterministic serialization
- Consistent across platforms
- Efficient for hashing
Hashing: SHA256
- Cryptographically secure
- 256-bit output (64 hex characters)
- Collision resistant
Process:
1. Collect content and tags
2. Serialize with Borsh: content + tags → binary
3. Hash with SHA256: binary → 256-bit hash
4. Encode as hex: hash → 64-character string
Why These Choices?
Borsh:
- Stable encoding (no ambiguity)
- Handles strings and collections consistently
- Designed for hashing use cases
SHA256:
- Industry standard
- Strong collision resistance
- Fast to compute
Benefits:
- Consistent fingerprints across systems
- Detects even small changes
- Impossible to forge (cryptographically secure)
Practical Examples
Example 1: Detecting Stale References
Scenario: USR-001 was updated 2 months ago. Are any child requirements out of date?
Process:
# Check for suspect links
req suspect
Output:
Found 1 suspect link(s):
SYS-001 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
Result: SYS-001 has a stale fingerprint and needs review.
Next steps:
# Review changes
vim USR-001.md # See what changed
vim SYS-001.md # Update if needed
# Accept the link
req accept SYS-001 USR-001
# Verify clean
req suspect
# Output: No suspect links found.
Example 2: Tag Changes
Scenario: Add a tag to a requirement.
Before:
# USR-001.md
tags:
- authentication
Fingerprint: e533784f...
After:
# USR-001.md
tags:
- authentication
- security
Fingerprint: c4020419... (changed!)
Impact: Any child requirements now have stale fingerprints.
Example 3: Whitespace-Only Changes
Scenario: Reformatting requirement text.
Before:
The system shall validate emails.
After:
The system shall validate emails.
(Added blank line)
Result: Fingerprint changes!
Caution: Even whitespace affects fingerprints. Be mindful of formatting changes.
Limitations and Future Work
Implemented Features
✓ Automatic suspect link detection
Use req suspect to find all stale fingerprints:
req suspect
# Lists all requirements with fingerprint mismatches
✓ Accepting suspect links
Update fingerprints after review:
# Accept individual link
req accept SYS-001 USR-001
# Accept all suspect links
req accept --all
✓ CI/CD integration
Exit codes enable automation:
req suspect
# Exit 0 if clean, exit 1 if suspect links found
Current Limitations
1. No review state tracking
No tracking of review status (current, under review, approved).
Planned: Review state management with status tracking and assignments.
2. No reporting
Can't generate comprehensive reports of requirement status.
Planned: req report command for traceability and review status.
3. No impact visualization
Can't see full dependency tree affected by a change.
Planned: req impact USR-001 to show affected descendants.
4. No fingerprint diff
Can't see what content changed between fingerprints.
Planned: req diff USR-001 to show fingerprint changes and content diff.
5. Whitespace sensitivity
Formatting changes trigger fingerprint updates.
Trade-off: Precision vs. false positives. Current design prioritizes detecting all changes.
Planned Features
Review state management:
req review start SYS-001
# Mark SYS-001 as "under review"
req review complete SYS-001
# Mark as "reviewed" and update fingerprints
req status
# Output:
# USR-001: current
# SYS-001: reviewed (parents unchanged since review)
# SYS-002: needs review (parent changed)
Impact analysis:
req impact USR-001
# Output:
# Direct children:
# SYS-001, SYS-002
# Indirect descendants:
# SWR-001 (via SYS-001)
# TST-001 (via SWR-001)
# Total affected: 4 requirements
Reporting:
req report review
# Generate review status report with metrics
Best Practices
1. Link Immediately After Creation
When creating a requirement with parents:
# Create requirement
req add SYS --parents USR-001
# Fingerprint is captured immediately
This ensures the fingerprint represents the baseline.
2. Check for Suspect Links Regularly
Periodically check for fingerprint mismatches:
# Check for suspect links
req suspect
# Before committing changes
req suspect || (echo "Review needed" && exit 1)
# In CI/CD pipeline
req suspect
3. Accept Links After Review
After reviewing parent changes and updating children:
# Accept individual link
req accept SYS-001 USR-001
# Or accept all after bulk review
req accept --all
This updates fingerprints to acknowledge the review.
4. Document Review Process
Include fingerprint checking in your review process:
## Requirement Review Checklist
1. Check for suspect links: `req suspect`
2. For each suspect link:
- Review parent changes
- Review child requirement text
- Update child if needed
- Accept link: `req accept CHILD PARENT`
3. Verify all clean: `req suspect`
4. Commit changes
5. Avoid Trivial Changes
Minimize whitespace-only or formatting changes to reduce fingerprint churn:
- Use consistent formatting from the start
- Configure editor to preserve formatting
- Avoid unnecessary reformatting
Troubleshooting
Unexpected Fingerprint Changes
Issue: Fingerprint changed but content looks the same.
Causes:
- Whitespace changes (trailing spaces, blank lines)
- Tag modifications
- Character encoding differences
Diagnosis:
# Show all changes including whitespace
git diff --ws-error-highlight=all USR-001.md
Fingerprint Not Updating
Issue: Changed requirement but fingerprint seems unchanged.
Explanation: Fingerprints are stored in parent references, not in the requirement itself.
Check: Look at a child requirement's parent reference to see the fingerprint.
Manual Fingerprint Edit
Issue: Accidentally edited a fingerprint in frontmatter.
Impact: Child will show incorrect fingerprint for parent.
Fix: Re-link the requirement:
req link SYS-001 USR-001
# This recalculates and stores the correct fingerprint
Summary
Key Concepts:
- Fingerprint: SHA256 hash of requirement content and tags
- Purpose: Detect when parent requirements change
- Storage: Stored in child's parent reference
- Automatic: Computed when linking requirements
- Immutable: Old fingerprints preserved in children, enabling change detection
What's Included: Markdown body + tags
What's Excluded: HRID, UUID, timestamps, parent relationships
Use Cases: Change detection, impact analysis, review tracking
Commands Available:
req suspect- List all suspect links (fingerprint mismatches)req accept <CHILD> <PARENT>- Accept suspect link after reviewreq accept --all- Accept all suspect links
Current State: Basic suspect link detection implemented
Future: Advanced review workflows with state tracking and assignments
Next Steps
- Learn about Review Workflows (planned feature)
- Understand Correcting HRIDs for maintaining references
Review Workflows
Note: Basic suspect link detection is implemented. Advanced review workflow features (state tracking, assignments, notifications) are planned for future releases.
Review workflows enable teams to track which requirements need review after upstream changes are detected via fingerprint mismatches.
Available Now: Suspect Link Detection
Requiem can now automatically detect and manage suspect links:
Commands
req suspect - List all requirements with fingerprint mismatches
req suspect
Example output:
Found 3 suspect link(s):
SYS-001 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-002 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-005 → USR-004
Stored fingerprint: 407c6e3413d5b3fa
Current fingerprint: c28afe188a974322
Exit codes:
0: No suspect links (all current)1: Suspect links found (useful for CI/CD)
req accept <CHILD> <PARENT> - Accept a suspect link after review
req accept SYS-001 USR-001
# Output: Accepted suspect link: SYS-001 → USR-001
req accept --all - Accept all suspect links
req accept --all
# Output:
# Accepted 3 suspect link(s):
# SYS-001 → USR-001
# SYS-002 → USR-001
# SYS-005 → USR-004
Basic Workflow
# 1. Check for suspect links
req suspect
# 2. Review parent changes
vim USR-001.md
# 3. Review and update affected children
vim SYS-001.md
vim SYS-002.md
# 4. Accept links after review
req accept SYS-001 USR-001
req accept SYS-002 USR-001
# Or accept all at once
req accept --all
# 5. Verify clean
req suspect
# Output: No suspect links found.
CI/CD Integration
Use in continuous integration:
#!/bin/bash
# Fail build if suspect links exist
req suspect
if [ $? -ne 0 ]; then
echo "ERROR: Requirements need review"
exit 1
fi
Or in GitHub Actions:
- name: Check for suspect links
run: |
req suspect || (echo "Requirements need review" && exit 1)
Planned Advanced Functionality
Automatic Review Triggers
When a parent requirement changes:
- Requiem detects fingerprint mismatch in child requirements
- Child requirements are flagged as "needs review"
- Team members are notified (configurable)
- Reviews are tracked until completed
Review States
Requirements will have review states:
- Current: No parent changes; requirement is up to date
- Suspect: Parent changed (fingerprint mismatch); needs review
- Under Review: Review in progress
- Reviewed: Review completed; requirement updated as needed
- Approved: Reviewed and approved; baseline updated
Commands (Planned)
# Check for requirements needing review
req check
# Mark requirement as under review
req review start SYS-001
# Complete review and update fingerprint
req review complete SYS-001
# Show review status
req status
# Generate review report
req report review
Motivation
The Problem
Scenario: A user requirement changes. Which system requirements are affected?
Current state: Manual tracking required.
Example:
- Edit USR-001: Change email validation rules
- SYS-001, SYS-002, and SYS-005 reference USR-001
- Challenge: Remember to review all three system requirements
- Risk: Forget to review one; inconsistency results
The Solution
Automatic review tracking:
- Edit USR-001
- Requiem automatically flags SYS-001, SYS-002, SYS-005 as "needs review"
- Team dashboard shows requirements pending review
- Reviews are tracked and reported
- Nothing falls through the cracks
How It Works (Current Implementation)
Step 1: Make Changes
Edit a requirement:
vim USR-001.md # Make your changes
The fingerprint of USR-001 automatically changes when content or tags change.
Step 2: Detect Suspect Links
Find affected children:
req suspect
Output:
Found 3 suspect link(s):
SYS-001 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-002 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-005 → USR-004
Stored fingerprint: 407c6e3413d5b3fa
Current fingerprint: c28afe188a974322
Step 3: Conduct Review
Review each affected requirement:
# Review parent changes
vim USR-001.md
# Review child and update if needed
vim SYS-001.md
Step 4: Accept Links
After review, accept the fingerprint change:
# Accept individual link
req accept SYS-001 USR-001
# Or accept all at once
req accept --all
Output:
Accepted 3 suspect link(s):
SYS-001 → USR-001
SYS-002 → USR-001
SYS-005 → USR-004
Step 5: Verify Clean
Confirm no suspect links remain:
req suspect
# Output: No suspect links found.
How Advanced Features Will Work (Planned)
Review State Tracking
Track review progress with states:
req review start SYS-001
# - Marks requirement as "under review"
# - Records reviewer and timestamp
req review complete SYS-001
# - Marks requirement as "reviewed"
# - Updates parent fingerprints
# - Clears review flag
Status Reports
Generate review reports:
req report review
Output:
Review Status Report (2025-07-22)
Pending Reviews:
SYS-002: parent USR-001 changed (flagged 3 days ago)
SYS-005: parent USR-001 changed (flagged 3 days ago)
Recently Reviewed:
SYS-001: reviewed by alice@example.com (2025-07-22)
All Current:
SYS-003, SYS-004, ...
Use Cases
Use Case 1: Change Impact Analysis
Scenario: Proposing a change to a critical requirement.
Question: What's the impact?
Workflow:
- Identify requirement to change (USR-001)
- Check impact:
req impact USR-001
- Output shows all descendants:
Requirements that depend on USR-001:
Direct children:
SYS-001, SYS-002, SYS-005
Indirect descendants:
SWR-001, SWR-003 (via SYS-001)
TST-001, TST-002 (via SYS-001, SYS-002)
Total affected: 7 requirements
- Decide if change is worth the review burden
Use Case 2: Release Readiness
Scenario: Preparing for a release.
Question: Are all requirements reviewed and current?
Workflow:
req status
Sample output:
Requirement Counts
==================
Kind | Count
-----------+-----
SYS | 118
TST | 24
USR | 6
-----------+-----
Total | 148
Suspect links: 3
If the command exits with code 1, use the suspect link total as your release checklist—clear
them before shipping:
req check
# Review each flagged requirement
req review complete ...
Use Case 3: Compliance Audits
Scenario: Demonstrating requirements traceability for audit.
Goal: Show that all requirements were reviewed after changes.
Workflow:
req report audit --since 2025-01-01
Output:
Audit Report: Jan 1 - Jul 22, 2025
Requirements Changed: 23
- USR-001, USR-005, SYS-003, ...
Reviews Conducted: 47
- All downstream requirements reviewed
- Average review time: 2.3 days
Compliance: ✓ PASS
- All changed requirements reviewed
- All affected descendants reviewed
Configuration (Planned)
Review Policies
# config.toml (planned)
[review]
# Automatically flag children when parent changes
auto_flag = true
# Require review completion before allowing further changes
block_on_pending_review = false
# Notification settings
notify_on_flag = true
notification_email = "team@example.com"
# Review SLA (days)
review_sla = 7
Review Rules
# config.toml (planned)
[review.rules]
# Require review for specific requirement kinds
require_review_for = ["USR", "SYS"]
# Skip review for certain kinds (e.g., documentation)
skip_review_for = ["DOC"]
# Require multiple approvers for critical requirements
require_approvals = 2 # For requirements tagged "critical"
Integration
Git Integration
Reviews tracked alongside code changes:
# Edit requirement
vim USR-001.md
# Flag affected requirements
req check
# Create PR with review tracking
git checkout -b update-usr-001
git add USR-001.md
git commit -m "Update USR-001: clarify email validation"
# PR description includes:
# - Changed requirement
# - Affected requirements
# - Review checklist
CI/CD Integration
# .github/workflows/requirements.yml (planned)
- name: Check review status
run: |
req check
if [ $? -ne 0 ]; then
echo "Requirements need review"
exit 1
fi
Issue Tracker Integration
Automatically create issues for flagged requirements:
req check --create-issues
# Creates GitHub/Jira issues for each requirement needing review
Current Workflow Examples
Example 1: Daily Review Check
Check for suspect links before starting work:
#!/bin/bash
# daily-check.sh
echo "Checking for suspect links..."
req suspect
if [ $? -eq 0 ]; then
echo "✓ All requirements current"
else
echo "⚠ Review needed - see above"
fi
Example 2: Pre-Commit Hook
Prevent commits with unreviewed changes:
#!/bin/bash
# .git/hooks/pre-commit
req suspect
if [ $? -ne 0 ]; then
echo "ERROR: Suspect links found. Run 'req suspect' to see them."
echo "Review and accept links before committing."
exit 1
fi
Example 3: Pull Request Workflow
# 1. After making changes
git add -A
git commit -m "Update USR-001 validation rules"
# 2. Check for suspect links
req suspect
# 3. Review and update affected requirements
vim SYS-001.md
vim SYS-002.md
# 4. Accept all after review
req accept --all
# 5. Commit accepted fingerprints
git add -A
git commit -m "Accept fingerprints after USR-001 changes"
# 6. Push
git push
Example 4: Bulk Review Session
Review all pending changes at once:
# List all suspect links
req suspect > review-list.txt
# Review each one
vim SYS-001.md
vim SYS-002.md
# ... review all
# Accept all at once
req accept --all
# Verify clean
req suspect
Supplementary Tracking (Optional)
While req suspect and req accept handle basic detection and acceptance, you may want additional tracking:
Git Commit Messages
Document reviews in commit messages:
git commit -m "Review SYS-001 after USR-001 change
USR-001 updated email validation rules.
Reviewed SYS-001 and verified consistency.
No changes needed to SYS-001.
Accepted fingerprint: c4020419ead000e9"
Issue Tracking
Create issues for complex reviews:
## Review affected requirements after USR-001 change
- [x] SYS-001: Reviewed, no changes needed
- [x] SYS-002: Updated validation logic
- [ ] SYS-005: Waiting for clarification
Tags in Frontmatter
Track review priority with tags:
# SYS-001.md
tags:
- high-priority
- security-critical
Future Enhancements
Beyond basic review workflows:
Advanced Features
Review assignments:
req review assign SYS-001 --to alice@example.com
Review templates:
req review start SYS-001 --template checklist.md
# Provides structured review checklist
Review history:
req history SYS-001
# Shows all reviews and changes over time
Bulk operations:
req review complete SYS-001 SYS-002 SYS-003
# Complete multiple reviews at once
Integrations
Slack/Teams notifications:
@alice Your review is needed: SYS-001 (parent changed)
Dashboard UI: Web dashboard showing review status, pending items, team metrics.
Approval workflows: Multi-step approval for critical requirements.
Implementation Status
Current status: Partially implemented
Available now:
- ✅
req suspect- Detect fingerprint mismatches - ✅
req accept <CHILD> <PARENT>- Accept individual suspect links - ✅
req accept --all- Accept all suspect links - ✅ CI/CD integration via exit codes
Planned for future releases:
- ⏳ Review state tracking (under review, reviewed, approved)
- ⏳ Review assignments and notifications
- ⏳ Status reports and dashboards
- ⏳ Review history and audit logs
- ⏳ Multi-approver workflows
See GitHub repository for updates.
Contributing
Interested in helping implement advanced review workflow features? See the project repository for contribution guidelines.
Summary
Implemented features:
- Automatic suspect link detection (
req suspect) - Accepting suspect links after review (
req accept) - CI/CD integration with proper exit codes
- Batch operations (
req accept --all)
Use these commands now:
req suspect # List suspect links
req accept SYS-001 USR-001 # Accept single link
req accept --all # Accept all suspect links
Planned advanced features:
- Review state tracking (suspect → under review → reviewed → approved)
- Commands:
req review start/complete,req status,req report - Review assignments and team workflows
- Notifications and integrations
- Comprehensive audit reports
Current best practices:
- Use
req suspectregularly to check for changes - Review requirements manually before accepting
- Use
req acceptto update fingerprints after review - Integrate into CI/CD pipelines for automated checks
- Document reviews in git commit messages
Next Steps
- Use Fingerprints for manual change detection
- Implement workarounds for your workflow
- Watch GitHub repository for implementation updates
Integration
Requiem integrates with existing tools in your development workflow. This chapter covers integration strategies and best practices.
Overview
Requiem's plain-text format enables integration with:
- MdBook - Embed requirements in MdBook documentation
- Sphinx - Include requirements in Sphinx-generated docs
- Version Control - Git workflows and best practices
Philosophy: Compose, Don't Replace
Requiem doesn't aim to replace your existing documentation or development tools. Instead, it composes with them:
Documentation Tools
Requirements live alongside your documentation:
docs/
├── user-guide.md
├── architecture.md
├── requirements/
│ ├── USR-001.md ← Requirements
│ └── SYS-001.md
└── api-reference.md
Documentation can reference or embed requirements directly.
Version Control
Requirements are plain text files that work naturally with Git:
- Meaningful diffs
- Branch and merge workflows
- Pull request reviews
- Complete history
Static Site Generators
MdBook and Sphinx can include requirement files in generated documentation:
# User Guide
## Requirements
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001 Plain Text Storage
## Statement
The tool shall store requirements as plain-text files that can be read and edited with any text editor.
## Rationale
Plain text storage enables:
- Version control integration with Git and other VCS tools
- Human review without specialized software
- Long-term archival and accessibility
- Integration with existing text-based workflows
## Acceptance Criteria
- Requirements are stored as `.md` (Markdown) files
- Files can be opened and edited in any text editor
- No proprietary or binary formats are required
- Files are compatible with standard version control systems
Requirements stay synchronized with documentation automatically.
CI/CD Pipelines
Validate requirements in continuous integration:
- name: Validate requirements
run: req clean
Catch errors before merging.
Custom Tools
Plain text enables custom tooling:
# Custom analysis script
import glob
for req_file in glob.glob("USR-*.md"):
# Parse, analyze, generate reports, etc.
Integration Patterns
Pattern 1: Standalone Requirements
Requirements in dedicated directory:
project/
├── src/ ← Source code
├── requirements/ ← Requirements (separate)
│ ├── config.toml
│ └── USR-001.md
└── docs/ ← Documentation (separate)
Best for: Clear separation of concerns, formal requirements management.
Pattern 2: Requirements with Documentation
Requirements embedded in documentation:
docs/
├── config.toml
├── user-guide.md
├── USR-001.md ← Mixed with docs
├── architecture.md
└── SYS-001.md ← Mixed with docs
Configuration: allow_unrecognised = true (to ignore non-requirement markdown files).
Best for: Integrated documentation, technical specifications.
Pattern 3: Monorepo with Multiple Projects
Each project has its own requirements:
monorepo/
├── project-a/
│ └── requirements/
│ └── USR-001.md
├── project-b/
│ └── requirements/
│ └── USR-001.md
└── shared/
└── requirements/
└── CORE-USR-001.md
Best for: Multi-project organizations, shared requirements.
Integration Benefits
Single Source of Truth
Requirements are defined once, referenced everywhere:
- User documentation includes requirement text
- Design docs reference requirements
- Test plans trace to requirements
- Code comments link to requirements
Changes propagate automatically (when using includes/references).
Automated Consistency
CI/CD ensures requirements remain valid:
# .github/workflows/requirements.yml
- run: req clean
Prevents broken traceability or invalid formatting.
Developer-Friendly
Plain text means developers can:
- Use their preferred editor
- Search with grep/ripgrep
- Script with Python/Bash
- Review in pull requests
No context switching to specialized tools.
Audit Trail
Git provides complete history:
# See all changes to a requirement
git log -p USR-001.md
# See who last modified
git blame USR-001.md
# See what changed in a sprint
git log --since="2 weeks ago" -- requirements/
Next Steps
Explore specific integrations:
- Using with MdBook - Embed requirements in MdBook sites
- Using with Sphinx - Include requirements in Sphinx documentation
- Version Control Best Practices - Git workflows for requirements
Using with MdBook
MdBook is a popular tool for creating documentation from Markdown files. Requiem integrates seamlessly with MdBook, allowing requirements to live alongside documentation.
Overview
Requiem requirements are Markdown files, making them naturally compatible with MdBook. You can:
- Include requirements in your MdBook table of contents
- Embed requirements in documentation chapters
- Mix requirements with narrative documentation
- Generate complete documentation sites with embedded requirements
Basic Setup
Project Structure
my-book/
├── book.toml ← MdBook configuration
└── src/
├── SUMMARY.md ← Table of contents
├── config.toml ← Requiem configuration
├── chapter1.md ← Documentation
├── USR-001.md ← Requirement
└── USR-002.md ← Requirement
Requiem Configuration
Since the src/ directory contains both requirements and documentation, configure Requiem to allow non-requirement files:
src/config.toml:
_version = "1"
allow_unrecognised = true # Important: allows chapter1.md, SUMMARY.md, etc.
MdBook Configuration
book.toml:
[book]
title = "My Project Documentation"
authors = ["Your Name"]
language = "en"
src = "src"
[build]
build-dir = "book"
No special MdBook configuration needed for Requiem requirements!
Including Requirements in Table of Contents
Requirements can be listed in SUMMARY.md like any other chapter:
src/SUMMARY.md:
# Summary
[Introduction](./introduction.md)
# Requirements
- [User Requirements](./user-requirements.md)
- [USR-001: User Authentication](./USR-001.md)
- [USR-002: Data Export](./USR-002.md)
- [USR-003: Email Validation](./USR-003.md)
- [System Requirements](./system-requirements.md)
- [SYS-001: Authentication Service](./SYS-001.md)
- [SYS-002: Export API](./SYS-002.md)
# User Guide
- [Getting Started](./getting-started.md)
- [Features](./features.md)
Requirements appear as chapters in the generated book. The HRID in the first heading (e.g., # USR-001 User Authentication) becomes the page title automatically.
Embedding Requirements
Use MdBook's include feature to embed requirements in documentation chapters:
src/user-guide.md:
# User Guide
## Authentication
Our authentication system satisfies the following requirement:
{{#include USR-001.md}}
To log in, navigate to...
When MdBook builds, USR-001.md content is embedded directly.
Selective Inclusion
Include only the requirement body (skip frontmatter but keep the heading):
{{#include USR-001.md:6:}}
This skips the YAML frontmatter and includes the heading and body.
Line counting:
--- ← Line 1
_version: '1'
uuid: ...
created: ...
--- ← Line 5
# USR-001 Title ← Line 6 (keep this!)
Requirement text... ← Line 7 onwards
Adjust the line number based on your frontmatter length. The heading with the HRID should typically be kept as it provides context.
Formatting Requirements
Display Frontmatter
To show frontmatter in documentation:
src/requirements-format.md:
# Requirement Format
Requirements include metadata in YAML frontmatter:
{{#include USR-001.md}}
MdBook renders the entire file, including frontmatter as a code block.
Hide Frontmatter
To show only the requirement text:
Option 1: Use line ranges
{{#include USR-001.md:7:}}
Option 2: Create requirement summary files
src/usr-001-summary.md:
<!-- Manually maintained summary without frontmatter -->
The system shall validate user email addresses according to RFC 5322.
Then include the summary file in documentation.
Custom Formatting with Preprocessors
For advanced formatting (e.g., extracting specific fields), use MdBook preprocessors:
- mdbook-linkcheck - Validate links
- mdbook-toc - Generate table of contents
- Custom preprocessor - Extract HRID, UUID, parent links from frontmatter
Working Example
See the complete example in the Requiem repository:
git clone https://github.com/danieleades/requirements-manager
cd requirements-manager/examples/mdbook
Example Structure
examples/mdbook/
├── book.toml
├── src/
│ ├── SUMMARY.md
│ ├── chapter_1.md
│ ├── USR-001.md
│ └── USR-002.md
└── README.md
Build the Example
- Install MdBook:
cargo install mdbook
- Build the book:
mdbook build
- View output:
mdbook serve --open
Your browser opens showing the documentation with requirements included.
Best Practices
1. Organize by Type
Group requirements in SUMMARY.md:
# Summary
# User Requirements
- [USR-001](./USR-001.md)
- [USR-002](./USR-002.md)
# System Requirements
- [SYS-001](./SYS-001.md)
- [SYS-002](./SYS-002.md)
2. Use Subdirectories
For large projects, organize requirements in subdirectories:
src/
├── SUMMARY.md
├── requirements/
│ ├── user/
│ │ ├── USR-001.md
│ │ └── USR-002.md
│ └── system/
│ ├── SYS-001.md
│ └── SYS-002.md
└── guides/
└── user-guide.md
SUMMARY.md:
# Summary
# Requirements
- [User Requirements](./requirements/user/USR-001.md)
- [System Requirements](./requirements/system/SYS-001.md)
3. Link Requirements
Link between requirements using standard Markdown links:
USR-001.md:
This requirement is implemented by [SYS-001](./SYS-001.md).
MdBook generates clickable links in the output.
4. Embed in Context
Embed requirements in relevant documentation sections:
user-guide.md:
# User Guide
## Email Validation
{{#include requirements/USR-003.md:7:}}
To validate emails, the system checks...
Keeps requirements and documentation synchronized.
5. Separate Config
Use separate config.toml for Requiem:
src/
├── config.toml ← Requiem config (allow_unrecognised = true)
├── book.toml ← Don't confuse with MdBook config
└── ...
Note: MdBook's config is book.toml in the root, not in src/.
Limitations
Frontmatter Rendering
MdBook doesn't parse YAML frontmatter specially. It renders as:
---
_version: '1'
uuid: 4bfeb7d5-...
created: 2025-07-22T12:19:56.950194157Z
---
Requirement text...
The frontmatter appears as a code block (triple-dash markers).
Workaround: Use line ranges to skip frontmatter (see Formatting Requirements).
No Dynamic Traceability
MdBook doesn't generate traceability matrices or parent-child diagrams automatically.
Workaround: Generate diagrams with external tools and include as images:
# Traceability

No HRID Validation
MdBook doesn't validate requirement references.
Workaround: Use CI to validate:
# .github/workflows/docs.yml
- name: Validate requirements
run: req clean
working-directory: ./src
- name: Build documentation
run: mdbook build
Advanced Techniques
Generating Traceability Pages
Use scripts to generate traceability documentation:
generate-traceability.sh:
#!/bin/bash
# Generate a markdown page showing parent-child relationships
echo "# Requirement Traceability" > traceability.md
echo "" >> traceability.md
for req in USR-*.md; do
hrid=$(basename "$req" .md)
echo "## $hrid" >> traceability.md
# Extract and format parent links
# ...
done
Run before MdBook build:
./generate-traceability.sh
mdbook build
Custom MdBook Preprocessor
Create a preprocessor to enhance requirement rendering:
Rust preprocessor example:
#![allow(unused)] fn main() { // Extract HRID and UUID from frontmatter // Add custom formatting // Generate cross-reference links }
See MdBook documentation for details.
GitHub Pages Deployment
Host your requirements documentation:
# .github/workflows/deploy.yml
name: Deploy Documentation
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install MdBook
run: cargo install mdbook
- name: Build book
run: mdbook build
working-directory: ./docs
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/book
Example Documentation Structure
Comprehensive documentation with requirements:
docs/
├── book.toml
└── src/
├── SUMMARY.md
├── config.toml ← Requiem config
│
├── introduction.md ← Narrative docs
├── architecture.md
├── getting-started.md
│
├── requirements/ ← Requirements
│ ├── user/
│ │ ├── USR-001.md
│ │ └── USR-002.md
│ ├── system/
│ │ ├── SYS-001.md
│ │ └── SYS-002.md
│ └── traceability.md ← Generated
│
└── user-guide/ ← User guides
├── authentication.md ← Embeds USR-001, SYS-001
└── export.md ← Embeds USR-002, SYS-002
Troubleshooting
Requirements Not Appearing in Book
Problem: Requirements listed in SUMMARY.md don't appear.
Diagnosis:
- Check file paths in
SUMMARY.mdare correct - Ensure files exist at specified paths
- Run
mdbook build -vfor verbose output
Solution: Verify paths match file structure exactly.
Frontmatter Renders as Code Block
Problem: YAML frontmatter shows as markdown code block.
Explanation: Expected behavior. MdBook doesn't parse YAML frontmatter.
Solution: Use line ranges to skip frontmatter (see Selective Inclusion).
Requiem Validation Fails
Problem: req clean reports errors about non-requirement files.
Solution: Set allow_unrecognised = true in config.toml:
_version = "1"
allow_unrecognised = true
Includes Don't Work
Problem: {{#include USR-001.md}} doesn't embed content.
Diagnosis:
- Check file path is correct relative to including file
- Check MdBook version (includes supported in 0.3.0+)
Solution: Use correct relative paths:
{{#include ./USR-001.md}} # If in same directory
{{#include ../requirements/USR-001.md}} # If in subdirectory
Summary
Key Points:
- Requiem requirements are compatible with MdBook out of the box
- Set
allow_unrecognised = truein Requiem config when mixing with docs - Include requirements in
SUMMARY.mdor embed with{{#include}} - Use line ranges to skip frontmatter if desired
- Combine requirements with narrative documentation for comprehensive docs
Benefits:
- Single source of truth
- Requirements stay synchronized with docs
- Easy navigation and search
- Professional-looking documentation
Limitations:
- Frontmatter renders as code block
- No automatic traceability diagrams
- No HRID validation (use external tools)
Next Steps
- See Using with Sphinx for Python documentation
- Review Version Control Best Practices for managing requirements in Git
Using with Sphinx
Sphinx is a powerful documentation generator widely used in Python projects. Requiem requirements integrate seamlessly with Sphinx using the MyST Parser extension.
Overview
Sphinx traditionally uses reStructuredText (RST), but with the MyST Parser extension, Sphinx can process Markdown files including Requiem requirements.
Key compatibility features:
- MyST Parser treats YAML frontmatter as page metadata (doesn't render it)
- HRIDs in headings (e.g.,
# USR-001 Title) work naturally as page titles - Requirements can be included in toctrees or embedded in documentation
Setup
Prerequisites
- Python 3.7 or later
- Sphinx
- MyST Parser extension
Installation
Using pip:
pip install sphinx myst-parser
Using uv (recommended):
uv pip install sphinx myst-parser
Project Structure
docs/
├── conf.py ← Sphinx configuration
├── index.md ← Main documentation
├── requirements/ ← Requirements directory
│ ├── config.toml ← Requiem configuration
│ ├── USR-001.md
│ ├── USR-002.md
│ ├── SYS-001.md
│ └── SYS-002.md
└── guides/
└── user-guide.md
Sphinx Configuration
Configure Sphinx to use MyST Parser for Markdown:
conf.py:
project = 'My Project'
copyright = '2025, Your Name'
author = 'Your Name'
# Add MyST Parser extension
extensions = ["myst_parser"]
# Exclude non-documentation files
exclude_patterns = [
'_build',
'Thumbs.db',
'.DS_Store',
'requirements/config.toml', # Exclude Requiem config
]
html_theme = 'alabaster' # Or your preferred theme
Requiem Configuration
Since requirements live in a subdirectory with other Sphinx content, configure Requiem appropriately:
requirements/config.toml:
_version = "1"
# Strict mode OK here since requirements are in dedicated directory
allow_unrecognised = false
Including Requirements
Option 1: Direct Inclusion via Table of Contents
Create a toctree including requirement files:
index.md:
# Project Documentation
## Contents
\```{toctree}
:maxdepth: 2
guides/user-guide
requirements/USR-001
requirements/USR-002
requirements/SYS-001
\```
Requirements appear as pages in generated documentation with the HRID-containing heading as the page title.
Option 2: Include Directive
Use the MyST {include} directive to embed requirements:
guides/user-guide.md:
# User Guide
## Authentication
Our authentication system satisfies this requirement:
\```{include} ../requirements/USR-001.md
\```
The entire requirement (excluding frontmatter) is embedded in the guide.
Option 3: Literalinclude for Examples
To show requirements as code examples:
requirements-format.md:
# Requirement Format
Requirements are Markdown files with YAML frontmatter:
\```{literalinclude} requirements/USR-001.md
:language: markdown
\```
HRID in Headings
Requiem stores HRIDs in the first markdown heading (e.g., # USR-001 Title) rather than in YAML frontmatter.
Benefits for Sphinx
- The first heading becomes the natural page title
- Sphinx uses the heading text for navigation and cross-references
- The HRID is visible in the rendered documentation
- No special processing needed to extract the HRID
Example
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
---
# USR-001 Plain Text Storage
Requirements are stored as plain-text files...
Sphinx renders this with "USR-001 Plain Text Storage" as the page title. The YAML frontmatter is treated as page metadata and doesn't appear in the rendered output.
Working Example
The Requiem repository includes a complete Sphinx example:
git clone https://github.com/danieleades/requirements-manager
cd requirements-manager/examples/sphinx
Build the Example
- Install dependencies:
uv pip install -r requirements.txt
Or with pip:
pip install sphinx myst-parser
- Build documentation:
make html
- View output:
# Open _build/html/index.html in your browser
Best Practices
1. Dedicated Requirements Directory
Keep requirements in a separate directory:
docs/
├── conf.py
├── requirements/ ← Requirements
│ ├── config.toml
│ └── *.md
└── guides/ ← Other docs
└── *.md
Benefits:
- Clear separation between requirements and narrative docs
- Easier Requiem configuration
- Simpler to manage
2. Create Requirement Indexes
Generate index pages for requirement types:
requirements/user-requirements.md:
# User Requirements
\```{toctree}
:maxdepth: 1
USR-001
USR-002
USR-003
\```
3. Cross-Reference with Sphinx Roles
Use Sphinx's cross-referencing:
guides/user-guide.md:
See {doc}`requirements/USR-001` for authentication requirements.
Sphinx generates proper links automatically.
4. Organize by Type
Structure your toctree to group requirements:
\```{toctree}
:maxdepth: 2
User Requirements <requirements/user-requirements>
System Requirements <requirements/system-requirements>
Specifications <requirements/specifications>
\```
Troubleshooting
MyST Parser Not Found
Error: Extension error: Could not import extension myst_parser
Solution: Install MyST Parser:
pip install myst-parser
Markdown Files Not Processed
Problem: Markdown files don't appear in generated docs.
Solution: Ensure MyST Parser is in extensions list in conf.py:
extensions = ["myst_parser"]
Include Directive Not Working
Problem: {include} directive doesn't embed content.
Solution: Check file path is correct relative to the source file:
\```{include} ../requirements/USR-001.md
\```
Requirements Not in Table of Contents
Problem: Requirements don't appear in navigation.
Solution: Add requirements to a toctree directive in your index or section files.
Summary
Key Points:
- Use MyST Parser extension for Markdown support
- MyST treats YAML frontmatter as metadata (doesn't render it)
- HRIDs in headings work naturally as page titles
- Include requirements via toctree or include directives
- Keep requirements in dedicated directory
Benefits:
- Seamless integration with Python documentation
- Requirements alongside API docs and guides
- Professional HTML output with themes
- Cross-referencing and search
Limitations:
- Requires MyST Parser (additional dependency)
- Less "native" than MdBook (Sphinx primarily RST-focused)
Next Steps
- Review the Sphinx example in the repository
- Compare with Using with MdBook for Rust projects
- See Version Control Best Practices for managing requirements
Version Control Best Practices
Requiem's plain-text format makes requirements ideal for version control. This chapter covers Git workflows and best practices.
Why Version Control Matters
Requirements benefit from version control:
- Complete history: Track all changes over time
- Audit trail: Know who changed what and when
- Branching: Develop requirements in parallel
- Review: Use pull requests for requirement reviews
- Rollback: Revert problematic changes
- Tagging: Mark requirement baselines (releases)
Git Basics for Requirements
Initial Setup
Create a Git repository for your requirements:
mkdir my-requirements
cd my-requirements
git init
# Create first requirement
req add USR
git add config.toml USR-001.md
git commit -m "Initial commit: add USR-001"
Adding Requirements
When creating requirements:
# Create requirement
req add USR
# Stage and commit
git add USR-002.md
git commit -m "Add USR-002: user data export requirement"
Editing Requirements
When modifying requirements:
# Edit requirement
vim USR-001.md
# Review changes
git diff USR-001.md
# Stage and commit
git add USR-001.md
git commit -m "Update USR-001: clarify email validation format"
Linking Requirements
When linking requirements:
# Create link
req link SYS-001 USR-001
# Both files change (child gets parent reference)
git diff
# Commit both
git add SYS-001.md
git commit -m "Link SYS-001 to USR-001"
Commit Message Best Practices
Format
Use clear, descriptive commit messages:
Bad:
git commit -m "update"
git commit -m "fix typo"
git commit -m "changes"
Good:
git commit -m "Add USR-042: user data export requirement"
git commit -m "Update USR-001: change email validation to RFC 5322"
git commit -m "Link SYS-001 to USR-001 and USR-002"
Structure
Use conventional commit format:
<type>: <HRID>: <description>
[optional body]
[optional footer]
Types:
add: New requirementupdate: Modify existing requirementlink: Create requirement linkremove: Delete requirementrefactor: Reorganize without changing contentdocs: Update documentation (non-requirement changes)
Examples:
# Add new requirement
git commit -m "add: USR-042: user data export"
# Update existing
git commit -m "update: USR-001: clarify email validation
Changed from 'valid email' to 'RFC 5322 compliant'
to remove ambiguity."
# Link requirements
git commit -m "link: SYS-001 -> USR-001, USR-002
SYS-001 satisfies both user requirements for authentication."
# Bulk operation
git commit -m "refactor: reorganize requirements into subdirectories
- Move USR-*.md to user/
- Move SYS-*.md to system/
- Update config.toml"
Branching Strategies
Feature Branches
Develop requirements for new features in branches:
# Create feature branch
git checkout -b feature/payment-system
# Add requirements
req add USR # USR-042
req add SYS # SYS-012
# Edit and link requirements
# Commit changes
git add .
git commit -m "add: payment system requirements (USR-042, SYS-012)"
# Push for review
git push origin feature/payment-system
Requirement Change Branches
For significant requirement changes:
# Create change branch
git checkout -b change/update-usr-001
# Edit requirement
vim USR-001.md
# Update dependent requirements
req clean
# Commit
git add .
git commit -m "update: USR-001: clarify email validation
Updated email validation to reference RFC 5322.
Corrected parent HRIDs in dependent requirements."
# Create pull request
gh pr create
Release Branches
Stabilize requirements for releases:
# Create release branch
git checkout -b release/v1.0
# Freeze requirements (no new additions)
# Allow only bug fixes and clarifications
# Tag when stable
git tag v1.0.0
git push origin v1.0.0
Pull Request Workflows
Creating Pull Requests
When changing requirements:
- Create branch:
git checkout -b update-auth-requirements
- Make changes:
vim USR-001.md
req clean
- Commit:
git add -A
git commit -m "update: USR-001: strengthen password requirements"
- Push and create PR:
git push origin update-auth-requirements
gh pr create --title "Update authentication requirements" \
--body "Strengthens password requirements to meet new security policy"
PR Description Template
Use a template for requirement PRs:
## Summary
Adds/updates/removes requirements for [feature/change].
## Changed Requirements
- USR-001: [description of change]
- SYS-005: [description of change]
## Impact Analysis
- Affects: SYS-001, SYS-003, TST-001
- Reviewed: ✓ All dependent requirements checked
## Checklist
- [x] `req clean` passes
- [x] Commit messages follow convention
- [x] Dependent requirements reviewed
- [x] Tests updated (if applicable)
- [ ] Approved by: @stakeholder
Reviewing Pull Requests
When reviewing requirement PRs:
- Check diffs carefully:
# Review line-by-line changes
gh pr diff 123
- Verify UUIDs unchanged:
# Ensure UUIDs haven't been modified
git diff main..HEAD -- '*.md' | grep 'uuid:'
- Check req clean passes:
# Validate requirements
req clean
- Review dependent requirements:
# Find affected requirements
grep -r "uuid: <changed-req-uuid>" *.md
- Approve and merge:
gh pr review 123 --approve
gh pr merge 123
Handling Conflicts
Merge Conflicts in Requirements
Conflicts occur when two branches modify the same requirement.
Example conflict:
<<<<<<< HEAD
The system shall validate emails using RFC 5321.
=======
The system shall validate emails using RFC 5322.
>>>>>>> feature/update-email-validation
Resolution:
-
Understand both changes: Read both versions.
-
Choose or combine: Decide which is correct or merge both:
The system shall validate emails using RFC 5322.
- Mark resolved:
git add USR-001.md
git commit
Frontmatter Conflicts
UUID conflicts (should never happen):
<<<<<<< HEAD
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
=======
uuid: 00000000-0000-0000-0000-000000000000
>>>>>>> other-branch
Resolution: Keep the original UUID (HEAD). Changing UUIDs breaks traceability.
Parent conflicts (both branches added parents):
<<<<<<< HEAD
parents:
- uuid: aaaa...
hrid: USR-001
=======
parents:
- uuid: bbbb...
hrid: USR-002
>>>>>>> other-branch
Resolution: Merge both parents:
parents:
- uuid: aaaa...
hrid: USR-001
- uuid: bbbb...
hrid: USR-002
Then run:
req clean # Validate merged result
Tagging and Releases
Creating Baseline Tags
Tag stable requirement sets:
# Tag current state
git tag -a v1.0.0 -m "Release 1.0.0 requirements baseline"
git push origin v1.0.0
Naming Conventions
Use semantic versioning:
v1.0.0- Major releasev1.1.0- Minor release (new requirements)v1.0.1- Patch release (clarifications, typo fixes)
Or use date-based tags:
baseline-2025-07-22release-2025-q3
Comparing Baselines
Compare requirement changes between releases:
# List changed requirements
git diff v1.0.0..v2.0.0 --name-only -- '*.md'
# Show detailed changes
git diff v1.0.0..v2.0.0 -- USR-001.md
# Generate changelog
git log v1.0.0..v2.0.0 --oneline -- '*.md'
Advanced Git Techniques
Git Blame for Requirements
See who last modified each line:
git blame USR-001.md
Output:
4bfeb7d5 (Alice 2025-07-20) The system shall validate
a1b2c3d4 (Bob 2025-07-22) user email addresses according
e5f6g7h8 (Alice 2025-07-23) to RFC 5322.
Git Log for Requirement History
View complete history:
# All commits affecting USR-001
git log -p USR-001.md
# One-line summary
git log --oneline USR-001.md
# Show who, when, what
git log --format="%h %an %ad %s" --date=short -- USR-001.md
Git Diff for Requirement Changes
Compare versions:
# Current vs. last commit
git diff HEAD~1 USR-001.md
# Current vs. specific commit
git diff a1b2c3d4 USR-001.md
# Between branches
git diff main..feature/update USR-001.md
# Ignore whitespace
git diff -w USR-001.md
Bisect to Find Breaking Changes
Find when a requirement changed incorrectly:
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# Git checks out middle commit
req clean # Test if requirements are valid
git bisect good # or 'bad'
# Repeat until found
git bisect reset
Ignoring Files
.gitignore for Requirements Projects
Exclude generated or temporary files:
.gitignore:
# Requiem temp files
*.tmp
# Editor files
*.swp
*.swo
*~
.vscode/
.idea/
# OS files
.DS_Store
Thumbs.db
# Build outputs (if using MdBook/Sphinx)
book/
_build/
_generated/
# Python
__pycache__/
*.pyc
.venv/
Don't ignore:
config.toml(Requiem configuration)*.md(requirements)
CI/CD Integration
GitHub Actions
Validate requirements automatically:
.github/workflows/requirements.yml:
name: Requirements Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Requiem
run: cargo install requirements-manager
- name: Validate requirements
run: req clean
working-directory: ./requirements
- name: Check for uncommitted changes
run: |
if [ -n "$(git status --porcelain)" ]; then
echo "Error: req clean modified files. Run req clean locally."
git diff
exit 1
fi
Pre-commit Hook
Validate before every commit:
.git/hooks/pre-commit:
#!/bin/bash
echo "Validating requirements..."
req clean
if [ $? -ne 0 ]; then
echo "Error: Requirements validation failed"
exit 1
fi
# Stage any changes made by req clean
git add -u
exit 0
Make executable:
chmod +x .git/hooks/pre-commit
Collaboration Best Practices
1. Clear Ownership
Define requirement ownership:
# CODEOWNERS
# Assign reviewers for requirement changes
requirements/USR-*.md @product-team
requirements/SYS-*.md @architecture-team
requirements/TST-*.md @qa-team
2. Require Reviews
Enforce PR reviews:
GitHub branch protection:
- Require pull request reviews before merging
- Require status checks (req clean) to pass
- Require up-to-date branches
3. Communication
Use commit messages and PR descriptions to communicate:
- Why the change was made
- What requirements are affected
- Who should review
4. Regular Syncs
Prevent divergence:
# Update from main frequently
git checkout feature/my-branch
git pull origin main
git merge main
# Resolve conflicts if any
req clean
5. Atomic Commits
One logical change per commit:
Bad:
# Single commit with unrelated changes
git commit -m "Add USR-042, update USR-001, fix typo in SYS-003"
Good:
# Separate commits
git commit -m "add: USR-042: user data export"
git commit -m "update: USR-001: clarify email validation"
git commit -m "fix: SYS-003: correct typo in authentication flow"
Troubleshooting
Large Diffs
Problem: Git diffs for requirement files are hard to read.
Solution: Use word-level diffs:
git diff --word-diff USR-001.md
Or color-words:
git diff --color-words USR-001.md
Accidental UUID Changes
Problem: Someone accidentally changed a UUID.
Detection:
# Find UUID changes
git log -p --all -S'uuid:' -- USR-001.md
Recovery:
# Restore correct UUID from history
git show a1b2c3d4:USR-001.md | grep 'uuid:'
# Manually fix or revert
Lost Requirements
Problem: Requirement file was deleted.
Recovery:
# Find when it was deleted
git log --all --full-history -- USR-099.md
# Restore from last good commit
git checkout a1b2c3d4 -- USR-099.md
Summary
Key Practices:
- Commit frequently with clear messages
- Use branches for features and changes
- Create PRs for reviews
- Validate with
req cleanbefore committing - Tag releases for baselines
- Review carefully to catch UUID changes
- Resolve conflicts thoughtfully (never change UUIDs)
- Use CI/CD for automated validation
Benefits:
- Complete audit trail
- Easy collaboration
- Reversible changes
- Formal review process
- Baseline management
Common Pitfalls:
- Changing UUIDs (breaks traceability)
- Poor commit messages (lost context)
- Ignoring conflicts (inconsistent requirements)
- Skipping validation (invalid requirements reach main)
Next Steps
- Set up CI/CD validation for your requirements
- Create commit message templates
- Configure branch protection
- Review Advanced Topics for more techniques
Advanced Topics
This chapter covers advanced features and techniques for requirements management with Requiem.
Overview
Advanced topics include:
- Coverage Reports - Traceability coverage analysis (planned)
- Cycle Detection - Finding circular dependencies (planned)
- Import and Export - Interoperability with other tools (planned)
Current Capabilities
Requiem currently provides core functionality:
- Plain-text requirements in Markdown
- Human-readable IDs with namespace support
- Parent-child relationships with multiple parents
- Content fingerprinting for change detection
- Fast parallel loading
- Integration with MdBook and Sphinx
Planned Capabilities
Future releases will add:
- Coverage reports: Analyze requirement traceability
- Cycle detection: Find and report circular dependencies
- Review workflows: Automated review triggering
- Import/export: ReqIF, JSON, CSV formats
- Validation rules: Custom requirement quality checks
- Query language: Advanced filtering and searching
Contributing
These features are planned but not yet implemented. Interested in contributing? See the GitHub repository for:
- Feature roadmap
- Open issues
- Contribution guidelines
- Development setup
Workarounds
Until advanced features are implemented, consider these approaches:
Manual Coverage Analysis
Use scripts to analyze traceability:
#!/bin/bash
# Find USR requirements without SYS children
comm -23 \
<(ls USR-*.md | sed 's/.md//' | sort) \
<(grep -oh "USR-[0-9]*" SYS-*.md | sort -u)
Manual Cycle Detection
Trace requirement chains manually:
# Follow parent chain
grep "uuid:" USR-001.md # Get UUID
grep "<uuid>" *.md # Find children
# Repeat for each child
Export with Scripts
Generate reports in various formats:
import glob
import yaml
import re
import json
requirements = []
for path in glob.glob("*.md"):
with open(path) as f:
content = f.read()
# Parse frontmatter and body
# Add to requirements list
# Export as JSON
with open("requirements.json", "w") as f:
json.dump(requirements, f, indent=2)
Next Steps
Explore planned features:
- Coverage Reports - What coverage analysis will provide
- Cycle Detection - How cycle detection will work
- Import and Export - Planned interoperability formats
Coverage Reports
Note: Coverage reporting is planned but not yet implemented. This chapter describes how the feature will work when available.
Coverage reports analyze requirement traceability, identifying gaps in the requirement hierarchy and ensuring all requirements are properly traced.
What is Coverage?
Coverage measures how completely requirements are traced across levels:
- Downstream coverage: Do all user requirements have system requirements?
- Upstream coverage: Do all test cases trace to requirements?
- Bidirectional traceability: Can you trace from user needs to implementation and tests?
Example
USR-001 ← User requirement
├─ SYS-001 ← System requirement (traced)
└─ SYS-002 ← System requirement (traced)
USR-002 ← User requirement
└─ (no children) ← Coverage gap!
SYS-003 ← System requirement
└─ (no parents) ← Orphan requirement!
Coverage report identifies:
- USR-002 has no system requirements (gap)
- SYS-003 has no parent (orphan)
Planned Functionality
Coverage Analysis Command
req coverage
Output:
Coverage Report
User Requirements (USR):
Total: 25
With children: 23 (92%)
Without children: 2 (8%)
- USR-002: User data export
- USR-018: Password recovery
System Requirements (SYS):
Total: 47
With parents: 45 (96%)
With children: 43 (91%)
Orphans: 2 (4%)
- SYS-003: Logging service
- SYS-029: Cache invalidation
Test Cases (TST):
Total: 156
With parents: 150 (96%)
Orphans: 6 (4%)
Overall Coverage: 93%
Coverage by Kind
Analyze specific requirement kinds:
req coverage --kind USR
Output:
User Requirement Coverage
Total: 25
With children: 23 (92%)
USR-001 → SYS-001, SYS-002
USR-003 → SYS-005, SYS-006, SYS-007
...
Without children (gaps): 2 (8%)
USR-002: User data export
USR-018: Password recovery
Recommendation: Add system requirements for USR-002 and USR-018
Detailed Reports
Generate detailed coverage information:
req coverage --detailed > coverage-report.md
Output format (Markdown):
# Coverage Report
## Summary
- User Requirements: 92% covered
- System Requirements: 96% traced upstream, 91% traced downstream
- Tests: 96% traced
## Gaps
### User Requirements Without Children
- **USR-002**: User data export
- Status: No system requirements
- Action: Create SYS requirements
- **USR-018**: Password recovery
- Status: No system requirements
- Action: Create SYS requirements
### Orphan System Requirements
- **SYS-003**: Logging service
- Status: No parent requirement
- Action: Link to USR requirement or remove
...
Visual Reports
Generate coverage diagrams:
req coverage --format html > coverage.html
Features:
- Interactive traceability matrix
- Heatmap showing coverage density
- Clickable requirement links
- Filterable by kind, tag, or namespace
Use Cases
Use Case 1: Requirement Review
Scenario: Preparing for a requirements review.
Goal: Identify incomplete traceability.
Workflow:
# Generate coverage report
req coverage --detailed > review-report.md
# Review gaps
# - USR-002: No system requirements
# - SYS-003: Orphan requirement
# Fix gaps
req add SYS --parent USR-002 # Add missing SYS requirement
req link SYS-003 USR-007 # Link orphan to parent
# Verify
req coverage
# Coverage improved to 100%
Use Case 2: Release Readiness
Scenario: Ensuring all requirements are traced before release.
Goal: 100% coverage required for release.
Workflow:
# Check coverage
req coverage --minimum 100
# Output (if < 100%):
# Error: Coverage is 93%, minimum required is 100%
# Gaps:
# - USR-002: No children
# - USR-018: No children
# - SYS-003: No parent
# Fix gaps...
# Verify
req coverage --minimum 100
# Success: Coverage is 100%
Use Case 3: Compliance Audit
Scenario: Demonstrating traceability for compliance audit.
Goal: Prove all user requirements are traced to implementation and tests.
Workflow:
# Generate audit report
req coverage --audit \
--trace-from USR \
--trace-to TST \
--output audit-report.pdf
# Report shows:
# - Complete traceability chain: USR → SYS → SWR → TST
# - No gaps
# - All requirements covered
Configuration (Planned)
Coverage Rules
# config.toml (planned)
[coverage]
# Minimum coverage percentage required
minimum = 95
# Require specific kinds to have children
require_children = ["USR", "SYS"]
# Require specific kinds to have parents
require_parents = ["SYS", "SWR", "TST"]
# Allowed to have no children (leaf requirements)
leaf_kinds = ["TST", "DOC"]
# Allowed to have no parents (root requirements)
root_kinds = ["USR"]
Coverage Thresholds
[coverage.thresholds]
# Per-kind minimum coverage
USR = 100 # All user requirements must have children
SYS = 95 # 95% of system requirements must have children
SWR = 90 # 90% of software requirements must have children
TST = 100 # All tests must have parents
Report Formats
Plain Text
Simple text output:
req coverage
Markdown
Detailed Markdown report:
req coverage --format markdown > coverage.md
HTML
Interactive HTML dashboard:
req coverage --format html > coverage.html
JSON
Machine-readable output:
req coverage --format json > coverage.json
Example JSON:
{
"timestamp": "2025-07-22T12:00:00Z",
"overall_coverage": 93,
"by_kind": {
"USR": {
"total": 25,
"with_children": 23,
"without_children": 2,
"coverage": 92
},
"SYS": {
"total": 47,
"with_parents": 45,
"with_children": 43,
"coverage": 96
}
},
"gaps": [
{
"hrid": "USR-002",
"type": "no_children",
"description": "User data export"
}
]
}
CSV
Spreadsheet-compatible output:
req coverage --format csv > coverage.csv
Traceability Matrix
Generate traceability matrices showing parent-child relationships:
req coverage --matrix
Output (simplified):
| USR-001 | USR-002 | USR-003
---------|---------|---------|---------
SYS-001 | X | |
SYS-002 | X | | X
SYS-003 | | |
SYS-004 | | | X
Features:
- Rows: Child requirements
- Columns: Parent requirements
- X: Link exists
- Empty: No link
- Highlights gaps and orphans
Integration
CI/CD
Enforce coverage in CI:
# .github/workflows/requirements.yml (planned)
- name: Check requirement coverage
run: |
req coverage --minimum 95
if [ $? -ne 0 ]; then
echo "Coverage below minimum"
req coverage --detailed
exit 1
fi
Pull Request Comments
Automatically comment on PRs with coverage impact:
- name: Coverage report
run: |
req coverage --format markdown > coverage.md
gh pr comment ${{ github.event.number }} --body-file coverage.md
Dashboard Integration
Export coverage to dashboards:
# Export for Grafana/Prometheus
req coverage --format prometheus > metrics.txt
Metrics (Planned)
Coverage Percentage
coverage = (requirements_with_links / total_requirements) * 100
Downstream Coverage
downstream_coverage = (parents_with_children / total_parents) * 100
Upstream Coverage
upstream_coverage = (children_with_parents / total_children) * 100
Orphan Rate
orphan_rate = (requirements_without_parents / total_requirements) * 100
Workarounds (Until Implemented)
Manual coverage analysis:
Script to Find Gaps
#!/bin/bash
# find-gaps.sh
echo "USR requirements without SYS children:"
comm -23 \
<(ls USR-*.md | sed 's/.md//' | sort) \
<(grep -oh "USR-[0-9]*" SYS-*.md | sort -u)
echo ""
echo "SYS requirements without parents:"
for sys in SYS-*.md; do
if ! grep -q "parents:" "$sys"; then
echo " $(basename "$sys" .md)"
fi
done
Spreadsheet Analysis
Create a spreadsheet:
| Requirement | Has Parents | Has Children | Coverage |
|---|---|---|---|
| USR-001 | N/A | Yes | ✓ |
| USR-002 | N/A | No | ✗ |
| SYS-001 | Yes | Yes | ✓ |
| SYS-003 | No | No | ✗ |
Track manually until coverage reporting is implemented.
Summary
Planned functionality:
- Coverage percentage by requirement kind
- Gap identification (requirements without parents/children)
- Orphan detection
- Traceability matrices
- Multiple report formats (text, Markdown, HTML, JSON, CSV)
- CI/CD integration
- Configurable coverage thresholds
Use cases:
- Requirement reviews
- Release readiness checks
- Compliance audits
- Quality assurance
Timeline: Implementation planned for future release
Next Steps
- Use workarounds for manual coverage analysis
- Plan your coverage requirements for when feature is available
- See Cycle Detection for finding circular dependencies
Cycle Detection
Note: Cycle detection is planned but not yet implemented. This chapter describes how the feature will work when available.
Cycle detection identifies circular dependencies in requirement graphs, which are usually errors that break valid traceability hierarchies.
What are Cycles?
A cycle occurs when requirements form a circular dependency chain:
USR-001 → SYS-001 → SYS-002 → USR-001
Requirements form a loop: USR-001 depends on SYS-001, which depends on SYS-002, which depends back on USR-001.
Why Cycles are Problematic
Break hierarchy assumptions:
- Requirements should form a Directed Acyclic Graph (DAG)
- Cycles violate DAG properties
Logical impossibility:
- A cannot be satisfied until B is satisfied
- B cannot be satisfied until C is satisfied
- C cannot be satisfied until A is satisfied
- Nothing can be satisfied!
Review complexity:
- Changes propagate indefinitely
- Impossible to determine impact
Compliance issues:
- Many standards require acyclic traceability
- Auditors expect clear hierarchies
Example Cycles
Simple Cycle (2 requirements)
USR-001 → SYS-001 → USR-001
Why it happens: Accidental bi-directional linking.
Detection: SYS-001 lists USR-001 as parent; USR-001 lists SYS-001 as parent.
Complex Cycle (3+ requirements)
USR-001 → SYS-001 → SYS-002 → SWR-001 → USR-001
Why it happens: Accumulation of links over time without oversight.
Detection: Following parent chain eventually returns to starting requirement.
Self-Reference
USR-001 → USR-001
Why it happens: Data entry error.
Detection: Requirement lists itself as a parent.
Planned Functionality
Cycle Detection Command
req check-cycles
Output (if cycles found):
Error: Cycles detected in requirement graph
Cycle 1 (length 3):
USR-001 → SYS-001 → SYS-002 → USR-001
Cycle 2 (length 2):
SYS-005 → SWR-003 → SYS-005
Cycle 3 (self-reference):
SWR-012 → SWR-012
Total cycles: 3
Fix these cycles to ensure valid traceability.
Output (no cycles):
No cycles detected. Requirement graph is acyclic.
Detailed Cycle Information
req check-cycles --detailed
Output:
Cycle 1:
Path: USR-001 → SYS-001 → SYS-002 → USR-001
Length: 3
Requirements involved:
- USR-001: User authentication
Parent: SYS-002 (creates cycle)
- SYS-001: Authentication service
Parent: USR-001
- SYS-002: Session management
Parent: SYS-001
Suggested fix:
Remove parent link from USR-001 to SYS-002
(User requirements should not depend on system requirements)
Visualization
Generate cycle diagrams:
req check-cycles --visualize > cycles.dot
dot -Tpng cycles.dot -o cycles.png
Output: Graph highlighting cyclic paths in red.
How Detection Works
Algorithm: Depth-First Search
Requiem will use DFS with cycle detection:
- Start from each requirement
- Follow parent links (or child links for reverse traversal)
- Track visited requirements in current path
- If revisit a requirement in current path: Cycle detected
- Report cycle: Full path from requirement back to itself
Example Walkthrough
Requirements:
USR-001 → SYS-001
SYS-001 → SYS-002
SYS-002 → USR-001 (creates cycle)
Detection:
1. Start at USR-001
2. Visit SYS-001 (parent of USR-001)
3. Visit SYS-002 (parent of SYS-001)
4. Visit USR-001 (parent of SYS-002)
5. USR-001 is already in path → Cycle detected!
6. Report: USR-001 → SYS-001 → SYS-002 → USR-001
Performance
- Time complexity: O(V + E) where V = requirements, E = links
- Expected runtime: Milliseconds for 1000s of requirements
- Parallel detection: Possible for disconnected subgraphs
Use Cases
Use Case 1: Continuous Validation
Scenario: Automatically check for cycles in CI.
Workflow:
# .github/workflows/requirements.yml (planned)
- name: Check for cycles
run: |
req check-cycles
if [ $? -ne 0 ]; then
echo "Cycles detected!"
req check-cycles --detailed
exit 1
fi
Benefit: Cycles are caught before merging.
Use Case 2: Fixing Legacy Requirements
Scenario: Inherited a requirement set with unknown quality.
Goal: Find and fix all cycles.
Workflow:
# Detect cycles
req check-cycles --detailed
# Output:
# Cycle 1: USR-001 → SYS-001 → SYS-002 → USR-001
# Suggested fix: Remove link from USR-001 to SYS-002
# Fix cycle
vim USR-001.md # Remove SYS-002 from parents
# Verify
req check-cycles
# No cycles detected
Use Case 3: Incremental Checking
Scenario: Adding a new link between requirements.
Goal: Ensure the new link doesn't create a cycle.
Workflow:
# Add link
req link SWR-001 SYS-005
# Check if cycle created
req check-cycles
# If cycle:
# Error: Cycle detected: SYS-005 → ... → SWR-001 → SYS-005
# If no cycle:
# No cycles detected
Benefit: Immediate feedback; don't commit cycle-inducing links.
Breaking Cycles
Strategy 1: Remove Link
Identify the "weakest" link in the cycle and remove it:
USR-001 → SYS-001 → SYS-002 → USR-001
^^^^^^^
Remove this link
Criteria for "weakest":
- Violates hierarchy (e.g., user requirement depending on system requirement)
- Accidental or incorrect
- Least impactful to remove
Strategy 2: Reverse Hierarchy
If requirements are at wrong levels, reassign:
Before (cycle):
USR-001 → SYS-001
SYS-001 → USR-002
USR-002 → USR-001
After (fixed):
USR-001, USR-002 → SYS-001
(SYS-001 now has both as parents; no cycle)
Strategy 3: Introduce Intermediate Requirement
Break cycle by adding a requirement:
Before (cycle):
USR-001 → SYS-001 → USR-001
After (fixed):
USR-001 → SYS-001 → SYS-002
(SYS-002 is new, breaks cycle)
Strategy 4: Merge Requirements
If cycle indicates redundancy, merge:
Before (cycle):
REQ-A → REQ-B → REQ-A
After (merged):
REQ-AB (combines A and B; no cycle)
Configuration (Planned)
Enable/Disable Cycle Checking
# config.toml (planned)
[cycles]
# Enable cycle detection
enabled = true
# Fail on cycle detection (exit with error)
fail_on_cycle = true
# Report self-references separately
detect_self_references = true
CI Integration
[cycles.ci]
# Run cycle detection in CI
enabled = true
# Block merge if cycles detected
block_on_cycle = true
Exceptions (Planned)
In rare cases, cycles might be intentional. Allow marking exceptions:
# USR-001.md (hypothetical)
---
_version: '1'
uuid: ...
parents:
- uuid: ...
hrid: SYS-002
cycle_exception: true # Mark as intentional cycle
---
Or in config:
[cycles.exceptions]
# Allow specific cycles
allowed = [
["USR-001", "SYS-001", "USR-001"],
]
Use sparingly: Cycles are almost always errors.
Related Features
Topological Sort
After ensuring no cycles, enable topological sorting:
req sort --topological
Output: Requirements in dependency order (parents before children).
Use case: Determine implementation order.
Dependency Depth
Analyze requirement depth in hierarchy:
req depth USR-001
Output:
USR-001:
Depth: 0 (root requirement)
Max descendant depth: 4
Path to deepest descendant:
USR-001 → SYS-001 → SWR-003 → TST-012
Workarounds (Until Implemented)
Manual cycle detection:
Script to Detect Simple Cycles
#!/usr/bin/env python3
import glob
import yaml
import re
def parse_requirement(path):
with open(path) as f:
content = f.read()
match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if match:
frontmatter = yaml.safe_load(match.group(1))
return frontmatter
return None
def find_cycles():
# Build graph
graph = {}
for req_file in glob.glob("*.md"):
hrid = req_file.replace('.md', '')
frontmatter = parse_requirement(req_file)
if frontmatter:
parents = frontmatter.get('parents', [])
parent_hrids = [p['hrid'] for p in parents]
graph[hrid] = parent_hrids
# Detect cycles with DFS
def visit(req, path):
if req in path:
cycle = path[path.index(req):] + [req]
print(f"Cycle detected: {' → '.join(cycle)}")
return True
if req not in graph:
return False
for parent in graph[req]:
if visit(parent, path + [req]):
return True
return False
for req in graph:
visit(req, [])
if __name__ == '__main__':
find_cycles()
Run:
python detect-cycles.py
Manual Inspection
For small requirement sets, manually trace parent chains:
- Pick a requirement (e.g., USR-001)
- Follow parent links
- Track visited requirements
- If you return to the starting requirement, cycle exists
Summary
Key concepts:
- Cycle: Circular dependency chain in requirement graph
- Problem: Breaks hierarchy, causes logical impossibility
- Detection: Depth-first search with path tracking
- Resolution: Remove links, reverse hierarchy, introduce intermediate requirements
Planned functionality:
- Automatic cycle detection
- Detailed cycle reports with suggested fixes
- Visualization of cyclic paths
- CI/CD integration
- Configurable checking
Use cases:
- CI validation
- Legacy requirement cleanup
- Incremental validation
Timeline: Implementation planned for future release
Next Steps
- Use workarounds for manual cycle detection
- Plan your cycle detection requirements for when feature is available
- See Coverage Reports for traceability analysis
Import and Export
Note: Import and export features are planned but not yet implemented. This chapter describes how these features will work when available.
Import and export enable interoperability with other requirements management tools and formats.
Overview
Planned import/export formats:
- ReqIF: Requirements Interchange Format (OMG standard)
- JSON: Machine-readable format for custom tools
- CSV: Spreadsheet format for analysis
- Doorstop YAML: Migrate from Doorstop projects
- HTML: Human-readable export for documentation
- PDF: Formal document generation
Why Import/Export Matters
Migration: Move requirements from other tools to Requiem
Integration: Exchange requirements with other systems
Analysis: Export to spreadsheets for custom analysis
Documentation: Generate formal requirement documents
Backup: Archive requirements in multiple formats
Compliance: Provide requirements in auditor-requested formats
Export Functionality
Export to JSON
req export --format json --output requirements.json
Output format:
{
"version": "1",
"exported_at": "2025-07-22T12:00:00Z",
"requirements": [
{
"hrid": "USR-001",
"uuid": "4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a",
"created": "2025-07-22T10:00:00Z",
"content": "The system shall validate...",
"tags": ["authentication", "security"],
"parents": [
{
"uuid": "3fc6800c-5acc-457e-baf9-a29b42b663fd",
"hrid": "USR-002",
"fingerprint": "e533784ff58c16cbf08e436cb06f09e0..."
}
]
}
]
}
Export to CSV
req export --format csv --output requirements.csv
Output format:
HRID,UUID,Created,Content,Tags,Parents
USR-001,4bfeb7d5-...,2025-07-22T10:00:00Z,"The system shall...","authentication,security","USR-002"
USR-002,3fc6800c-...,2025-07-22T09:00:00Z,"Users shall be able to...","",""
SYS-001,81e63bac-...,2025-07-22T11:00:00Z,"The authentication service...","","USR-001,USR-002"
Open in Excel, Google Sheets, or other spreadsheet tools.
Export to ReqIF
req export --format reqif --output requirements.reqif
ReqIF: OMG standard for requirements exchange, compatible with:
- IBM DOORS
- Siemens Polarion
- PTC Integrity
- Jama Connect
- Many other tools
Use case: Send requirements to partners/customers using commercial tools.
Export to HTML
req export --format html --output requirements.html
Features:
- Styled requirement documents
- Clickable traceability links
- Filterable by kind, tag
- Printable
- Standalone (no external dependencies)
Export to PDF
req export --format pdf --output requirements.pdf
Use case: Formal requirement documents for:
- Reviews
- Approvals
- Audits
- Archival
Import Functionality
Import from JSON
req import --format json --input requirements.json
Creates .md files from JSON requirement data.
Validation:
- Checks for UUID conflicts
- Validates HRID format
- Ensures parent references are valid
Conflict resolution:
req import --format json --input requirements.json --on-conflict skip
req import --format json --input requirements.json --on-conflict overwrite
req import --format json --input requirements.json --on-conflict rename
Import from CSV
req import --format csv --input requirements.csv
CSV format requirements:
- Must have headers:
HRID,UUID,Content - Optional:
Created,Tags,Parents Parentscolumn: comma-separated HRIDs or UUIDs
Example CSV:
HRID,UUID,Content,Tags,Parents
USR-001,4bfeb7d5-...,The system shall validate emails,authentication,
SYS-001,81e63bac-...,Email validation service,authentication,USR-001
Import from Doorstop
Migrate from Doorstop projects:
req import --format doorstop --input /path/to/doorstop/project
What's imported:
- Doorstop documents → Requiem requirement kinds
- Doorstop items → Requiem requirements
- Links → Parent relationships
- Attributes → Tags or content
Mapping:
Doorstop Requiem
-------- -------
Document PREFIX Requirement KIND (e.g., USR)
Item UID UUID (generated or preserved)
Item text Requirement content
Item links Parent relationships
Item attributes Tags
Import from ReqIF
req import --format reqif --input requirements.reqif
Use case: Import from commercial tools (DOORS, Polarion, etc.)
Challenges:
- ReqIF is complex; not all features map to Requiem
- May require manual cleanup after import
Selective Export/Import
Export Specific Requirements
By kind:
req export --kind USR --format json --output usr-requirements.json
By tag:
req export --tag security --format csv --output security-reqs.csv
By namespace:
req export --namespace AUTH --format html --output auth-reqs.html
Import with Filtering
Skip certain requirements:
req import --format json --input reqs.json --exclude-kind DOC
Rename on import:
req import --format json --input reqs.json --rename-kind USR=USER
Transformation During Import/Export
HRID Remapping
Change HRIDs during import:
req import --format json --input reqs.json --remap-hrids
Generates new HRIDs while preserving UUIDs (maintains traceability).
Use case: Merging requirement sets with conflicting HRIDs.
Namespace Addition
Add namespace during import:
req import --format json --input reqs.json --add-namespace LEGACY
Imports USR-001 as LEGACY-USR-001.
Use case: Integrating acquired projects.
Tag Transformation
Add tags during import:
req import --format json --input reqs.json --add-tag imported --add-tag legacy
Round-Trip Compatibility
Goal: Export and re-import without data loss.
Guaranteed for:
- JSON format (lossless)
- ReqIF format (best effort)
Limitations:
- CSV format (lossy: no complex structures)
- HTML/PDF (read-only export, no import)
Validation:
# Export
req export --format json --output export.json
# Import to clean directory
mkdir test && cd test
req import --format json --input ../export.json
# Compare
diff -r ../original ./
# Should be identical
Use Cases
Use Case 1: Migrating from Doorstop
Scenario: Existing project using Doorstop.
Goal: Migrate to Requiem.
Workflow:
# Export from Doorstop (if needed)
doorstop export all doorstop-export.json
# Import to Requiem
mkdir requiem-reqs && cd requiem-reqs
req import --format doorstop --input ../doorstop-project
# Validate
req clean
# Compare manually
# Adjust as needed
# Commit
git init
git add .
git commit -m "Migrate from Doorstop to Requiem"
Use Case 2: Exchanging Requirements with Partners
Scenario: Partner uses IBM DOORS; you use Requiem.
Goal: Exchange requirements.
Workflow:
# Export from Requiem to ReqIF
req export --format reqif --output requirements.reqif
# Send to partner
# Partner imports into DOORS
# Receive updated ReqIF from partner
# Import updates
req import --format reqif --input updated-requirements.reqif --on-conflict merge
# Review changes
git diff
# Accept or reject
Use Case 3: Spreadsheet Analysis
Scenario: Need to analyze requirements in Excel.
Goal: Export to CSV, analyze, re-import.
Workflow:
# Export to CSV
req export --format csv --output requirements.csv
# Open in Excel
# Add column "Priority" with values
# Save as requirements-with-priority.csv
# Import with new tags
req import --format csv --input requirements-with-priority.csv \
--map-column Priority=tag
# Priority values become tags
Use Case 4: Generating Formal Documents
Scenario: Need PDF for customer review.
Goal: Professional requirement document.
Workflow:
# Export to PDF
req export --format pdf --output requirements.pdf \
--template formal \
--include-toc \
--include-traceability
# Review
open requirements.pdf
# Send to customer
Configuration (Planned)
Export Settings
# config.toml (planned)
[export]
# Default export format
default_format = "json"
# Include fingerprints in export
include_fingerprints = true
# Include timestamps
include_timestamps = true
[export.json]
# Pretty-print JSON
pretty = true
indent = 2
[export.csv]
# CSV delimiter
delimiter = ","
# Include header row
include_header = true
[export.pdf]
# Template to use
template = "formal"
# Include table of contents
include_toc = true
# Include traceability matrix
include_traceability = true
Import Settings
[import]
# Action on UUID conflict
on_conflict = "skip" # skip, overwrite, rename
# Validate after import
validate = true
# Automatically run req clean after import
auto_clean = true
Troubleshooting
UUID Conflicts
Problem: Importing requirements with UUIDs that already exist.
Solutions:
--on-conflict skip: Skip conflicting requirements--on-conflict overwrite: Replace existing--on-conflict rename: Generate new UUIDs
Invalid HRIDs
Problem: Imported HRIDs don't match Requiem format.
Solution:
req import --format csv --input reqs.csv --remap-hrids
Generates valid HRIDs automatically.
Broken Links After Import
Problem: Parent references don't resolve.
Diagnosis:
req clean
# Reports missing parent requirements
Solution: Ensure all referenced requirements are imported.
Workarounds (Until Implemented)
Manual export/import with scripts:
Export to JSON (Manual)
#!/usr/bin/env python3
import glob
import yaml
import re
import json
requirements = []
for path in glob.glob("*.md"):
with open(path) as f:
content = f.read()
match = re.match(r'^---\n(.*?)\n---\n(.*)$', content, re.DOTALL)
if match:
frontmatter = yaml.safe_load(match.group(1))
body = match.group(2).strip()
hrid = path.replace('.md', '')
requirements.append({
"hrid": hrid,
"uuid": frontmatter['uuid'],
"created": frontmatter['created'],
"content": body,
"tags": frontmatter.get('tags', []),
"parents": frontmatter.get('parents', [])
})
with open("requirements.json", "w") as f:
json.dump({"requirements": requirements}, f, indent=2, default=str)
print(f"Exported {len(requirements)} requirements to requirements.json")
Import from CSV (Manual)
#!/usr/bin/env python3
import csv
import uuid
from datetime import datetime
with open("requirements.csv") as f:
reader = csv.DictReader(f)
for row in reader:
hrid = row['HRID']
req_uuid = row.get('UUID', str(uuid.uuid4()))
content = row['Content']
tags = row.get('Tags', '').split(',') if row.get('Tags') else []
frontmatter = f"""---
_version: '1'
uuid: {req_uuid}
created: {datetime.utcnow().isoformat()}Z
"""
if tags:
frontmatter += "tags:\n"
for tag in tags:
frontmatter += f"- {tag.strip()}\n"
frontmatter += "---\n\n"
with open(f"{hrid}.md", "w") as f:
f.write(frontmatter + content + "\n")
print("Import complete")
Summary
Planned formats:
- Export: JSON, CSV, ReqIF, HTML, PDF
- Import: JSON, CSV, ReqIF, Doorstop
Use cases:
- Migration from other tools
- Partner/customer exchange
- Spreadsheet analysis
- Formal document generation
- Backup and archival
Key features:
- Selective export/import
- Format transformation
- Conflict resolution
- Round-trip compatibility (JSON, ReqIF)
- Validation
Timeline: Implementation planned for future release
Next Steps
- Use manual workarounds for current export/import needs
- Plan your import/export requirements for when feature is available
- Review Coverage Reports and Cycle Detection for other advanced features
Example: Requiem's Own Requirements
This section contains Requiem's actual project requirements - the specification that defines what this tool does. These requirements serve a dual purpose:
- Project Specification: Formal requirements that guide Requiem's development
- Worked Example: A real-world demonstration of Requiem managing its own requirements
Why This Matters
Most requirements management tools provide toy examples with a handful of simple requirements. By using Requiem to manage Requiem's own requirements, we demonstrate:
- Dogfooding: We trust our own tool for serious work
- Real traceability: User requirements flow down to system requirements
- Best practices: Professional structure, clear writing, proper linking
- Scale: A complete requirements set, not just a demo
- Integration: Requirements living alongside documentation (MdBook)
Requirements Structure
Requiem's requirements follow a two-level hierarchy:
User Requirements (USR)
High-level requirements that describe what users need from the tool. These focus on user-facing functionality and capabilities.
- USR-001: Plain Text Storage
- USR-002: Unique and Stable Identifiers
- USR-003: Requirement Relationships and Traceability
- USR-004: Graph Analysis and Validation
- USR-005: Static Site Generator Integration
- USR-006: Requirement Templates
- USR-007: Requirement Visibility and Navigation
System Requirements (SYS)
Detailed technical requirements that describe how the system implements user needs. These specify file formats, algorithms, CLI commands, and implementation details.
- SYS-001: Markdown File Format with YAML Frontmatter
- SYS-002: UUID and HRID Fields
- SYS-003: Parent Requirement Links
- ... and 17 more system requirements
View all system requirements →
Traceability in Action
Notice how system requirements trace back to user requirements. For example:
USR-006: Requirement Templates has five child system requirements:
- SYS-011: Template File Storage
- SYS-012: Default Template Application
- SYS-013: Template Override via CLI
- SYS-014: Template Format
- SYS-015: Namespace-Specific Templates
This demonstrates the USR→SYS traceability that Requiem was built to support. Each user need is decomposed into specific technical requirements.
Using This as a Learning Resource
As you read through the user guide, refer back to these requirements to see concepts in practice:
- File Format: See SYS-001 for the actual specification
- HRIDs: See SYS-002 for identifier format rules
- Parent Links: See SYS-003 for linking structure
- Fingerprints: See SYS-005 for suspect link detection
- Templates: See SYS-011 through SYS-015 for complete template system specification
- CLI Visibility: See SYS-017 through SYS-019 for the listing and navigation interface
Configuration
This requirements directory includes:
config.toml: Requiem configuration (version only).req/templates/: Template files for new requirementsUSR.md: Template for user requirementsSYS.md: Template for system requirements
Exploring Further
Browse the requirements directly:
Or jump to specific requirements using the links above.
Note: These requirements are managed using Requiem itself. Any changes go through the same review process documented in Maintaining Requirements.
User Requirements
User requirements (USR) define the high-level capabilities that Requiem must provide to its users. These requirements focus on what the tool enables users to accomplish, from the user's perspective.
Overview
Requiem has 7 user requirements that establish the core value proposition:
| ID | Title | Summary |
|---|---|---|
| USR-001 | Plain Text Storage | Requirements stored as plain text files readable in any editor |
| USR-002 | Unique and Stable Identifiers | Dual identifiers: UUIDs for machines, HRIDs for humans |
| USR-003 | Requirement Relationships and Traceability | Parent-child relationships forming traceable hierarchies |
| USR-004 | Graph Analysis and Validation | Cycle detection and change impact analysis |
| USR-005 | Static Site Generator Integration | Compatibility with MdBook and Sphinx |
| USR-006 | Requirement Templates | Support for templates when creating new requirements |
| USR-007 | Requirement Visibility and Navigation | CLI listing and graph exploration for working sets |
Detailed Requirements
USR-001: Plain Text Storage
The tool shall store requirements as plain-text files that can be read and edited with any text editor.
Why this matters: Plain text enables version control integration, human review without specialized software, long-term archival, and integration with existing text-based workflows.
Child requirements: SYS-001, SYS-002
USR-002: Unique and Stable Identifiers
The tool shall assign each requirement both a UUID (for technical stability) and a human-readable ID/HRID (for human reference).
Why this matters: UUIDs prevent conflicts and enable merging, while HRIDs like "USR-001" make requirements easy to discuss, link, and remember.
Child requirements: SYS-002
USR-003: Requirement Relationships and Traceability
The tool shall support defining parent-child relationships between requirements, enabling traceability from high-level needs to detailed specifications.
Why this matters: Traceability is essential for understanding requirement flow, impact analysis, coverage verification, and compliance in regulated industries.
Child requirements: SYS-003
USR-004: Graph Analysis and Validation
The tool shall analyze the requirement graph to detect invalid structures (cycles) and identify the impact of changes.
Why this matters: Requirements form a directed acyclic graph (DAG). Cycles are errors. Impact analysis shows what's affected when requirements change.
Child requirements: SYS-004, SYS-005, SYS-008, SYS-009, SYS-010
USR-005: Static Site Generator Integration
The tool shall integrate with documentation frameworks (Sphinx, MdBook) so requirements can be included in generated documentation.
Why this matters: Requirements shouldn't live in isolation. They should integrate with design docs, user guides, and API documentation in a single published site.
Child requirements: SYS-006, SYS-007
USR-006: Requirement Templates
The tool shall support defining templates that provide default content and structure for new requirements.
Why this matters: Templates ensure consistency, reduce boilerplate, encode best practices, and make requirement creation faster.
Child requirements: SYS-011, SYS-012, SYS-013, SYS-014, SYS-015
USR-007: Requirement Visibility and Navigation
The tool shall let users quickly locate, inspect, and summarize requirements from the command line without opening individual files.
Why this matters: Reviewers and systems engineers need instant visibility into requirement sets during audits, change control, and release prep. Native listing and navigation commands eliminate manual grepping and ad-hoc spreadsheets.
Child requirements: SYS-017, SYS-018, SYS-019
Traceability
Each USR requirement traces down to one or more SYS (system) requirements that provide technical implementation details:
USR-001 (Plain Text Storage)
├── SYS-001 (Markdown File Format with YAML Frontmatter)
└── SYS-002 (UUID and HRID Fields)
USR-002 (Unique and Stable Identifiers)
└── SYS-002 (UUID and HRID Fields)
USR-003 (Requirement Relationships and Traceability)
└── SYS-003 (Parent Requirement Links)
USR-004 (Graph Analysis and Validation)
├── SYS-004 (Cycle Detection in Requirement Graph)
├── SYS-005 (Suspect Link Detection)
├── SYS-008 (Suspect Links CLI Command)
├── SYS-009 (Accept Individual Suspect Links)
└── SYS-010 (Accept All Suspect Links in Bulk)
USR-005 (Static Site Generator Integration)
├── SYS-006 (Sphinx and MyST Parser Compatibility)
└── SYS-007 (MdBook Compatibility)
USR-006 (Requirement Templates)
├── SYS-011 (Template File Storage)
├── SYS-012 (Default Template Application)
├── SYS-013 (Template Override via CLI)
├── SYS-014 (Template Format)
└── SYS-015 (Namespace-Specific Templates)
USR-007 (Requirement Visibility and Navigation)
├── SYS-017 (Requirements Listing CLI Command)
├── SYS-018 (Listing Filters and Scopes)
├── SYS-019 (Relationship Navigation Views)
└── SYS-020 (Status Dashboard CLI Command)
This hierarchy demonstrates requirement decomposition from user needs down to technical implementation.
Next Steps
System Requirements
System requirements (SYS) define the technical implementation details for Requiem. While user requirements describe what users need, system requirements specify how the tool delivers those capabilities. Some outcomes include dedicated specifications (SPC) that capture detailed interaction or visual design.
Overview
Requiem has 20 system requirements organized by functional area:
File Format & Identifiers
| ID | Title | Parent | Summary |
|---|---|---|---|
| SYS-001 | Markdown File Format with YAML Frontmatter | USR-001 | Files contain YAML metadata block and Markdown body |
| SYS-002 | UUID and HRID Fields | USR-001, USR-002 | Frontmatter includes UUID, HRID, version, created timestamp |
| SYS-003 | Parent Requirement Links | USR-003 | Parent links stored as arrays with UUID, HRID, fingerprint |
Graph Analysis & Validation
| ID | Title | Parent | Summary |
|---|---|---|---|
| SYS-004 | Cycle Detection in Requirement Graph | USR-004 | Tool validates requirements form a DAG with no cycles |
| SYS-005 | Suspect Link Detection | USR-004 | Detects when parent fingerprint doesn't match stored value |
| SYS-008 | Suspect Links CLI Command | USR-004 | req suspect command lists all suspect links — spec: SPC-001 |
| SYS-009 | Accept Individual Suspect Links | USR-004 | req accept <child> <parent> updates one suspect link — spec: SPC-001 |
| SYS-010 | Accept All Suspect Links in Bulk | USR-004 | req accept --all updates all suspect links with safeguards — spec: SPC-001 |
Static Site Integration
| ID | Title | Parent | Summary |
|---|---|---|---|
| SYS-006 | Sphinx and MyST Parser Compatibility | USR-005 | Requirements compatible with Sphinx + MyST Parser |
| SYS-007 | MdBook Compatibility | USR-005 | Requirements render correctly in MdBook |
Template System
| ID | Title | Parent | Summary |
|---|---|---|---|
| SYS-011 | Template File Storage | USR-006 | Templates stored as markdown files in .req/templates/ |
| SYS-012 | Default Template Application | USR-006 | Creating requirement uses template content as default body |
| SYS-013 | Template Override via CLI | USR-006 | -t and -b flags override template content |
| SYS-014 | Template Format | USR-006 | Templates support full CommonMark markdown |
| SYS-015 | Namespace-Specific Templates | USR-006 | Different templates for same KIND with different namespaces |
Repository Organisation
| ID | Title | Parent | Summary |
|---|---|---|---|
| SYS-016 | Directory Structure Modes | — | Toggle between filename and path-based HRID conventions — spec: SPC-004 |
CLI Visibility & Navigation
| ID | Title | Parent | Summary |
|---|---|---|---|
| SYS-017 | Requirements Listing CLI Command | USR-007 | req list enumerates requirements with key metadata — spec: SPC-002 |
| SYS-018 | Listing Filters and Scopes | USR-007 | Filters restrict results by kind, namespace, tags, text — spec: SPC-002 |
| SYS-019 | Relationship Navigation Views | USR-007 | Options expose parents, children, ancestors, descendants — spec: SPC-002 |
| SYS-020 | Status Dashboard CLI Command | USR-007 | req status shows counts by kind and suspect total — spec: SPC-003 |
Detailed Requirements
File Format & Identifiers
SYS-001: Markdown File Format with YAML Frontmatter
Each requirement shall be stored as a single plain-text Markdown file containing a YAML frontmatter block and a Markdown body. Files are named {HRID}.md with frontmatter delimited by --- markers.
SYS-002: UUID and HRID Fields
The YAML frontmatter shall include required fields: _version (format version), uuid (globally unique identifier), created (ISO 8601 timestamp). The HRID is derived from the filename.
SYS-003: Parent Requirement Links
Parent links shall be stored in a parents array, where each link contains uuid, hrid, and fingerprint (SHA256 hash of parent content) for change detection.
Graph Analysis & Validation
SYS-004: Cycle Detection in Requirement Graph
The tool shall validate that requirements form a directed acyclic graph (DAG). Cycles are invalid because they create circular dependencies. Detection uses depth-first traversal.
SYS-005: Suspect Link Detection
When a parent's fingerprint doesn't match the stored value in a child's frontmatter, the link is "suspect" - indicating the parent changed. The tool identifies these for review.
SYS-008: Suspect Links CLI Command
The req suspect command lists all suspect links in the graph, showing child HRID and suspect parent HRID. Exits with non-zero status if suspect links found (useful for CI).
Read full requirement → Specification: SPC-001
SYS-009: Accept Individual Suspect Links
The req accept <child-hrid> <parent-hrid> command accepts a specific suspect link by updating the fingerprint in the child's frontmatter to match the parent's current content hash.
Read full requirement → Specification: SPC-001
SYS-010: Accept All Suspect Links in Bulk
The req accept --all command accepts all suspect links in bulk. Supports --dry-run to preview changes and --force to bypass confirmation prompt.
Read full requirement → Specification: SPC-001
Static Site Integration
SYS-006: Sphinx and MyST Parser Compatibility
Requirement files shall be compatible with Sphinx using the MyST Parser, rendering frontmatter as metadata and body content correctly. YAML syntax must be MyST-compatible.
SYS-007: MdBook Compatibility
Requirement files shall render correctly in MdBook. YAML frontmatter is ignored (not rendered), and markdown body content displays properly following CommonMark specification.
Template System
SYS-011: Template File Storage
Templates are stored as individual markdown files in the .req/templates/ directory, named after requirement kind: {KIND}.md. Namespace-specific templates use {NAMESPACE}-{KIND}.md.
SYS-012: Default Template Application
When creating a requirement via req add <KIND>, if a template file exists for that kind, the tool uses the template content as the default body content.
SYS-013: Template Override via CLI
The -t/--title and -b/--body flags allow users to override template content. If either flag is provided, the template is completely ignored.
SYS-014: Template Format
Template files contain plain markdown text supporting standard markdown formatting: headings, lists, code blocks, links, etc. No special template syntax required - content is inserted verbatim.
SYS-015: Namespace-Specific Templates
Different templates can be configured for the same KIND with different namespaces (e.g., AUTH-USR.md vs USR.md). Template lookup tries full prefix first, then falls back to KIND only.
Repository Organisation
SYS-016: Directory Structure Modes
Repositories can opt into filename-based or path-based HRID conventions, ensuring teams keep traceability intact while adopting folder structures that fit their workflow.
Read full requirement → Specification: SPC-004
CLI Visibility & Navigation
SYS-017: Requirements Listing CLI Command
The req list command enumerates requirements with key metadata, supporting multiple output formats for human and machine consumption.
Read full requirement → Specification: SPC-002
SYS-018: Listing Filters and Scopes
The listing command provides filters (kind, namespace, tag, text search) and pagination controls so users can focus on relevant subsets.
Read full requirement → Specification: SPC-002
SYS-019: Relationship Navigation Views
Relationship-centric options expose parents, children, ancestors, descendants, and tree views to assist with impact analysis and reviews.
Read full requirement → Specification: SPC-002
SYS-020: Status Dashboard CLI Command
The req status command prints requirement counts per kind, reports the overall total, and highlights the suspect link count with a non-zero exit when attention is required.
Read full requirement → Specification: SPC-003
Implementation Status
Implemented ✅:
- All file format requirements (SYS-001, SYS-002, SYS-003)
- Fingerprints and suspect link detection (SYS-005, SYS-008)
- Static site integration (SYS-006, SYS-007)
- Complete template system (SYS-011 through SYS-015)
- Individual suspect link acceptance (SYS-009)
- Status dashboard command (SYS-020)
In Progress 🚧:
- Cycle detection (SYS-004)
- Bulk suspect link acceptance (SYS-010)
Planned 📝:
- Requirements listing and navigation (SYS-017, SYS-018, SYS-019)
Traceability
Each system requirement traces back to one or more user requirements. See the "Parent" column in the tables above, or view the User Requirements page for the complete traceability tree.
Next Steps
CLI Command Reference
Complete reference for the req command-line interface.
Overview
The req command is the main interface to Requiem. It provides commands for creating, linking, and managing requirements.
Global Synopsis
req [OPTIONS] <COMMAND>
Running req with no subcommand defaults to req status, providing a quick health
dashboard for the repository.
Getting Help
# General help
req --help
# Command-specific help
req add --help
req link --help
req clean --help
Version Information
req --version
Global Options
Options that apply to all commands.
-v, --verbose
Increase logging verbosity. Can be specified multiple times.
Levels:
- No
-v: WARN level (errors and warnings only) -v: INFO level (general information)-vv: DEBUG level (detailed debugging information)-vvv: TRACE level (very detailed trace information)
Examples:
req -v clean # INFO level
req -vv add USR # DEBUG level
req -vvv link SYS-001 USR-001 # TRACE level
Use cases:
- Normal use: No
-vflag - Troubleshooting:
-vor-vv - Development/debugging:
-vvv
-r, --root <PATH>
Specify the root directory containing requirements.
Default: Current directory (.)
Examples:
req --root /path/to/requirements add USR
req -r ./reqs clean
req --root ~/project/requirements link SYS-001 USR-001
Notes:
- Path can be absolute or relative
- Must be a directory
- Directory should contain
config.toml(optional) and.mdrequirement files
Commands
req status
Display a quick summary of requirement counts and suspect links.
Synopsis
req status [OPTIONS]
Options
None.
Behavior
- Loads all requirements in the repository.
- Prints a table listing each requirement kind with its count and the overall total.
- Displays the total number of suspect links.
- Exits with status code
1when any suspect links are present, otherwise0.
Examples
Summary view:
req status
req add
Create a new requirement.
Synopsis
req add [OPTIONS] <KIND>
Arguments
<KIND> (required)
The kind of requirement to create. This becomes the KIND component of the HRID.
Examples: USR, SYS, SWR, TST, AUTH-USR (with namespace)
Options
-p, --parent <PARENT>...
Specify parent requirement(s) by HRID. Can be specified multiple times or as comma-separated list.
Examples:
# Single parent
req add SYS --parent USR-001
# Multiple parents (multiple flags)
req add SYS --parent USR-001 --parent USR-002
# Multiple parents (comma-separated)
req add SYS --parents USR-001,USR-002
# Short form
req add SYS -p USR-001,USR-002
-t, --title <TITLE>
Set the title of the requirement. The title will be formatted as a markdown heading (# Title).
If both -t and -b are provided, the title appears first, followed by a blank line, then the body.
Examples:
# Create with title only
req add USR -t "User Authentication"
# Create with title and body
req add USR -t "User Authentication" -b "The system shall authenticate users."
-b, --body <BODY>
Set the body content of the requirement. Can be any markdown text.
Examples:
# Create with body only
req add USR -b "The system shall validate user input."
# Create with multi-line body (using quotes)
req add USR -b "The system shall:
- Validate input
- Sanitize data
- Log attempts"
Behavior
- Determines next available ID for the given KIND (e.g.,
USR-001) - Determines title and body:
- Title from
-t/--titleflag, or empty if not provided - Body from
-b/--bodyflag, or template file, or empty
- Title from
- Creates requirement file
<KIND>-<ID>.mdwith:- Level-1 heading with HRID and title (e.g.,
# USR-001 My Title) - YAML frontmatter (UUID, timestamp, tags, parents)
- Body content (from flag, template, or empty)
- Level-1 heading with HRID and title (e.g.,
- Prints the HRID of created requirement
Template Behavior:
- Templates provide body content only (not HRID or title)
- CLI flags (
-t,-b) always override templates - Templates are matched by KIND (e.g.,
USR.mdforUSRrequirements) - Template files are stored in
.req/templates/directory - See Templates Guide for details
Examples
Create user requirement:
req add USR
# Output: Added requirement USR-001
Create system requirement with parent:
req add SYS --parent USR-001
# Output: Added requirement SYS-001
Create requirement with multiple parents:
req add SWR --parents SYS-001,SYS-002
# Output: Added requirement SWR-001
Create namespaced requirement:
req add AUTH-USR
# Output: Added requirement AUTH-USR-001
Create with title and body:
req add USR -t "User Authentication" -b "The system shall authenticate users."
# Output: Added requirement USR-001
# Content: # User Authentication\n\nThe system shall authenticate users.
Create with template (assuming .req/templates/USR.md exists):
req add USR
# Output: Added requirement USR-001
# File structure:
# ---
# _version: '1'
# uuid: ...
# created: ...
# ---
# # USR-001
#
# [Template body content from .req/templates/USR.md]
Create with template and title:
req add USR -t "User Authentication"
# Output: Added requirement USR-001
# Uses title from -t flag, body from template
Override template with body flag:
req add USR -b "Custom content"
# Output: Added requirement USR-001
# Uses body from -b flag, template ignored
Error Cases
Empty KIND:
req add ""
# Error: Kind cannot be empty
Invalid KIND (if allowed_kinds configured):
req add INVALID
# Error: Kind 'INVALID' is not in the allowed list
Parent not found:
req add SYS --parent USR-999
# Error: Parent requirement USR-999 not found
req link
Create a parent-child link between two existing requirements.
Synopsis
req link <CHILD> <PARENT>
Arguments
<CHILD> (required)
HRID of the child requirement (the requirement gaining a parent).
<PARENT> (required)
HRID of the parent requirement (the upstream requirement).
Behavior
- Loads both child and parent requirements
- Adds parent reference to child's frontmatter:
- Parent's UUID
- Parent's current HRID
- Parent's current fingerprint
- Saves updated child requirement
- Prints confirmation message
Examples
Link system to user requirement:
req link SYS-001 USR-001
# Output: Linked SYS-001 to USR-001
Link with namespaces:
req link AUTH-SYS-001 AUTH-USR-001
# Output: Linked AUTH-SYS-001 to AUTH-USR-001
Create second parent (multiple parents supported):
req link SYS-001 USR-001 # First parent
req link SYS-001 USR-002 # Second parent
# SYS-001 now has two parents
Error Cases
Child not found:
req link SYS-999 USR-001
# Error: Child requirement SYS-999 not found
Parent not found:
req link SYS-001 USR-999
# Error: Parent requirement USR-999 not found
Invalid HRID format:
req link INVALID USR-001
# Error: Invalid HRID format: INVALID
req suspect
List all suspect links in the requirement graph.
Synopsis
req suspect
Arguments
None.
Options
None.
Behavior
- Loads all requirements from the requirements directory
- Compares stored parent fingerprints with current parent fingerprints
- Lists all requirements with mismatched fingerprints (suspect links)
- For each suspect link, displays:
- Child HRID → Parent HRID
- Stored fingerprint (first 16 characters)
- Current fingerprint (first 16 characters)
- Exits with code 1 if suspect links found (useful for CI/CD)
- Exits with code 0 if no suspect links found
Examples
Check for suspect links:
req suspect
Example output when suspect links exist:
Found 3 suspect link(s):
SYS-001 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-002 → USR-001
Stored fingerprint: e533784ff58c16cb
Current fingerprint: c4020419ead000e9
SYS-005 → USR-004
Stored fingerprint: 407c6e3413d5b3fa
Current fingerprint: c28afe188a974322
Example output when no suspect links:
No suspect links found.
In CI/CD pipeline:
req suspect && echo "All links current" || echo "Review needed"
Use Cases
- Pre-commit validation: Check if parent requirements changed without updating children
- CI/CD integration: Fail builds when requirements need review
- Regular audits: Identify requirements needing review after upstream changes
- Change impact: See which requirements are affected by parent changes
Exit Codes
- 0: No suspect links found (all fingerprints current)
- 1: Suspect links found (some requirements need review)
This exit code behavior makes the command useful in automation:
#!/bin/bash
req suspect
if [ $? -ne 0 ]; then
echo "ERROR: Requirements need review before release"
exit 1
fi
req accept
Accept suspect links after review, updating fingerprints to current values.
Synopsis
req accept <CHILD> <PARENT>
req accept --all
Arguments
<CHILD> (required unless --all)
HRID of the child requirement containing the suspect link.
<PARENT> (required unless --all)
HRID of the parent requirement referenced by the suspect link.
Options
--all
Accept all suspect links in the requirements directory. Updates all fingerprints to match current parent values.
Behavior
Single link mode (req accept <CHILD> <PARENT>):
- Loads the child and parent requirements
- Verifies the link exists
- Updates the stored fingerprint to match the parent's current fingerprint
- Saves the updated child requirement
- Prints confirmation or reports if link was already up to date
Bulk mode (req accept --all):
- Finds all suspect links
- Updates all fingerprints to current values
- Saves all affected requirements
- Prints summary of updated links
Examples
Accept a single suspect link:
req accept SYS-001 USR-001
# Output: Accepted suspect link: SYS-001 → USR-001
Accept all suspect links:
req accept --all
# Output:
# Accepted 3 suspect link(s):
# SYS-001 → USR-001
# SYS-002 → USR-001
# SYS-005 → USR-004
Accept after no review needed:
req accept SYS-001 USR-001
# Output: Link SYS-001 → USR-001 is already up to date (not suspect).
Workflow
Typical workflow for handling suspect links:
# 1. Check for suspect links
req suspect
# 2. Review parent changes
vim USR-001.md # Review what changed
# 3. Review child requirement
vim SYS-001.md # Update if needed
# 4. Accept the link (marks as reviewed)
req accept SYS-001 USR-001
# 5. Verify no more suspect links
req suspect
Use Cases
- After review: Mark requirements as reviewed after verifying consistency with parent changes
- Bulk acceptance: Update all fingerprints after reviewing multiple changes
- Post-merge: Accept fingerprints after merging upstream requirement changes
- Release preparation: Clear all suspect links before release
Error Cases
Link not found:
req accept SYS-001 USR-999
# Error: Parent requirement USR-999 not found
Child not found:
req accept SYS-999 USR-001
# Error: Child requirement SYS-999 not found
No link exists:
req accept SYS-001 USR-001
# Error: link from SYS-001 to USR-001 not found
No suspect links with --all:
req accept --all
# Output: No suspect links to accept.
req list
List requirements with optional filtering, traversal, and output formatting.
Synopsis
req list [OPTIONS] [HRID...]
Arguments
<HRID> (optional, repeats)
Target requirements to anchor the listing. When omitted, the command starts from all requirements (with the default view limited to top-level, parentless requirements).
Options
--columns <COL>: Comma-separated list of columns (hrid,title,kind,namespace,parents,children,tags,path,created). Default columns show HRID, title, kind, parent count, child count, and tags. When--quietis present without explicit columns, only HRIDs are emitted.--sort <FIELD>: Sort output byhrid(default),kind,title, orcreated.--output <FORMAT>: Choosetable(default),json, orcsv. Table output is human readable; JSON and CSV are machine friendly.--quiet: Suppress headers and format rows for shell pipelines. Defaults to one HRID per line unless additional columns are requested.--kind <KIND>,--namespace <SEG>,--tag <TAG>: Filter by kind, namespace segment, or tag (case-insensitive, commas or repeated flags allowed).--orphans,--leaves: Limit to requirements with no parents or no children.--contains <TEXT>,--regex <PATTERN>: Search requirement title/body with a case-insensitive substring or Rust regular expression (mutually exclusive).--view <MODE>: Choose how to explore relationships. Options:summary(default table),parents,children,ancestors,descendants,tree(indented descendant view), andcontext(base rows plus labelled neighbours).--depth <N>: Depth limit for the selected view (default1for parents/children/context, unlimited for ancestors/descendants/tree). Use0for no limit.--limit <N>,--offset <N>: Paginate large result sets by skippingoffsetrows and then truncating tolimit. Defaults to 200 rows when omitted; pass--limit 0for no cap.
Behavior
- Loads all requirements and builds parent/child relationships.
- Determines the working set:
- If HRIDs are provided, they anchor traversal; otherwise all requirements are considered.
- Without explicit filters or traversal flags, the default view lists every requirement sorted by HRID and capped at the default limit.
- Applies requested filters and relationship traversal.
- Formats output according to the selected layout.
Examples
Top-level overview:
req list
HRID Title Kind Parents Children Tags
USR-001 Plain Text Storage USR 0 2
USR-004 Graph Analysis and Validation USR 0 5
Filter by kind and tag:
req list --kind SYS --tag navigation --output csv
Descendants of a user requirement:
req list USR-004 --view descendants --kind SYS
Tree view:
req list USR-004 --view tree --depth 2
req clean
Correct parent HRIDs in all requirements.
Synopsis
req clean
Arguments
None.
Options
None.
Behavior
- Loads all requirements from the requirements directory
- For each requirement:
- Checks parent HRIDs against actual parent filenames
- If HRID is outdated, updates to current HRID
- Saves requirement if changed
- Silent on success (no output if no corrections made)
- With
-v, logs each correction
Examples
Validate/correct all requirements:
req clean
# (no output = success, all HRIDs correct or corrected)
Verbose output:
req -v clean
# Output:
# INFO Corrected parent HRID in SYS-001: USR-001 → USR-100
# INFO Corrected parent HRID in SYS-002: USR-001 → USR-100
With custom root:
req --root /path/to/requirements clean
Use Cases
- After renaming requirement files
- After reorganizing requirements
- Before committing changes (validation)
- Regular maintenance
Error Cases
Parent UUID not found:
req clean
# Error: Parent requirement <UUID> not found!
This indicates a requirement references a parent that doesn't exist. Either restore the parent or manually remove the reference.
Self-referential parent:
req clean
# Error: Requirement <UUID> is its own parent!
This indicates a requirement lists itself as a parent. Manually remove the self-reference.
Common Workflows
Creating a Requirement Hierarchy
# Create user requirements
req add USR # USR-001
req add USR # USR-002
# Create system requirements linked to user requirements
req add SYS --parent USR-001 # SYS-001
req add SYS --parent USR-002 # SYS-002
# Create software requirement satisfying multiple system requirements
req add SWR --parents SYS-001,SYS-002 # SWR-001
# Create test linked to software requirement
req add TST --parent SWR-001 # TST-001
Renaming Requirements
# Rename requirement file
mv USR-001.md USR-100.md
# Update parent references
req clean
# Verify
git diff # See updated parent HRIDs
Linking Existing Requirements
# Requirements already exist
# USR-001.md
# SYS-001.md
# Create link
req link SYS-001 USR-001
# Add second parent
req link SYS-001 USR-002
Managing Requirement Changes
# Edit a parent requirement
vim USR-001.md # Make changes
# Check for suspect links
req suspect
# Output: SYS-001 → USR-001 (fingerprint mismatch)
# Review affected child
vim SYS-001.md # Review and update if needed
# Accept the change
req accept SYS-001 USR-001
# Verify all links current
req suspect
# Output: No suspect links found.
Bulk Review Workflow
# After updating multiple parent requirements
req suspect
# Shows all suspect links
# Review and update children as needed
vim SYS-001.md
vim SYS-002.md
# ... review all affected requirements
# Accept all at once
req accept --all
# Commit changes
git add -A
git commit -m "Update requirements after USR changes"
Exit Codes
Requiem uses standard exit codes:
- 0: Success
- Non-zero: Error
Examples:
req add USR && echo "Success" # Success
req add INVALID || echo "Failed" # Failed (if KIND not allowed)
Use in scripts:
#!/bin/bash
req clean
if [ $? -eq 0 ]; then
echo "Requirements validated"
git commit -am "Update requirements"
else
echo "Validation failed"
exit 1
fi
Environment Variables
RUST_LOG
Control logging level (alternative to -v flags).
Values:
error: Error messages onlywarn: Warnings and errors (default)info: Informational messagesdebug: Debug messagestrace: Verbose trace messages
Examples:
RUST_LOG=info req clean
RUST_LOG=debug req add USR
RUST_LOG=trace req link SYS-001 USR-001
Module-specific logging:
RUST_LOG=requiem=debug req clean
RUST_LOG=requiem::storage=trace req add USR
Output Formats
Standard Output
Success messages go to stdout:
req add USR
# Output: Added requirement USR-001
Standard Error
Errors and logs go to stderr:
req add INVALID 2> errors.log
JSON Output (Planned)
Machine-readable output:
req add USR --format json
# {"success": true, "hrid": "USR-001", "uuid": "..."}
Shell Completion
Generate shell completion scripts:
Bash:
req --generate-completion bash > /etc/bash_completion.d/req
Zsh:
req --generate-completion zsh > /usr/local/share/zsh/site-functions/_req
Fish:
req --generate-completion fish > ~/.config/fish/completions/req.fish
PowerShell:
req --generate-completion powershell > req.ps1
(Note: Completion generation not yet implemented in current version)
Configuration File
While not a CLI option, the config.toml file affects CLI behavior:
_version = "1"
allowed_kinds = ["USR", "SYS", "TST"] # Restricts req add
digits = 3 # Affects HRID formatting
allow_unrecognised = true # Affects req clean behavior
See Configuration Reference for details.
Performance Considerations
Parallel Loading
Requiem loads requirements in parallel for performance:
- 100 requirements: < 1 second
- 1000 requirements: ~2-3 seconds
- 10000 requirements: ~15-20 seconds
Large Directories
For very large requirement sets (1000+):
- Use subdirectories for organization
req cleanscales well due to parallelism- Consider namespaces to partition large sets
Troubleshooting
Command Not Found
Error: req: command not found
Solution:
# Install Requiem
cargo install requirements-manager
# Verify installation
which req
req --version
Permission Denied
Error: Permission denied when creating/modifying files
Solution: Ensure write permissions to requirements directory:
chmod u+w *.md
chmod u+w .
Invalid Configuration
Error: Failed to parse config file
Solution: Check config.toml syntax:
# Validate TOML
cat config.toml | python -c "import sys, toml; toml.load(sys.stdin)"
Unexpected Behavior
Enable verbose logging:
req -vv <command>
Check logs for detailed error messages.
Summary
Core commands:
req add <KIND>- Create requirementreq link <CHILD> <PARENT>- Link requirementsreq suspect- List suspect links (fingerprint mismatches)req accept <CHILD> <PARENT>- Accept suspect link after reviewreq accept --all- Accept all suspect linksreq clean- Correct parent HRIDs
Global options:
-v, --verbose- Increase logging-r, --root <PATH>- Specify requirements directory
Exit codes:
0- Success1- Suspect links found (req suspect only)- Non-zero - Error (other commands)
Getting help:
req --help- General helpreq <command> --help- Command-specific help
Next Steps
- See File Format Specification for requirement file structure
- See Configuration Reference for
config.tomloptions - Review Working with Requirements for practical usage
File Format Specification
Formal specification of the Requiem requirement file format.
Overview
Requiem requirements are stored as Markdown files with YAML frontmatter. This document provides the formal specification.
File Extension
.md (Markdown)
Character Encoding
UTF-8
Filename Format
{NAMESPACE-}*{KIND}-{ID}.md
Where:
NAMESPACE: Zero or more namespace segments (alphanumeric, hyphen-separated)KIND: Alphanumeric requirement kind (e.g.,USR,SYS)ID: Positive integer (zero-padded to configured digits, default 3)
Examples:
USR-001.md
SYS-042.md
AUTH-USR-001.md
MOBILE-AUTH-LOGIN-SYS-005.md
Validation Rules:
- Must end with
.md - NAMESPACE segments: non-empty, alphanumeric plus hyphen
- KIND: non-empty, alphanumeric
- ID: positive integer (1 or more), may have leading zeros
- Segments separated by single hyphen
- - No consecutive hyphens
-- - No leading or trailing hyphens
File Structure
Requirements consist of three parts:
- YAML Frontmatter: Metadata enclosed in
---delimiters - HRID Heading: First heading with HRID as first token
- Markdown Body: Requirement text in CommonMark format
General Structure
---
<YAML frontmatter>
---
# <HRID> <Title>
<blank line optional>
<Markdown content>
Example
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
tags:
- authentication
- security
parents:
- uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
hrid: USR-001
---
# SYS-001 Email Validation
The system shall validate user email addresses according to RFC 5322.
Email validation must occur before account creation.
YAML Frontmatter
Delimiters
- Opening delimiter:
---on first line - Closing delimiter:
---on its own line - Both required
Schema Version 1
Current version: 1
Required Fields
_version
Type: String (quoted)
Format: "1"
Purpose: Schema version for forward/backward compatibility
Validation:
- Must be present
- Must be string type (quoted in YAML)
- Currently only
"1"is valid
Example:
_version: '1'
uuid
Type: UUID (string format)
Format: UUID v4 (RFC 4122)
Purpose: Globally unique, stable identifier
Validation:
- Must be present
- Must be valid UUID format:
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - Should be generated with
uuid::Uuid::new_v4()or equivalent - Must be unique across all requirements (globally)
- Must never change after creation
Example:
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created
Type: Timestamp (string format)
Format: ISO 8601 with timezone (RFC 3339)
Purpose: Requirement creation timestamp
Validation:
- Must be present
- Must be valid ISO 8601 timestamp
- Must include timezone (use UTC:
Zsuffix) - Format:
YYYY-MM-DDTHH:MM:SS.sssssssssZ
Example:
created: 2025-07-22T12:19:56.950194157Z
Notes:
- Nanosecond precision supported
- Timezone must be UTC (
Zsuffix) - Set once at creation; never modified
Optional Fields
tags
Type: Array of strings
Format: YAML list
Purpose: Categorize and tag requirements
Validation:
- Optional (omit if no tags)
- Array elements must be strings
- Empty array allowed but should be omitted
- No duplicate tags within same requirement
- Tags are case-sensitive
Example:
tags:
- authentication
- security
- high-priority
Omission:
# No tags field = no tags
_version: '1'
uuid: ...
# tags field omitted
Serialization:
- Include only if non-empty:
skip_serializing_if = "BTreeSet::is_empty" - Stored as
BTreeSetinternally (sorted, unique)
parents
Type: Array of parent objects
Format: YAML list of objects
Purpose: Link to parent (upstream) requirements
Validation:
- Optional (omit if no parents, e.g., root requirements)
- Array elements must be parent objects (see Parent Object Schema)
- Empty array allowed but should be omitted
- Duplicate parent UUIDs allowed (though unusual)
Example:
parents:
- uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
hrid: USR-001
- uuid: 7a8f9e2b-1c3d-4e5f-6a7b-8c9d0e1f2a3b
fingerprint: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
hrid: USR-003
Omission:
# No parents field = no parents (root requirement)
_version: '1'
uuid: ...
# parents field omitted
Serialization:
- Include only if non-empty:
skip_serializing_if = "Vec::is_empty"
Parent Object Schema
Each parent object has three fields:
uuid
Type: UUID (string format)
Format: UUID v4
Purpose: Stable reference to parent requirement
Validation:
- Must be present in parent object
- Must be valid UUID format
- Should match
uuidfield of an existing requirement
Example:
uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint
Type: String (hex-encoded SHA256 hash)
Format: 64-character hexadecimal string
Purpose: Content hash of parent for change detection
Validation:
- Must be present in parent object
- Must be 64-character hexadecimal string
- Generated by hashing parent's content and tags with SHA256
Example:
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
Generation:
1. Collect parent's content (markdown body) and tags
2. Serialize with Borsh encoding
3. Hash with SHA256
4. Encode as hexadecimal string (64 characters)
hrid
Type: String (HRID format)
Format: {NAMESPACE-}*{KIND}-{ID}
Purpose: Human-readable reference to parent (convenience field)
Validation:
- Must be present in parent object
- Must be valid HRID format
- Should match parent's filename (without
.mdextension)
Example:
hrid: USR-001
Notes:
- Convenience field for human readability
- May become outdated if parent is renamed
- Corrected by
req cleancommand - UUID is authoritative; HRID is informational
Schema Evolution
Future schema versions (e.g., _version: "2") will be backward-compatible:
- New optional fields may be added
- Required fields will not be removed
- Field semantics will not change incompatibly
Parsers should:
- Ignore unknown fields
- Provide defaults for missing optional fields
- Reject unknown
_versionvalues (fail-safe)
HRID Heading
Format
The first heading in the markdown must contain the HRID as the first token:
# <HRID> <Title Text>
Requirements
- Must be a level-1 heading (
#) - HRID must be the first token (word)
- Followed by space and title text
- HRID must match the filename (without
.md)
Examples
# USR-001 Plain Text Storage
# SYS-042 Email Validation System
# AUTH-LOGIN-SYS-001 Password Hashing
Rationale
The HRID is stored in the heading (not frontmatter) for compatibility with Sphinx and MdBook, which use the first heading as the page title.
Markdown Body
Format
CommonMark (Markdown specification)
Location
Everything after the first heading is the markdown body.
Content
Free-form Markdown:
- Headings (
##,###, etc. - first#is reserved for HRID) - Paragraphs
- Lists (ordered, unordered)
- Code blocks (fenced, indented)
- Emphasis (bold, italic)
- Links
- Images
- Blockquotes
- Tables
- Any CommonMark-compliant content
Whitespace
- Leading/trailing whitespace: preserved
- Empty lines between frontmatter and body: ignored
- Empty body: valid (empty string)
Example
---
_version: '1'
uuid: ...
created: ...
---
# USR-001 Email Validation
The system shall validate user email addresses.
## Rationale
Email validation ensures...
## Acceptance Criteria
- Valid email format
- Rejects invalid emails
- Provides clear error messages
Parsing Rules
Frontmatter Parsing
- First line must be
--- - Read lines until next
---on its own line - Parse collected lines as YAML
- Validate against schema
- Remaining lines are markdown body
Error Handling
Missing opening delimiter:
Error: Expected frontmatter starting with '---'
Missing closing delimiter:
Error: Unexpected EOF while parsing frontmatter
Invalid YAML:
Error: Failed to parse YAML: <syntax error details>
Missing required field:
Error: Missing required field '<field_name>'
Invalid UUID format:
Error: Invalid UUID format: '<value>'
Invalid timestamp format:
Error: Invalid timestamp format: '<value>'
Unknown _version:
Error: Unknown schema version: '<value>'
Strict vs. Permissive
Requiem parsing is strict by default:
- All required fields must be present
- All fields must be valid
- Unknown fields in schema version 1 cause errors (currently)
Controlled by allow_invalid config option:
allow_invalid = false(default): Strict parsing, fail on errorsallow_invalid = true: Skip invalid requirements with warnings
Serialization Rules
Field Order
Fields serialized in this order:
_versionuuidcreatedtags(if present)parents(if present)
Omission Rules
tags: Omitted if emptyparents: Omitted if empty
Formatting
- YAML indentation: 2 spaces
- String quoting: Single quotes for strings containing special characters
- Array formatting: One element per line with
-prefix - Object formatting: Indented key-value pairs
Example Output
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
tags:
- authentication
- security
parents:
- uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
hrid: USR-001
---
Requirement text here.
Validation
Syntactic Validation
- Valid YAML frontmatter
- Valid Markdown body (CommonMark)
- Correct delimiters
Semantic Validation
- Required fields present
- Field types correct
- UUID format valid
- Timestamp format valid
- HRID format valid (in parent references)
- Fingerprint format valid (64-char hex)
Referential Integrity
- Parent UUIDs reference existing requirements
- No self-references (requirement is not its own parent)
- No duplicate UUIDs across all requirements
Configuration-Based Validation
- HRID KIND in
allowed_kinds(if configured) - File follows naming convention (if
allow_unrecognised = false)
Canonical Example
---
_version: '1'
uuid: 4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a
created: 2025-07-22T12:19:56.950194157Z
tags:
- authentication
- security
- high-priority
parents:
- uuid: 3fc6800c-5acc-457e-baf9-a29b42b663fd
fingerprint: c4020419ead000e9b5f9cfd4ebf6192e73f905c27e6897548d8f6e12fd7f1356
hrid: USR-001
- uuid: 7a8f9e2b-1c3d-4e5f-6a7b-8c9d0e1f2a3b
fingerprint: a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
hrid: USR-003
---
# SYS-001 Email Validation
The system shall validate user email addresses according to RFC 5322.
## Rationale
Email validation ensures that user accounts can be contacted and that
authentication tokens can be delivered reliably.
## Acceptance Criteria
- Email addresses must match RFC 5322 format
- Invalid email addresses must be rejected with clear error message
- Validation must occur before account creation
## References
- RFC 5322: Internet Message Format
- OWASP Email Validation Guidelines
Summary
File format:
- Markdown (
.md) files with UTF-8 encoding - YAML frontmatter enclosed in
---delimiters - CommonMark markdown body
Required frontmatter fields:
_version: Schema version (currently"1")uuid: Unique identifier (UUID v4)created: Creation timestamp (ISO 8601 with UTC)
Optional frontmatter fields:
tags: Array of tagsparents: Array of parent objects (uuid, fingerprint, hrid)
Validation:
- Strict by default
- Controlled by
allow_invalidconfig option - Includes syntactic, semantic, and referential checks
Next Steps
- See CLI Command Reference for working with requirements
- See Configuration Reference for config options
- Review Working with Requirements for practical examples
Configuration Reference
Complete reference for Requiem's config.toml configuration file.
Overview
The config.toml file configures Requiem's behavior. It must be located in the root of your requirements directory.
File Location
requirements/
├── config.toml ← Configuration file
├── USR-001.md
├── USR-002.md
└── SYS-001.md
File Format
TOML (Tom's Obvious Minimal Language)
Optional
Configuration file is optional. If absent, Requiem uses defaults.
Schema Version 1
Current schema version: 1
Complete Example
_version = "1"
allowed_kinds = ["USR", "SYS", "SWR", "TST"]
digits = 3
allow_unrecognised = false
allow_invalid = false
subfolders_are_namespaces = false
Configuration Fields
_version (required)
Schema version for forward/backward compatibility.
Type: String (quoted)
Required: Yes
Default: N/A (must be explicitly specified)
Valid Values: "1"
Example:
_version = "1"
Purpose:
- Enables future schema changes
- Allows old Requiem versions to detect incompatible configs
- Allows new Requiem versions to handle old configs
Validation:
- Must be present
- Must be quoted string
- Must be
"1"in current version
Errors:
Missing:
# config.toml
allowed_kinds = ["USR"]
Error: Failed to parse config file: missing field '_version'
Wrong type:
_version = 1 # Wrong: integer instead of string
Error: Failed to parse config file: invalid type: integer, expected a string
allowed_kinds
Restrict which requirement kinds are permitted.
Type: Array of strings
Required: No
Default: [] (empty array = all kinds allowed)
Valid Values: Array of non-empty strings
Example:
allowed_kinds = ["USR", "SYS", "SWR", "TST"]
Purpose:
- Enforce project conventions
- Prevent typos (USR vs UST)
- Document allowed requirement types
Behavior:
Empty array (default):
allowed_kinds = []
# OR omit field entirely
All kinds accepted: USR-001, SYS-001, CUSTOM-001, etc.
Non-empty array:
allowed_kinds = ["USR", "SYS"]
Only listed kinds accepted:
req add USR✓ Succeedsreq add SYS✓ Succeedsreq add TST✗ Fails (TST not in allowed list)
With namespaces:
allowed_kinds = ["AUTH-USR", "AUTH-SYS", "PAYMENT-USR"]
Exact match required:
req add AUTH-USR✓ Succeedsreq add USR✗ Fails (USR not in allowed list)
Examples:
Aerospace project (DO-178C):
allowed_kinds = ["URQT", "SRQT", "SWRQT", "HWRQT", "TRQT"]
Software project:
allowed_kinds = ["USR", "SYS", "SWR", "TST", "DOC"]
Multi-component with namespaces:
allowed_kinds = [
"AUTH-USR", "AUTH-SYS",
"PAYMENT-USR", "PAYMENT-SYS",
"REPORTING-USR", "REPORTING-SYS"
]
Validation:
- Each element must be non-empty string
- Duplicates allowed (but pointless)
- Case-sensitive matching
Errors:
Empty string in array:
allowed_kinds = ["USR", ""]
Error: Failed to parse config file: empty strings not allowed in allowed_kinds
digits
Number of digits in HRID numbering (with zero-padding).
Type: Unsigned integer
Required: No
Default: 3
Valid Values: Any positive integer (typically 3-5)
Example:
digits = 3
Purpose:
- Control HRID formatting
- Accommodate projects with many requirements per kind
Behavior:
digits = 3 (default):
USR-001
USR-002
USR-010
USR-099
USR-100 # Expands beyond 3 digits when needed
USR-1000
digits = 4:
USR-0001
USR-0002
USR-0010
USR-0999
USR-1000
USR-10000 # Expands beyond 4 digits when needed
digits = 2:
USR-01
USR-02
USR-99
USR-100 # Expands beyond 2 digits when needed
Parsing:
- Requirements can have any number of digits when parsing
USR-1,USR-01,USR-001all parse as ID 1- Display/creation uses configured padding
Recommendations:
digits = 3: < 1000 requirements per kind (most projects)digits = 4: 1000-9999 requirements per kinddigits = 5: Very large projects
Examples:
Small project:
digits = 2
Medium project (default):
digits = 3
Large project:
digits = 4
Validation:
- Must be positive integer
- Zero or negative not allowed
Errors:
Zero:
digits = 0
Error: Failed to parse config file: digits must be positive
allow_unrecognised
Allow markdown files that don't match HRID pattern.
Type: Boolean
Required: No
Default: false
Valid Values: true, false
Example:
allow_unrecognised = true
Purpose:
- Enable mixing requirements with other documentation
- Control strictness of file validation
Behavior:
allow_unrecognised = false (default, strict):
docs/
├── config.toml
├── USR-001.md ← Loaded (valid HRID)
├── USR-002.md ← Loaded (valid HRID)
└── README.md ← ERROR: Not a valid HRID
Error during req clean:
Error: Unrecognised file: README.md
allow_unrecognised = true (permissive):
docs/
├── config.toml
├── USR-001.md ← Loaded (valid HRID)
├── USR-002.md ← Loaded (valid HRID)
└── README.md ← Ignored (not a valid HRID)
No error; README.md is silently skipped.
Use Cases:
Use false (default):
- Dedicated requirements directory
- Strict validation desired
- Catch typos in filenames
Use true:
- Requirements mixed with MdBook/Sphinx content
- Documentation and requirements in same directory
- Legacy projects with existing non-requirement files
Examples:
Strict requirements-only:
_version = "1"
allow_unrecognised = false
Mixed documentation:
_version = "1"
allow_unrecognised = true # Allow chapter1.md, README.md, etc.
Validation:
- Must be boolean
- Case-sensitive:
trueorfalse(lowercase)
Errors:
Wrong case:
allow_unrecognised = True # Wrong: uppercase
Error: Failed to parse config file: invalid value
subfolders_are_namespaces
Control whether subfolder paths contribute to requirement namespaces.
Type: Boolean
Required: No
Default: false
Valid Values: true, false
Example:
subfolders_are_namespaces = true
Purpose:
- Choose between filename-based and path-based directory organization
- Enable cleaner filenames in hierarchical structures
- Align folder structure with namespace hierarchy
Behavior:
subfolders_are_namespaces = false (default, filename-based):
requirements/
├── custom/folder/
│ └── system-auth-REQ-001.md → HRID: system-auth-REQ-001
└── any/path/
└── payment-USR-002.md → HRID: payment-USR-002
- HRID: Fully encoded in filename
- Folders: Purely organizational, don't affect HRID
- Flexibility: Move files freely without changing HRIDs
subfolders_are_namespaces = true (path-based):
requirements/
├── system/
│ └── auth/
│ ├── REQ-001.md → HRID: system-auth-REQ-001
│ └── USR/
│ └── 002.md → HRID: system-auth-USR-002
└── payment/
└── USR-003.md → HRID: payment-USR-003
- HRID: Namespace from folder path + KIND-ID from filename
- Folders: Encode namespace segments
- Format inference:
- Numeric filename (
002.md) → KIND from parent folder - KIND-ID filename (
USR-003.md) → KIND from filename
- Numeric filename (
- Constraint: Moving files changes their HRID
Use Cases:
Use false (default):
- Maximum folder flexibility
- Arbitrary organizational schemes
- Frequent folder reorganization
- Explicit namespaces in every filename
Use true:
- Hierarchical component structures
- Folder structure mirrors system architecture
- Cleaner, shorter filenames
- Enforced namespace-folder alignment
Examples:
Filename-based (flexible organization):
_version = "1"
subfolders_are_namespaces = false
Path-based (structured hierarchy):
_version = "1"
subfolders_are_namespaces = true
Migration:
To convert from filename-based to path-based:
- Set
subfolders_are_namespaces = true - Reorganize files to match namespace structure
- Rename files to remove namespace prefix
To convert from path-based to filename-based:
- Move files and encode full HRID in filename
- Set
subfolders_are_namespaces = false - Optionally flatten directory structure
See Directory Structure for detailed migration guide.
Validation:
- Must be boolean
- Case-sensitive:
trueorfalse(lowercase)
Errors:
Wrong type:
subfolders_are_namespaces = "yes" # Wrong: string instead of boolean
Error: Failed to parse config file: invalid type: string, expected a bool
allow_invalid
Allow requirements with invalid YAML frontmatter or formatting.
Type: Boolean
Required: No
Default: false
Valid Values: true, false
Example:
allow_invalid = true
Purpose:
- Control strictness of requirement validation
- Enable partial loading during migration or recovery
Behavior:
allow_invalid = false (default, strict):
requirements/
├── USR-001.md ← Valid frontmatter, loaded
├── USR-002.md ← Invalid frontmatter (missing uuid)
└── USR-003.md ← Valid frontmatter
Error during req clean:
Error: Invalid requirement USR-002.md: missing required field 'uuid'
Loading fails; no requirements processed.
allow_invalid = true (permissive):
requirements/
├── USR-001.md ← Valid, loaded
├── USR-002.md ← Invalid, skipped with warning
└── USR-003.md ← Valid, loaded
Warning during req clean:
Warning: Skipping invalid requirement USR-002.md: missing required field 'uuid'
Successfully loaded 2 requirements (1 skipped)
Loading continues; valid requirements processed.
Use Cases:
Use false (default):
- Production use
- Ensure data quality
- Catch errors immediately
Use true:
- Migrating from another tool (gradual fix-up)
- Recovering from manual editing errors
- Development/debugging
- Partial validation during cleanup
Examples:
Production (strict):
_version = "1"
allow_invalid = false
Migration (permissive):
_version = "1"
allow_invalid = true # Temporarily allow invalid requirements
Validation:
- Must be boolean
- Case-sensitive:
trueorfalse(lowercase)
Errors:
Wrong type:
allow_invalid = "yes" # Wrong: string instead of boolean
Error: Failed to parse config file: invalid type: string, expected a bool
Minimal Configuration
Smallest valid configuration:
_version = "1"
All other fields use defaults:
allowed_kinds = [](all kinds allowed)digits = 3allow_unrecognised = falseallow_invalid = falsesubfolders_are_namespaces = false
Default Configuration
If config.toml is absent, equivalent to:
_version = "1"
allowed_kinds = []
digits = 3
allow_unrecognised = false
allow_invalid = false
subfolders_are_namespaces = false
Configuration Examples
Small Project
_version = "1"
digits = 3
allow_unrecognised = false
allow_invalid = false
Large Project
_version = "1"
allowed_kinds = ["USR", "SYS", "SWR", "HWR", "TST", "DOC"]
digits = 4 # Expect 1000+ requirements per kind
allow_unrecognised = false
allow_invalid = false
Integrated Documentation
_version = "1"
allowed_kinds = ["USR", "SYS"]
digits = 3
allow_unrecognised = true # Allow MdBook/Sphinx files
allow_invalid = false
Migration Project
_version = "1"
digits = 3
allow_unrecognised = true # Mixed content during migration
allow_invalid = true # Some requirements may be incomplete
Aerospace (DO-178C)
_version = "1"
allowed_kinds = ["URQT", "SRQT", "SWRQT", "HWRQT", "TRQT"]
digits = 4
allow_unrecognised = false
allow_invalid = false
Multi-Component System
_version = "1"
allowed_kinds = [
"CORE-USR", "CORE-SYS",
"AUTH-USR", "AUTH-SYS",
"PAYMENT-USR", "PAYMENT-SYS",
"REPORTING-USR", "REPORTING-SYS"
]
digits = 3
allow_unrecognised = false
allow_invalid = false
Validation
Parsing Errors
Missing _version:
allowed_kinds = ["USR"]
Error: Failed to parse config file: missing field '_version'
Invalid TOML syntax:
_version = "1
allowed_kinds = ["USR"]
Error: Failed to parse config file: expected '"', got newline
Wrong type:
_version = 1 # Should be string
Error: Failed to parse config file: invalid type: integer, expected a string
Unknown field (future-proofing):
_version = "1"
unknown_field = "value"
Currently allowed (forward compatibility), but may be rejected in strict mode.
Runtime Validation
Configuration is loaded at:
req addreq linkreq clean
Errors reported immediately:
req clean
# Error: Failed to load config: missing field '_version'
Schema Evolution
Version 1 (Current)
Fields:
_version(required)allowed_kinds(optional)digits(optional)allow_unrecognised(optional)allow_invalid(optional)subfolders_are_namespaces(optional)
Future Versions
Planned fields (not yet implemented):
Version 2 (hypothetical):
_version = "2"
# Existing fields
allowed_kinds = ["USR", "SYS"]
digits = 3
allow_unrecognised = false
allow_invalid = false
# New fields
[namespaces]
required = true
allowed = ["AUTH", "PAYMENT"]
[review]
auto_flag = true
notify = "team@example.com"
[coverage]
minimum = 95
Compatibility:
- Old Requiem: Rejects
_version = "2"(unknown version) - New Requiem: Reads
_version = "1"(backward compatible)
Troubleshooting
Config Not Recognized
Problem: Changes to config.toml don't take effect.
Solution:
- Ensure file is named exactly
config.toml(lowercase, no extension) - Ensure file is in requirements root directory
- Verify TOML syntax with validator
Parse Errors
Problem: Error: Failed to parse config file
Diagnosis:
- Check TOML syntax
- Ensure strings are quoted
- Ensure arrays use square brackets
- Check for typos in field names
Solution: Validate TOML:
# Python
python -c "import sys, toml; toml.load(open('config.toml'))"
# Online validator
# Copy config to https://www.toml-lint.com/
Requirements Rejected
Problem: req add fails with "Kind not in allowed list"
Diagnosis: Check allowed_kinds in config.
Solution: Add kind to allowed_kinds or use empty array:
allowed_kinds = [] # Allow all kinds
Files Ignored Unexpectedly
Problem: Valid requirement files not loaded.
Diagnosis: Check filename matches HRID pattern.
Solution:
- Ensure filename is
{KIND}-{ID}.md - Set
allow_unrecognised = falseto get error messages
Summary
Configuration file:
- Location:
config.tomlin requirements root - Format: TOML
- Optional: Uses defaults if absent
Required fields:
_version: Schema version (currently"1")
Optional fields:
allowed_kinds: Restrict requirement kinds (default:[], allow all)digits: HRID digit padding (default:3)allow_unrecognised: Allow non-HRID files (default:false)allow_invalid: Allow invalid requirements (default:false)subfolders_are_namespaces: Use path-based structure (default:false)
Defaults:
- All kinds allowed
- 3-digit HRID padding
- Strict file validation
- Strict requirement validation
- Filename-based directory structure
Next Steps
- See CLI Command Reference for commands affected by configuration
- See File Format Specification for requirement format
- Review Configuration File for detailed explanations