Files
itpp-infrastructure/docs/git-docs-as-code-plan.md

17 KiB

ITPP Git Environment Restructuring Plan — Docs-as-Code

Author: Sho'Nuff (Hermes Agent) Date: August 10, 2026 Status: Draft — awaiting Germaine review Gitea Instance: git.itpropartner.com (app2, Docker, Gitea 1.22.6)


1. Repository Structure: Multi-Repo, Docs Beside Code

Decision: Multi-repo with docs alongside code. No monorepo for docs.

Rationale (for a solo dev with AI assistance)

Factor Multi-Repo Monorepo
Repo boundaries (Germaine's preference) Clean — one project, one repo Muddy — all docs in one bucket
AI agent context Small repos = small diffs, fast clones 50+ projects in one tree = huge context
Docs discoverability README in every repo, Gitea UI browses repos Single search but heavy
CI/CD simplicity Per-repo Gitea Actions One giant pipeline filtering paths
Cross-linking ⚠️ Need explicit links between repos Internal links stay in-repo
Gitea migration Already 43 separate repos Would require consolidation

Winner: Multi-repo. Germaine's existing repo boundaries are already clean (itpp-infrastructure ≠ homelab ≠ transitpin). We build on that, not against it.

Where Docs Live Per Repo

Every repo follows this structure (minimally):

<repo-root>/
├── README.md          # What, why, how to use it
├── CHANGELOG.md       # Reverse-chronological change log
├── docs/              # Extended documentation (optional, for complex projects)
│   ├── architecture.md
│   ├── decisions.md
│   └── ...
├── .gitea/            # Gitea-specific config (templates, CI)
│   └── workflows/     # Gitea Actions CI/CD
└── src/ or code/      # Actual code/assets (project-specific)

Key rule: Docs live in the same repo as the code they describe. Infrastructure docs live in itpp-infrastructure. Home lab docs live in homelab. TransitPin docs live in transitpin.

Exceptions

  • Cross-cutting infrastructure docs (server inventory, DNS records, backup plan) → itpp-infrastructure repo (already correct)
  • Cross-project ADRs (Architecture Decision Records) → each project's own docs/decisions.md
  • Shared templates/standards → a new itpp-standards repo (see Section 5)

2. Documentation Standards Per Repo

2.1 README.md — Mandatory, Every Repo

Goal: Someone reads this in 60 seconds and knows what the project is, whether it's live, how to reach it, and where credentials live.

# <Project Name>

> **Owner:** Germaine | **Status:** LIVE / DEV / PLANNED
> **Last Updated:** YYYY-MM-DD

<One-paragraph summary of what this project does and why it exists.>

## Access

| Resource | URL | Location | Notes |
|---|---|---|---|
| <service name> | https://... | <server> | <how to auth> |

## Tech Stack

<Bullet list: Python 3.11, FastAPI, SQLite, Docker, etc.>

## Quick Start

```bash
git clone https://git.itpropartner.com/ippadmin/<repo>.git
cd <repo>
# how to run / deploy

**Minimum byte check:** README under 400 bytes is a stub — counts as MISSING in audits. The `project-documentation` skill already enforces this.

### 2.2 CHANGELOG.md — Mandatory, Every Repo

```markdown
# <Project Name> — CHANGELOG

## YYYY-MM-DD — <Short Title>

- **Category** (Added/Fixed/Changed/Removed): what changed and what the user sees
- User-facing, not commit-log style
- One-line per change, reverse chronological

## YYYY-MM-DD — Initial

- Created project repository.

Rule: CHANGELOG entries happen INLINE with work, not as a post-hoc catch-up. The project-documentation skill standing order already enforces this. Also: no em dashes, no smart quotes — plain ASCII.

2.3 DESIGN.md — When Needed

Create docs/design.md when:

  • The project has a public API or library interface
  • There are multiple consumers of the code
  • Design decisions affect how others build on it

Content: token/schema specs, API surface, data models, integration points. Follow the Google DESIGN.md convention (see design-md skill).

2.4 Additional Docs — As Appropriate

File When Lives In
docs/architecture.md Multi-server, multi-service, or complex data flows Repo root
docs/decisions.md Key technology/architecture choices made (ADR format) Repo root
docs/roadmap.md Active development, planned features Repo root
docs/glossary.md Domain-heavy (legal, ISP, medical terms) Repo root
ROADMAP.md Same, but for user-facing product repos Repo root

These match the project-documentation skill standard. No new convention — just consistent application.


3. Static Site Generation for Docs

Decision: MkDocs (Material theme)

Tool Pros Cons Verdict
MkDocs + Material Python (matches ITPP stack), simple config, fast build, excellent search, dark mode built-in Less flexible than Docusaurus for React-heavy sites Best fit
Docusaurus React-based, MDX support, versioning Node.js toolchain, heavier, overkill for solo-dev docs Over-engineered
Sphinx Python, rST native rST is painful for casual docs, less pretty out of box Not for Markdown-first workflow
Just Gitea Zero setup, docs render in Gitea UI No cross-repo search, no TOC, no branding ⚠️ Works but limited

How It Works

ONE MkDocs site that aggregates docs from ALL repos. Not one site per repo — too many to maintain.

docs.itpropartner.com  (hosted on app3 via CloudPanel/nginx)
  ├── Infrastructure/   → itpp-infrastructure repo docs
  ├── Home Lab/         → homelab repo docs  
  ├── TransitPin/       → transitpin repo docs
  ├── FleetTracker360/  → fleettracker360 repo docs
  ├── Shark Game/       → shark-game repo docs
  ├── VerdictTank/      → verdicttank repo docs
  ├── Scripts/          → scripts repo README
  └── Standards/        → itpp-standards repo

Implementation

  1. Create a new repo: itpp-docs on git.itpropartner.com
  2. MkDocs config (mkdocs.yml) with nav pointing to subdirectories
  3. Build script (build-docs.sh): clones/fetches each repo, copies docs/ folders into MkDocs source tree, runs mkdocs build
  4. Deploy: Output is static HTML. Nginx on app3 serves docs.itpropartner.com pointing to the build directory
  5. CI/CD: Gitea Actions workflow in itpp-docs repo triggers rebuild on push to any tracked repo (or nightly)

Why not per-project MkDocs sites? Germaine has ~43 repos. Managing 43 separate MkDocs configs + 43 nginx vhosts is maintenance overhead with zero benefit for a solo dev. One aggregated site with sections per project is the pragmatic choice.

Alternative: Gitea's Built-in Rendering

Gitea already renders Markdown READMEs, CHANGELOGs, and any .md file in the repo tree. For a solo dev, this is actually 80% of the value. The docs.itpropartner.com MkDocs site is the polish layer — cross-project search, consistent branding, a single URL to share.

Phase 1: Ensure every repo has complete Markdown docs (READMEd, CHANGELOG, etc.) — these render in Gitea immediately. Phase 2: Build the aggregated MkDocs site.


4. CI/CD Pipeline — Gitea Actions

Gitea 1.22.6 supports Gitea Actions (GitHub Actions-compatible). The runner must be registered on a server that can reach the repos.

4.1 Gitea Actions Runner Setup

Deploy a Gitea Actions runner on Core (152.53.192.33) — it already has Python, Node.js, and access to all repos:

# On Core
# 1. Download act_runner binary
# 2. Register with git.itpropartner.com token
# 3. Run as systemd service

See gitea-deployment skill for the runner setup pattern (used for modelortho instance).

File: .gitea/workflows/docs-check.yml (template, deployed to every repo)

name: Docs Check
on:
  push:
    paths:
      - '**.md'
      - 'docs/**'
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Markdown lint
        run: |
          npm install -g markdownlint-cli
          markdownlint '**/*.md' --ignore node_modules
      - name: Link check
        run: |
          npm install -g markdown-link-check
          find . -name '*.md' -not -path '*/node_modules/*' \
            -exec markdown-link-check {} \;
      - name: Spell check (optional)
        run: |
          pip install codespell
          codespell '**/*.md' --skip='*.git*'

4.3 Workflow: Docs Publish (aggregated site)

File: .gitea/workflows/docs-publish.yml in the itpp-docs repo only

name: Publish Docs Site
on:
  push:
    branches: [main]
  schedule:
    - cron: '0 5 * * *'  # nightly rebuild at 5 AM

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build MkDocs site
        run: |
          pip install mkdocs mkdocs-material
          bash build-docs.sh
          mkdocs build
      - name: Deploy to app3
        run: |
          rsync -avz site/ root@152.53.241.111:/var/www/docs.itpropartner.com/

4.4 What Gets Checked

  • Every push to any .md file: lint + link check via per-repo workflow
  • PR merge on itpp-docs: rebuild + deploy aggregated site
  • Nightly: full rebuild of aggregated site (catches stale links across repos)

5. Template Repos & Starter Kits

5.1 itpp-standards — The Canonical Template Repo

A new repo at git.itpropartner.com/ippadmin/itpp-standards.git containing:

itpp-standards/
├── README.md                 # What this is, how to use
├── CHANGELOG.md
├── templates/
│   ├── repo-readme.md        # README.md template (copy-paste, fill blanks)
│   ├── repo-changelog.md     # CHANGELOG.md starter
│   ├── design-template.md    # DESIGN.md template
│   ├── mkdocs.yml            # MkDocs config template
│   └── gitea-ci/
│       ├── docs-check.yml    # Lint + link check workflow
│       └── docs-publish.yml  # Aggregated site rebuild
├── .gitea/
│   └── workflows/
│       └── docs-check.yml    # Self-checking
├── .gitignore
└── .markdownlint.json        # Lint rules

5.2 Gitea Repo Templates

Gitea supports repo templates — mark itpp-standards as a template in the Gitea UI. When creating a new repo, select "From Template: itpp-standards" and it clones the structure.

5.3 New Project Bootstrap Script

A script at /root/.hermes/scripts/new-project.sh that:

  1. Creates the Gitea repo via API (from template)
  2. Clones to /root/projects/<name>/
  3. Replaces {{PROJECT_NAME}} placeholders in README template
  4. Creates LiteLLM virtual key on admin-ai
  5. Commits and pushes
# Usage
new-project.sh transitpin "School bus GPS tracking portal"

5.4 .gitignore Standard

Every repo gets:

# OS
.DS_Store
Thumbs.db

# Editor
.vscode/
.idea/
*.swp
*.swo

# Secrets
.env
*.pem
*.key
credentials.json

# Python
__pycache__/
*.pyc
.venv/
venv/

# Node
node_modules/

# Build output
dist/
build/
site/

6. Migration Path

Phase 0: Foundation (Week 1)

No repo changes yet. Set up the infrastructure:

  1. Create itpp-standards repo with templates and CI workflows
  2. Create itpp-docs repo with MkDocs skeleton
  3. Deploy Gitea Actions runner on Core
  4. Mark itpp-standards as template repo in Gitea UI
  5. Write new-project.sh bootstrap script

Phase 1: Git-ify All Projects (Week 1-2)

Goal: Zero non-Git projects under /root/projects/.

Current gap: 19 projects without .git/ directories (transitpin, forefront-broadband-map, diglocate, giftaroast, mautic-multitenant, twilio-10dlc, village-express, etc.).

For each non-Git project:

cd /root/projects/<name>
git init -b main
# Copy in .gitignore from itpp-standards template
git add -A
git commit -m "Initial: migrate to Git"
git remote add origin https://ippadmin:<token>@git.itpropartner.com/ippadmin/<name>.git
git push -u origin main

Priority order:

  1. Active projects first: transitpin (12 files, active development) → forefront-wireless-portal → giftaroast → ...
  2. Planning/research: diglocate, mautic-multitenant, obsidian-selfhost, paperless-ngx
  3. Stubs/minimal: competitive-analysis, mcp-planning, udm-tailscale

Phase 2: Standardize Existing Repos (Week 2-3)

Goal: Every repo has a real README (not stub) + CHANGELOG + .gitea/workflows/docs-check.yml.

Step 1 — Audit: Already done (see data above). Key gaps:

  • Zero/missing READMEs: apex-track (75B), boxpilot (73B), osint-tool (75B), launchcheck (189B), super-search-business (205B), cartmylist-repo (MISSING), org-audit (MISSING)
  • No CHANGELOG in many repos
  • master branch on org-audit → rename to main

Step 2 — Batch fix: For each repo with stub/missing README:

  1. Read existing files to understand what the project does
  2. Write proper README following the template
  3. Add CHANGELOG.md with initial entry
  4. Add .gitea/workflows/docs-check.yml
  5. Commit and push

Step 3 — Branch consistency: Rename org-audit from master to main.

Phase 3: Aggregated Docs Site (Week 3-4)

Goal: docs.itpropartner.com live with all project docs.

  1. Build the MkDocs config in itpp-docs repo
  2. Write build-docs.sh that pulls from each repo
  3. Configure Gitea Actions to build + deploy to app3
  4. Set up nginx vhost on app3 for docs.itpropartner.com
  5. DNS: add docs.itpropartner.com A record → 152.53.241.111 (or CNAME via Cloudflare if proxied)
  6. Test: manual push to any repo → docs site updates within minutes

Phase 4: Ongoing (Continuous)

  • New projects bootstrap from itpp-standards template
  • new-project.sh automates the whole flow
  • Docs-check CI catches broken links on every push
  • Nightly rebuild keeps aggregated site current

7. git.modelortho.com — Anita's Instance

Decision: Same Standards, Separate Instance

Rationale:

  • git.modelortho.com is on app3 (152.53.241.111), separate Gitea binary + SQLite DB
  • It's Anita's domain — ModelOrtho branding, Anita's repos
  • It's behind Cloudflare proxy (verified: CF-Ray in response headers)
  • Germaine manages it technically but Anita owns the content

What to Standardize

Standard git.itpropartner.com git.modelortho.com
README template Required Same template (ModelOrtho-branded)
CHANGELOG format Required Same format
CI/CD linting Gitea Actions Same workflows (copy from itpp-standards)
MkDocs site docs.itpropartner.com Separate: docs.modelortho.com (optional)
Template repo itpp-standards Copy itpp-standards as modelortho-standards
Token auth HTTPS + token Same pattern

What's Separate

  • Gitea instance: Separate binary, DB, systemd unit (gitea.modelortho)
  • Users: Anita has her own account (not ippadmin)
  • Domain: git.modelortho.com — Cloudflare-proxied to app3
  • Docs site: docs.modelortho.com (optional, separate MkDocs instance or same build script with different output)
  • Backup: Included in app3 backup standard, separate from git.itpropartner.com on app2

Immediate Actions for modelortho

  1. Create modelortho-standards repo on git.modelortho.com (copy from itpp-standards, swap branding)
  2. Install Gitea Actions runner for modelortho (or share the Core runner with different registration)
  3. Create Anita's user account with admin privileges
  4. Set up first ModelOrtho project as template demo

8. Summary: Before/After

Dimension Current State Target State
Repos in Git 43 of 62 projects in Git 100% of projects in Git
README quality 8 stubs (< 400B), 7 MISSING Every repo has a real README
CHANGELOG Inconsistent Every repo has CHANGELOG.md
CI/CD None Docs lint + link check on every push
Docs site None — read individual Gitea repos docs.itpropartner.com aggregating all
New project bootstrap Manual mkdir + git init new-project.sh from template
modelortho Fresh deploy, no repos Standards repo + Anita onboarded
Branch standard 42 main, 1 master All main

9. Priority Order (What to Do First)

  1. Create itpp-standards repo — this is the foundation everything else builds on (30 min)
  2. Git-ify transitpin — it's active, has 12 files, no git history (10 min)
  3. Deploy Gitea Actions runner — enables CI/CD for all subsequent work (30 min)
  4. Fix stub READMEs in active repos — apex-track, boxpilot, osint-tool, launchcheck (30 min)
  5. Create itpp-docs repo with MkDocs skeleton (1 hr)
  6. Onboard Anita on git.modelortho.com — create standards repo, user account (30 min)

Total Phase 1 estimated effort: ~3 hours for Germaine + AI assistance.