Antora Cross-Reference Maintenance

1. Overview

This runbook documents the cross-reference (xref) rules for the domus-* documentation ecosystem and provides procedures for auditing, fixing, and verifying xref compliance.

The Golden Rule:

Cross-component xrefs (`xref:component::path.adoc[`]) only work when building through the hub (domus-docs). Spoke repos building standalone will FAIL.

2. Architecture Mental Model

Antora Xref Hub-Spoke Model

2.1. Build Contexts

Context What’s Available Xref Behavior

Hub build (domus-docs)

All 14 components loaded

`xref:infra-ops::runbooks/file.adoc[`] resolves ✓

Spoke standalone (make serve)

Only that component

`xref:infra-ops::...` has nothing to resolve to ✗

3. The Rules

3.1. Rule 1: No Cross-Component Xrefs in Spokes

Location Allowed Xrefs

Hub (domus-docs)

`xref:component::path.adoc[Label`] ✓

Spoke (all other domus-*)

Same-component only: `xref:path.adoc[Label`] ✓

3.2. Rule 2: Plain Text for Cross-Component References

In spoke repos, reference other components as plain text:

WRONG (spoke repo)
* xref:infra-ops::runbooks/backup-strategy.adoc[Backup Strategy]
CORRECT (spoke repo)
* Backup Strategy (infra-ops)

3.3. Rule 3: Exceptions That Look Like Violations

These are NOT violations:

Pattern Why It’s OK

Inside [source,…​] blocks

Code examples, not processed

Inside macro

Escaped, renders as literal text

Commented with //

Not processed

In _drafts/ directory

Not published

4. Audit Procedure

4.1. Step 1: Scan All Repos

# Run from atelier/_bibliotheca/
for repo in domus-automation-ops domus-captures domus-identity-ops domus-infra-ops \
            domus-ise-linux domus-ise-ops domus-ise-windows domus-linux-ops \
            domus-netapi-docs domus-o11y-ops domus-python domus-secrets-ops \
            domus-siem-ops domus-windows-ops; do
  REPO_PATH="/home/evanusmodestus/atelier/_bibliotheca/$repo"
  count=$(grep -rn 'xref:[a-z-]*::' "$REPO_PATH/docs" 2>/dev/null \
    | grep -v '/build/' \
    | grep -v '/_drafts/' \
    | grep -v 'template.adoc' \
    | grep -v 'antora-xref-guide' \
    | grep -v 'antora-architecture' \
    | grep -v 'antora-troubleshooting' \
    | grep -v 'docs-as-code' \
    | wc -l)
  if [ "$count" -gt 0 ]; then
    echo "$repo: $count potential violations"
  fi
done

4.2. Step 2: Inspect Violations

# For a specific repo, show actual violations
grep -rn 'xref:[a-z-]*::' /path/to/repo/docs \
  | grep -v '/build/' \
  | grep -v '/_drafts/' \
  | grep -v 'template.adoc'

4.3. Step 3: Filter False Positives

Check if matches are inside code blocks:

# Check context around line 91 of a file
awk 'NR>=88 && NR<=95' /path/to/file.adoc

If you see [source,…​] or ---- delimiters, it’s an example, not a violation.

5. Fix Procedure

5.1. Single File Fix

# Preview what will change
sed -n 's|xref:infra-ops::runbooks/backup-strategy.adoc\[Backup Strategy\]|Backup Strategy (infra-ops)|gp' file.adoc

# Apply fix
sed -i 's|xref:infra-ops::runbooks/backup-strategy.adoc\[Backup Strategy\]|Backup Strategy (infra-ops)|g' file.adoc

5.2. Batch Fix Pattern

# Fix all .adoc files in a directory
find /path/to/repo/docs -name "*.adoc" -type f -exec sed -i \
  -e 's|xref:infra-ops::index.adoc\[Infrastructure Ops\]|Infrastructure Ops (infra-ops)|g' \
  -e 's|xref:ise-linux::index.adoc\[ISE Linux\]|ISE Linux (ise-linux)|g' \
  -e 's|xref:linux-ops::index.adoc\[Linux Operations\]|Linux Operations (linux-ops)|g' \
  {} \;

5.3. Common Replacements

Original Replacement

`xref:infra-ops::index.adoc[Infrastructure Ops]`

Infrastructure Ops (infra-ops)

`xref:ise-linux::index.adoc[ISE Linux]`

ISE Linux (ise-linux)

`xref:linux-ops::index.adoc[Linux Operations]`

Linux Operations (linux-ops)

`xref:netapi::index.adoc[netapi CLI]`

netapi CLI (netapi-docs)

`xref:identity-ops::index.adoc[Identity Ops]`

Identity Ops (identity-ops)

`xref:secrets-ops::index.adoc[Secrets Ops]`

Secrets Ops (secrets-ops)

6. Commit and Push

6.1. Commit Pattern

git -C /path/to/repo add -A
git -C /path/to/repo commit -m "fix(xref): Convert cross-component xrefs to plain text"

6.2. Push All Repos

for repo in domus-automation-ops domus-ise-ops domus-secrets-ops; do
  SSH_AUTH_SOCK=/run/user/1000/ssh-agent.socket \
    git -C "/home/evanusmodestus/atelier/_bibliotheca/$repo" push origin main
done

7. Verify Build

7.1. Local Build (Hub)

cd /home/evanusmodestus/atelier/_bibliotheca/domus-docs
make

Watch for:

[ERROR] target of xref not found: component::path.adoc

7.2. Check Deployments

# List recent Cloudflare Pages deployments
CLOUDFLARE_ACCOUNT_ID=7f6981e005108a7a90b03ec3ff4b5197 \
  wrangler pages deployment list --project-name=domus-docs

Expected output shows: - Environment: Production - Branch: main - Source: commit hash matching your push - Status: timestamp showing recent deployment

8. Changelog

When fixing xrefs across repos, document in changelog:

changelog/YYYY-MM-DD-xref-fixes.adoc
= YYYY-MM-DD - Cross-Component Xref Fixes

== Summary
Fixed N cross-component xref violations across M spoke repos.

== Repos Fixed
* domus-automation-ops: N violations
* domus-ise-ops: N violations
...

== Pattern Applied
Converted `xref:component::path.adoc[Label]` to `Label (component)`

9. Quick Reference

Task Command

Scan all repos

for repo in domus-; do grep -rn 'xref:[a-z-]::' …​

Fix single xref

sed -i 's|xref:comp::path\[Label\]|Label (comp)|g' file

Commit fix

git commit -m "fix(xref): Convert cross-component xrefs to plain text"

Check deployments

wrangler pages deployment list --project-name=domus-docs

Local build

cd domus-docs && make

10. Troubleshooting

10.1. "target of xref not found" Error

Cause: Cross-component xref in spoke repo

Fix: Convert to plain text reference

10.2. Build Succeeds Locally, Fails in CI

Cause: Local build might use cached components

Fix: Clean build: make clean && make

10.3. Deployment Not Triggering

Cause: GitHub webhook not firing

Fix: 1. Check repo Settings > Webhooks 2. Manual trigger: push empty commit

+

git commit --allow-empty -m "chore: Trigger rebuild"
git push