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