---
title: "Traceability Best Practices"
description: "Practical guidelines for implementing effective traceability"
---

# Traceability Best Practices

These practices are distilled from industry standards and real-world experience. Following them will help you get the most value from traceability with the least overhead.

## Core Principles

### 1. Trace as You Go

**Don't**: Wait until the end to create traces
**Do**: Create links when you create artifacts

```python
# Good: Link immediately when creating
feature = client.create_item(title="User Login", item_type="feature")
test = client.create_item(title="Test Login", item_type="test")
client.create_link(test.id, feature.id, "tests")  # Right away!

# Bad: Create now, trace "later"
feature = client.create_item(title="User Login", item_type="feature")
# TODO: Add traceability later  ← Never happens
```

**Why**: Memory fades. After a week, you won't remember why test_xyz exists.

### 2. Use Semantic Links

**Don't**: Use generic "related_to" for everything
**Do**: Use specific link types that convey meaning

| Relationship | Link Type |
|--------------|-----------|
| Code implements requirement | `implements` |
| Test verifies requirement | `tests` |
| Feature depends on feature | `depends_on` |
| Feature blocks feature | `blocks` |

```python
# Good: Semantic meaning
client.create_link(code.id, feature.id, "implements")
client.create_link(test.id, feature.id, "tests")

# Bad: No semantic meaning
client.create_link(code.id, feature.id, "related_to")
client.create_link(test.id, feature.id, "related_to")
# Later: "Does this test verify the feature or just relate to it?"
```

### 3. Right-Size Your Granularity

**Don't**: Trace every function to every requirement
**Do**: Trace at meaningful levels

```
✓ Good granularity:
FEAT-001 (Login) ← CODE-001 (auth_handler.py)
                 ← TEST-001 (test_login_success)
                 ← TEST-002 (test_login_failure)

✗ Too fine:
FEAT-001 (Login) ← CODE-001 (validate_email function)
                 ← CODE-002 (hash_password function)
                 ← CODE-003 (create_session function)
                 ← CODE-004 (log_attempt function)
                 ... (unmaintainable)

✗ Too coarse:
EPIC-001 (Auth System) ← CODE-ALL (src/auth/)
                       ← TEST-ALL (tests/auth/)
                       ... (meaningless)
```

### 4. Maintain Bidirectional Traces

**Don't**: Only trace forward or only backward
**Do**: Trace both directions

```
Forward:  FEAT-001 → CODE-001 → TEST-001
          "Is this requirement implemented and tested?"

Backward: TEST-001 → CODE-001 → FEAT-001
          "Why does this test exist?"
```

### 5. Validate Continuously

**Don't**: Assume traces are correct
**Do**: Validate regularly, preferably in CI/CD

```yaml
# .github/workflows/traceability.yml
- name: Validate Traceability
  run: |
    tracertm validate --check coverage --min 90
    tracertm validate --check orphans --fail-on-any
    tracertm validate --check cycles
```

## Implementation Patterns

### Pattern 1: Link on Create

Create links atomically with artifacts:

```python
def create_feature_with_test(title, test_title):
    """Create a feature and its test together."""
    feature = client.create_item(title=title, item_type="feature")
    test = client.create_item(
        title=test_title,
        item_type="test",
        metadata={"linked_feature": feature.id}
    )
    client.create_link(test.id, feature.id, "tests")
    return feature, test
```

### Pattern 2: Convention-Based Linking

Use naming conventions for automatic discovery:

```python
# File: tests/test_FEAT_001_login.py
# Convention: test_<FEATURE_ID>_<description>.py

def scan_tests_by_convention():
    for test_file in glob("tests/test_*.py"):
        match = re.match(r"test_(FEAT_\d+)_", test_file.name)
        if match:
            feature_id = match.group(1)
            # Auto-link test file to feature
            client.create_link(test_file.id, feature_id, "tests")
```

### Pattern 3: Code Comment Traces

Embed traceability in code:

```python
def validate_password(password: str) -> bool:
    """
    Validate password meets security requirements.

    Implements: FEAT-008, SEC-003
    """
    # FEAT-008: Minimum 8 characters
    if len(password) < 8:
        return False

    # SEC-003: Require special character
    if not re.search(r"[!@#$%^&*]", password):
        return False

    return True
```

Scan and extract:
```python
def scan_code_traces(file_path):
    content = open(file_path).read()
    # Find "Implements: FEAT-XXX" patterns
    for match in re.findall(r"Implements:\s*([\w-]+(?:,\s*[\w-]+)*)", content):
        for item_id in match.split(","):
            yield item_id.strip()
```

### Pattern 4: Test Docstring Traces

Use test docstrings for traceability:

```python
def test_login_success():
    """
    Tests: FEAT-001
    Priority: critical
    Type: integration
    """
    response = client.post("/login", json=credentials)
    assert response.status_code == 200
```

### Pattern 5: PR-Based Tracing

Require traces in pull requests:

```markdown
## PR Checklist
- [ ] Tests added for new features
- [ ] Traceability links updated
- [ ] Impact analysis reviewed

## Traceability
Features implemented: FEAT-042, FEAT-043
Tests added: TEST-089, TEST-090
Impact: tracertm impact FEAT-042 shows 5 affected artifacts
```

## Quality Checks

### Check 1: Coverage

Ensure all requirements have tests:

```bash
tracertm report coverage --type feature --min 95

# Fail build if critical features untested
tracertm validate --check coverage \
  --filter "priority=critical" \
  --min 100
```

### Check 2: Orphans

Find artifacts without links:

```bash
tracertm validate --check orphans

# Output:
# Orphan features (no tests): 3
#   FEAT-042, FEAT-089, FEAT-101
# Orphan tests (no requirements): 2
#   TEST-OLD-001, TEST-TEMP-002
# Orphan code (no requirements): 5
#   legacy/*, utils/deprecated.py
```

### Check 3: Cycles

Detect circular dependencies:

```bash
tracertm validate --check cycles

# Output:
# Cycle detected:
#   FEAT-001 → depends_on → FEAT-002 → depends_on → FEAT-001
# Resolution: Remove one dependency or extract shared component
```

### Check 4: Broken Links

Find links to deleted items:

```bash
tracertm validate --check broken-links

# Output:
# Broken links: 2
#   TEST-042 → FEAT-099 (deleted)
#   CODE-015 → FEAT-088 (deleted)
```

## Maintenance Practices

### Weekly Review

```bash
# Generate weekly traceability health report
tracertm report health --period week

# Output:
# Traceability Health Report (Dec 1-7, 2024)
# ──────────────────────────────────────────
# Coverage: 94% (+2% from last week)
# Orphans: 5 (-2 from last week)
# Stale links: 3 (>30 days without update)
# New items without links: 8
```

### Quarterly Audit

```bash
# Comprehensive audit for compliance
tracertm audit --output quarterly-audit.pdf

# Includes:
# - Full coverage matrix
# - Gap analysis
# - Change history
# - Orphan analysis
# - Compliance checklist
```

### Continuous Integration

```yaml
# Run on every PR
on: [pull_request]

jobs:
  traceability:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Check new features have tests
        run: |
          new_features=$(tracertm changed --type feature --since ${{ github.event.before }})
          for feature in $new_features; do
            tests=$(tracertm links $feature --type verified_by)
            if [ -z "$tests" ]; then
              echo "ERROR: $feature has no tests"
              exit 1
            fi
          done

      - name: Validate coverage threshold
        run: tracertm validate --check coverage --min 90
```

## Anti-Patterns to Avoid

### Anti-Pattern 1: Big Bang Tracing

```
❌ Month 1-11: Write code without traceability
   Month 12: "Let's trace everything before the audit"

Problem: Can't remember why things exist
Result: Guessed links, incomplete coverage
```

### Anti-Pattern 2: Over-Linking

```
❌ Every test linked to every "possibly related" feature
   Every code file linked to all features in the module

Problem: Signal lost in noise
Result: Impact analysis is useless
```

### Anti-Pattern 3: Set and Forget

```
❌ Initial traceability created perfectly
   Never updated as code evolves

Problem: Links become stale
Result: False confidence in coverage
```

### Anti-Pattern 4: Manual-Only

```
❌ All traceability maintained manually
   No automation or validation

Problem: Human error, inconsistency
Result: Incomplete, unreliable traces
```

## Tooling Integration

### IDE Integration

Add traceability to your development workflow:

```json
// VS Code settings.json
{
  "tracertm.showLinksInEditor": true,
  "tracertm.validateOnSave": true,
  "tracertm.suggestLinks": true
}
```

### Git Hooks

Validate before commit:

```bash
# .git/hooks/pre-commit
#!/bin/bash
tracertm validate --check orphans --scope staged
if [ $? -ne 0 ]; then
  echo "Traceability validation failed"
  exit 1
fi
```

### CI/CD Pipeline

```yaml
# Include traceability in your pipeline
stages:
  - test
  - traceability
  - deploy

traceability:
  stage: traceability
  script:
    - tracertm scan src/ --auto-link
    - tracertm validate --all
    - tracertm report coverage --output coverage.html
  artifacts:
    paths:
      - coverage.html
```

## Summary Checklist

- [ ] Traces created when artifacts created
- [ ] Semantic link types used consistently
- [ ] Bidirectional traceability maintained
- [ ] Granularity is appropriate (not too fine/coarse)
- [ ] Coverage validated in CI/CD
- [ ] Orphans reviewed weekly
- [ ] Cycles prevented
- [ ] Broken links fixed immediately
- [ ] Quarterly audits scheduled
- [ ] Team trained on practices

## Related Topics

- [What is Traceability?](/docs/wiki/concepts/traceability/what-is) - Fundamentals
- [Types of Traceability](/docs/wiki/concepts/traceability/types) - Different approaches
- [Benefits](/docs/wiki/concepts/traceability/benefits) - ROI and value
- [Industry Standards](/docs/wiki/concepts/traceability/standards) - Compliance requirements

