# 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:
1. **YAML Frontmatter** - Metadata enclosed in `---` delimiters
2. **HRID Title** - The HRID as the first token in the first markdown heading
3. **Markdown Body** - The requirement text
### Example
```markdown
---
_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:
```markdown
# 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`
```yaml
_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`
```yaml
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`
```yaml
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`
```yaml
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 identifier
- `fingerprint` - SHA256 hash of parent's content
- `hrid` - 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)
```yaml
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
```markdown
# 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
```markdown
# 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
```markdown
# 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
```markdown
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:
```markdown
# USR-001 User Authentication
## Rationale
The requirement exists because...
## Acceptance Criteria
- Criterion 1
- Criterion 2
```
#### Lists
```markdown
The system shall support the following authentication methods:
1. Username and password
2. OAuth (Google, GitHub)
3. SAML SSO
```
#### Code Blocks
```markdown
Example API response:
\`\`\`json
{
"user_id": "4bfeb7d5-d168-44a7-b0f1-e292c1c89b9a",
"email": "user@example.com"
}
\`\`\`
```
#### Emphasis
```markdown
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 = true` in 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
```markdown
---
_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
```markdown
---
...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:
```bash
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):
- `created` timestamp
- Parent `fingerprint` fields (updated by linking commands)
### Using Scripts
Since requirements are plain text, you can process them with scripts:
```python
# 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:
```bash
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](../requirements.md) which contains 21 real requirements used by Requiem itself:
- [USR-001: Plain Text Storage](../requirements/USR-001.md) - Simple user requirement
- [SYS-001: Markdown File Format with YAML Frontmatter](../requirements/SYS-001.md) - 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)](./hrids.md) and their syntax rules.