# Document Linking

> Unified ID system for PRDs, ADRs, PRPs, and GitHub issues with bidirectional links.

Unified ID system for PRDs, ADRs, PRPs, and GitHub issues with bidirectional links. Use when linking docs, finding orphans, auto-assigning IDs, or validating cross-doc references.

- Page: https://ss33.ai/skills/laurigates/document-linking-72890723496
- Publisher: laurigates
- Category: [Software Development](https://ss33.ai/skills/category/software-development-t44z8z) › [Developer docs & tooling](https://ss33.ai/skills/category/software-development-t44z8z/developer-docs-and-tooling-nich6w)
- License: MIT
- Source: https://github.com/laurigates/claude-plugins/blob/f8dc5cd452a2ed3af86ab7e65949e0653e88127f/blueprint-plugin/skills/document-linking/SKILL.md

## Skill

SKILL.md: https://ss33.ai/api/v1/ss33/download/laurigates/document-linking-72890723496

# Document Linking

Provides a unified ID system connecting PRDs, ADRs, PRPs, work-orders, GitHub issues, commits, and PRs. IDs are project-scoped, auto-generated on first access, and maintained bidirectionally.

## When to Use This Skill

| Use this skill when... | Use blueprint-sync-ids instead when... |
|---|---|
| You need bidirectional links between PRD/ADR/PRP/issue at runtime | You're doing a one-shot bulk ID assignment for docs missing IDs |
| You're auto-assigning an ID on first document access | You want a `--dry-run` preview of bulk ID changes |
| You want to validate broken cross-document references | Use blueprint-adr-validate instead for ADR-only relationship checks |
| You need to find orphan docs/issues across the project | Use document-detection instead when capturing a brand-new doc |

## ID Format

| Document Type | Format | Example | Notes |
|---------------|--------|---------|-------|
| PRD | `PRD-NNN` | `PRD-001` | 3-digit, zero-padded |
| ADR | `ADR-NNNN` | `ADR-0003` | 4-digit (matches existing convention) |
| PRP | `PRP-NNN` | `PRP-007` | 3-digit, zero-padded |
| Work-Order | `WO-NNN` | `WO-042` | 3-digit, matches work-order number |

## Frontmatter Schema

All blueprint documents should include these fields:

```yaml
---
id: PRD-001                    # Unique identifier (auto-generated if missing)
relates-to:                    # Cross-document references (optional)
  - ADR-0003
  - PRP-002
github-issues:                 # Linked GitHub issues (optional)
  - 42
  - 87
implements:                    # For PRPs: source PRD (optional)
  - PRD-001
# ... existing fields (created, modified, status, etc.)
---
```

## ID Registry (manifest.json)

IDs are tracked in `docs/blueprint/manifest.json`:

```json
{
  "id_registry": {
    "last_prd": 3,
    "last_prp": 7,
    "documents": {
      "PRD-001": {
        "path": "docs/prds/user-authentication.md",
        "github_issues": [42, 87],
        "title": "User Authentication"
      },
      "ADR-0003": {
        "path": "docs/adrs/0003-database-choice.md",
        "github_issues": [],
        "title": "Database Choice"
      },
      "PRP-002": {
        "path": "docs/prps/oauth-integration.md",
        "github_issues": [45],
        "implements": ["PRD-001"],
        "title": "OAuth Integration"
      }
    },
    "github_issues": {
      "42": ["PRD-001", "PRP-002"],
      "45": ["PRP-002"],
      "87": ["PRD-001"]
    }
  }
}
```

## Auto-ID Generation

### When Triggered

IDs are automatically generated when:

1. **Creating documents** - `/blueprint:derive-plans`, `/blueprint:prp-create`
2. **Accessing documents without IDs** - Any command reading PRD/ADR/PRP files
3. **Batch sync** - `/blueprint:sync-ids` assigns IDs to all documents

### Generation Algorithm

```bash
# Get next PRD ID
get_next_prd_id() {
  local manifest="docs/blueprint/manifest.json"
  local last=$(jq -r '.id_registry.last_prd // 0' "$manifest")
  local next=$((last + 1))
  printf "PRD-%03d" "$next"
}

# Get next PRP ID
get_next_prp_id() {
  local manifest="docs/blueprint/manifest.json"
  local last=$(jq -r '.id_registry.last_prp // 0' "$manifest")
  local next=$((last + 1))
  printf "PRP-%03d" "$next"
}

# ADR IDs use existing 4-digit number from filename
get_adr_id() {
  local filename="$1"
  local num=$(basename "$filename" | grep -oE '^[0-9]{4}')
  printf "ADR-%s" "$num"
}
```

### Auto-Assignment on Access

When reading a document without an ID:

1. **Check frontmatter** for existing `id` field
2. **If missing**: Generate next available ID
3. **Update document** frontmatter with new ID
4. **Update manifest** ID registry
5. **Continue** with original operation

```bash
# Check if document has ID
ensure_document_id() {
  local file="$1"
  local type="$2"  # PRD, ADR, PRP

  # Extract existing ID from frontmatter
  local existing_id=$(head -50 "$file" | grep -m1 "^id:" | sed 's/^id:[[:space:]]*//')

  if [ -z "$existing_id" ]; then
    # Generate and assign new ID
    case "$type" in
      PRD) new_id=$(get_next_prd_id) ;;
      PRP) new_id=$(get_next_prp_id) ;;
      ADR) new_id=$(get_adr_id "$file") ;;
    esac

    # Insert ID into frontmatter (after first ---)
    # Update manifest registry
    # Return new ID
  fi

  echo "${existing_id:-$new_id}"
}
```

## GitHub Integration

### Issue Title Format

When creating GitHub issues from documents:

```
[PRD-001] User authentication feature
[PRP-002] Implement OAuth integration
[WO-042] Add JWT token generation
```

### Issue Body Format

```markdown
## Related Documents
- PRD-001: User Authentication
- ADR-0003: Database Choice

## Traceability
- **Implements**: PRD-001
- **Related ADRs**: ADR-0003, ADR-0005
- **Work Orders**: WO-042, WO-043

---
*Auto-linked by Blueprint. Update document frontmatter to modify links.*
```

### Commit Message Format

```
feat(PRD-001): add login form component

Implements requirement FR-003 from PRD-001.
Related: ADR-0003 (session storage decision)
```

### PR Title/Body Format

**Title**: `[PRD-001] Implement user authentication`

**Body**:
```markdown
## Summary
Implements user authentication as specified in PRD-001.

## Related Documents
- PRD-001: User Authentication
- ADR-0003: Database Choice
- PRP-002: OAuth Integration

## Closes
- Fixes #42
- Fixes #87
```

## Bidirectional Link Maintenance

### When Creating Links

1. **Document → GitHub Issue**
   - Add issue number to document's `github-issues` array
   - Add document ID to issue body (comment or edit)
   - Update manifest registry

2. **Document → Document**
   - Add target ID to source's `relates-to` array
   - Add source ID to target's `relates-to` array (bidirectional)
   - Update manifest registry

3. **PRP → PRD (implements)**
   - Add PRD ID to PRP's `implements` field
   - Add PRP ID to PRD's `implemented-by` tracking in manifest

### Link Validation

Check for broken links during `/blueprint:status`:

```bash
# Validate all links in manifest
validate_links() {
  local manifest="docs/blueprint/manifest.json"

  # Check each document exists
  jq -r '.id_registry.documents | to_entries[] | "\(.key) \(.value.path)"' "$manifest" | \
  while read id path; do
    if [ ! -f "$path" ]; then
      echo "BROKEN: $id -> $path (file missing)"
    fi
  done

  # Check GitHub issues exist (if gh available)
  if command -v gh &>/dev/null; then
    jq -r '.id_registry.github_issues | keys[]' "$manifest" | \
    while read issue; do
      if ! gh issue view "$issue" &>/dev/null; then
        echo "BROKEN: GitHub issue #$issue (not found or closed)"
      fi
    done
  fi
}
```

## Traceability Queries

`get_related` (all documents linked to an ID) and `get_implementation_chain` (PRD → PRPs → work-orders → GitHub issues): [references/traceability-queries.md](references/traceability-queries.md).

## Orphan Detection

`find_orphan_documents` (documents without GitHub issues) and `find_orphan_issues` (issues with no registry entry and no ID in the title): [references/orphan-and-duplicate-detection.md](references/orphan-and-duplicate-detection.md).

## Duplicate Detection

Before creating a GitHub issue, run `check_for_duplicates` from [references/orphan-and-duplicate-detection.md](references/orphan-and-duplicate-detection.md) against registry titles and open issues.

## Integration Points

### /blueprint:derive-plans (PRDs)

After creating PRD:
1. Generate `PRD-NNN` ID
2. Add to frontmatter
3. Update manifest registry
4. Prompt: "Create GitHub issue for tracking?"

### /blueprint:derive-plans (ADRs)

After creating ADR:
1. Extract `ADR-NNNN` from filename
2. Add to frontmatter (if missing)
3. Update manifest registry
4. Link to related PRDs if applicable

### /blueprint:prp-create

After creating PRP:
1. Generate `PRP-NNN` ID
2. Prompt: "Which PRD does this implement?"
3. Add `implements` field
4. Update manifest registry with bidirectional link

### /blueprint:work-order

After creating work-order:
1. Assign `WO-NNN` ID
2. Auto-link to source PRP/PRD
3. Create GitHub issue with ID in title
4. Update manifest registry

### /blueprint:status

Show traceability section:
```
Traceability:
- Documents: 15 total (3 PRDs, 5 ADRs, 7 PRPs)
- Linked to GitHub: 12/15 (80%)
- Orphan documents: 3 (PRD-002, ADR-0004, PRP-006)
- Orphan issues: 2 (#23, #45)
- Broken links: 0
```

## Quick Reference

| Operation | Command |
|-----------|---------|
| Assign IDs to all docs | `/blueprint:sync-ids` |
| Link doc to issue | Update `github-issues` in frontmatter |
| Link doc to doc | Update `relates-to` in frontmatter |
| View traceability | `/blueprint:status` |
| Find orphans | `/blueprint:status` (included) |

| GitHub Format | Example |
|---------------|---------|
| Issue title | `[PRD-001] Feature name` |
| Commit scope | `feat(PRD-001): description` |
| PR reference | `Implements PRD-001, Fixes #42` |
