Phase 01: Hub Repository

Phase 1: Create the Hub Repository

The hub is a lightweight orchestrator — it does NOT contain documentation content. It defines where to find content (spoke repos), how to build it (playbook), and what entry point to show (landing page). Everything else lives in spokes.

Architecture Decision: Hub vs Spoke Responsibilities

Layer Hub (team-docs) Spoke (infra-docs, nac-docs, etc.)

Content

Landing page + cross-component navigation only

All technical documentation — runbooks, architecture, reference

Attributes

Global only: company name, team email, domain, infrastructure versions

Self-contained: every IP, hostname, VLAN, port, path the spoke references

Navigation

Links TO spokes (cross-component xrefs)

Internal nav for its own pages

Build

Owns the playbook, Makefile, build.sh, CI/CD

None — built by the hub

Deployment

Owns the output directory and deployment target

Pushes content to Git — hub pulls it at build time

Step 1: Initialize the Repo

mkdir team-docs && cd team-docs
git init
mkdir -p docs/modules/ROOT/pages

Step 2: Create the Playbook

This is the heart of the system. Every spoke, every extension, every build option is controlled here.

File: antora-playbook.yml

# ============================================================================
# Team Documentation — Antora Playbook
# ============================================================================
# Central orchestration for all documentation components.
#
# Components:
#   - home: Landing page (this repo)
#   - infra-ops: Infrastructure operations
#   - nac-ops: NAC/ISE operations
#   (add more as you create spoke repos)
#
# Usage:
#   npx antora antora-playbook.yml
#   make
#
# Maintainer: Network Engineering
# ============================================================================

site:
  title: Network Engineering Documentation
  url: https://docs.internal.example.com  # Replace with your site URL
  start_page: home::index.adoc

content:
  sources:
    # ──────────────────────────────────────────────────────────────
    # HUB (this repo) — landing pages and cross-component nav
    # ──────────────────────────────────────────────────────────────
    - url: .
      branches: HEAD
      start_path: docs
      edit_url: false

    # ──────────────────────────────────────────────────────────────
    # SPOKE REPOS — one per documentation domain
    # start_path: docs/asciidoc for full technical spokes
    # start_path: docs for lightweight/narrative spokes
    # ──────────────────────────────────────────────────────────────

    # Infrastructure Operations
    - url: https://github.com/your-org/infra-docs
      branches: main
      start_path: docs/asciidoc
      edit_url: false

    # NAC/ISE Operations (uncomment when ready)
    # - url: https://github.com/your-org/nac-docs
    #   branches: main
    #   start_path: docs/asciidoc
    #   edit_url: false

    # ──────────────────────────────────────────────────────────────
    # LOCAL DEVELOPMENT — uncomment for local builds
    # ──────────────────────────────────────────────────────────────
    # - url: ../infra-docs
    #   branches: HEAD
    #   start_path: docs/asciidoc

ui:
  bundle:
    # Default Antora UI (replace with custom bundle when ready)
    url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/HEAD/raw/build/ui-bundle.zip?job=bundle-stable
    snapshot: true

antora:
  extensions:
    # Full-text search (optional — add @antora/lunr-extension to package.json)
    # - require: "@antora/lunr-extension"
    #   index_latest_only: true
    #   languages: [en]

asciidoc:
  attributes:
    # Suppress warnings for intentional placeholders
    attribute-missing: skip
    # Global attributes (available to ALL components)
    page-pagination: ""
    hide-uri-scheme: ""
    # Diagram server (uncomment when using Kroki)
    # kroki-server-url: https://kroki.io
    # kroki-fetch-diagram: true
  # Extensions (uncomment as needed)
  # extensions:
  #   - "@asciidoctor/tabs"
  #   - "asciidoctor-kroki"

output:
  dir: ./build/site
  clean: true

runtime:
  fetch: true
  cache_dir: .cache/antora

Key decisions in this playbook:

  • start_path: docs/asciidoc for technical spokes (the pattern from domus-infra-ops) — gives room for the asciidoc module structure within a broader docs/ directory

  • start_path: docs for the hub and any lightweight/narrative spokes

  • edit_url: false — disable "Edit this page" links (internal docs, not open source)

  • runtime.fetch: true — fetch remote repos at build time (required for GitHub URLs)

Step 3: Create the Hub Component Descriptor

File: docs/antora.yml

name: home
title: Network Engineering
version: ~
start_page: ROOT:index.adoc
nav:
  - modules/ROOT/nav.adoc
asciidoc:
  attributes:
    # Global infrastructure versions (shared across all spokes)
    company-name: CHLA
    team-name: Network Engineering
    domain: corp.example.com
    ise-version: '3.3'
    # Add versions and global constants here
    # Spokes inherit these but can override

The hub’s antora.yml is intentionally minimal. 14 attributes, not 200. Global values only — versions, domains, team identifiers. Spoke-specific data (IPs, hostnames, VLANs) belongs in each spoke’s own antora.yml.

Step 4: Create the Hub Landing Page

File: docs/modules/ROOT/pages/index.adoc

= Network Engineering Documentation
:description: Central documentation hub — runbooks, architecture, operations
:icons: font

Documentation system for the network engineering team.

== Components

[cols="2,3,1"]
|===
| Component | Description | Pages

| xref:infra-ops::index.adoc[Infrastructure Operations]
| Runbooks, architecture, validated designs, reference tables
| TBD

| NAC/ISE Operations _(coming soon)_
| 802.1X, profiling, policy sets, dACLs, RADIUS
| —

| Automation _(coming soon)_
| Scripts, Ansible playbooks, API documentation
| —
|===

== Quick Links

* xref:infra-ops::runbooks/index.adoc[All Runbooks]
* xref:infra-ops::reference/vlan-table.adoc[VLAN Reference]

The hub links TO spokes. It doesn’t duplicate their content.

Step 5: Create the Hub Navigation

File: docs/modules/ROOT/nav.adoc

* xref:index.adoc[Home]
* .Infrastructure
** xref:infra-ops::index.adoc[Operations Hub]
** xref:infra-ops::runbooks/index.adoc[Runbooks]
** xref:infra-ops::architecture/index.adoc[Architecture]
* .NAC & ISE
** _Coming soon_
* .Automation
** _Coming soon_

The . prefix creates collapsible sections in the Antora sidebar.

Step 6: Create the Makefile

File: Makefile

.PHONY: all serve clean check

# Build the site
all:
	npx antora antora-playbook.yml

# Build and serve locally
serve: all
	@echo "Serving at http://localhost:8080"
	npx http-server build/site -p 8080

# Check for build warnings
check:
	@npx antora antora-playbook.yml 2>&1 | grep -E "WARN|ERROR" || echo "Build clean — no warnings"

# Clean build artifacts
clean:
	rm -rf build .cache

Step 7: Create .gitignore

File: .gitignore

build/
.cache/
node_modules/
package-lock.json

Step 8: Test the Build

npx antora antora-playbook.yml
make check
# Open build/site/index.html

Directory Structure After Phase 1

team-docs/
├── antora-playbook.yml         # THE PLAYBOOK — heart of the system
├── Makefile                    # make, make serve, make check, make clean
├── .gitignore
└── docs/
    ├── antora.yml              # Hub component: name=home, global attributes
    └── modules/ROOT/
        ├── nav.adoc            # Cross-component navigation
        └── pages/
            └── index.adoc      # Landing page with component table