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

484 lines
17 KiB
Markdown

# 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.
```markdown
# <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
```
## Related
- [itpp-infrastructure](https://git.itpropartner.com/ippadmin/itpp-infrastructure) — server inventory, DNS
- [<other related repo>](https://git.itpropartner.com/ippadmin/<repo>)
```
**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:
```bash
# 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).
### 4.2 Workflow: Docs Lint & Link Check
File: `.gitea/workflows/docs-check.yml` (template, deployed to every repo)
```yaml
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
```yaml
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
```bash
# Usage
new-project.sh transitpin "School bus GPS tracking portal"
```
### 5.4 `.gitignore` Standard
Every repo gets:
```gitignore
# 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:
```bash
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.