diff --git a/docs/git-audit-2026-08-08.md b/docs/git-audit-2026-08-08.md new file mode 100644 index 0000000..e7b0d59 --- /dev/null +++ b/docs/git-audit-2026-08-08.md @@ -0,0 +1,364 @@ +# Git Audit Report — IT Pro Partner Gitea Organization + +**Date:** 2026-08-08 +**Auditor:** Hermes Agent (automated) +**Scope:** git.itpropartner.com / ippadmin (all 42 remote repos + 59 local clones in `/root/projects/`) + +--- + +## Summary Verdict + +**The Gitea organization suffers from repo sprawl, weak hygiene, and live secrets in history.** Of 42 remote repos, 32 are single-commit documentation stubs. Only 3–4 repos show active development. The `itpp-infrastructure/docs/` folder is a flat grab-bag and needs structured nesting. 23 local-only repos lack any off-server backup. Credentials are embedded in plaintext across at least 2 repos (`scripts`, `hermes-recovery`). Consolidation, cleanup, and a hygiene push are overdue. + +--- + +## Quick Answers to User's Two Questions + +### 1. Should `itpp-infrastructure/docs/` have more nested folders? + +**Yes, absolutely.** The current structure is: + +``` +docs/ + backup-restore/ ← already nested (good) + legal/ ← already nested (good) + ops-portal/ ← already nested (good) + app2-caddyfile-audit-2026-07-21.md ← flat + client-katie-watts-design.md ← flat + cost-control-rollout-2026-07-24.md ← flat + git-audit-2026-08-07.md ← flat + infrastructure-gap-assessment-2026-08-04.md ← flat + key-inventory.md ← flat + mattermost-replacement-analysis.md ← flat + model-chain.md ← flat + project-log.md ← flat + projects-master-readme.md ← flat + super-search-cf-bypass.md ← flat + super-search-enhancement-plan.md ← flat + uptime-kuma-monitoring-plan.md ← flat +``` + +**14 flat files is too many.** Recommended restructuring: + +``` +docs/ + audit/ ← git-audit reports, gap assessments + backup-restore/ ← (existing, keep) + clients/ ← client-katie-watts-design.md + infrastructure/ ← model-chain.md, cost-control-rollout, caddyfile-audit, key-inventory + legal/ ← (existing, keep) + monitoring/ ← uptime-kuma-monitoring-plan.md + ops-portal/ ← (existing, keep) + projects/ ← project-log.md, projects-master-readme.md + super-search/ ← cf-bypass, enhancement-plan + mattermost-replacement-analysis.md ← leave at top level (one-off) +``` + +This gives every file a clear home without over-nesting. + +### 2. Are there too many top-level repos? Should they be consolidated? + +**Yes — 42 repos is far too many for the actual workload.** Here's the breakdown: + +| Category | Count | Action | +|----------|-------|--------| +| Active development repos | 3–4 | Keep (`itpp-infrastructure`, `hermes-skills`, `scripts`, `homelab`) | +| Single-commit documentation stubs | 32 | Consolidate into fewer repos | +| Empty repos | 1 | Delete (`auth` — no commits, no content) | +| MCP stub repos | 5 | Merge into one `mcp-catalog` repo | +| Duplicate/stale repos | 2 | Resolve (`itpp-infra` vs `itpp-infrastructure`, `cartmylist-repo` vs `cartmylist`) | +| Local-only (unbacked) | 23 | Push to Gitea or archive | + +**Recommended consolidation:** + +1. **Merge 4 MCP stubs** (`mcp-browser`, `mcp-email`, `mcp-filesystem`, `mcp-git`) into `mcp-servers/` as subdirectories +2. **Merge related business ideas** into a `project-ideas` monorepo: + - `apex-track`, `boxpilot`, `digital-signage`, `fleettracker360`, `gift-a-roast`, `hudu`, `launchcheck`, `mooresunnydaze`, `nvr-shield`, `osint-tool`, `shark-game`, `startup-studio`, `track-a-flock`, `personal-assistant` +3. **Merge related operational repos**: `disaster-recovery` + `backup-restore` → `disaster-recovery/` with `backup-restore/` subdir +4. **Merge website/docs stubs**: `itpropartner-website`, `content-creation-pipeline`, `ops-portal` → subdirectories in `itpp-infrastructure` +5. **Resolve** `itpp-infra` (stale, SSH-only, 1 commit) → archive; use `itpp-infrastructure` as primary +6. **Delete** `auth` (empty repo with `auth.db` — never committed) +7. **Keep as-is**: `itpp-infrastructure`, `hermes-skills`, `hermes-recovery`, `scripts`, `homelab`, `dre`, `verdicttank`, `voipsimplicity`, `voipsimplicity-manual`, `forefront-wireless-portal`, `super-search-business`, `model-fallback`, `unifi`, `unms`, `pipeline`, `super-search` + +**Target:** ~15–20 repos instead of 42. + +--- + +## Detailed Findings + +### Step 1 — Full Inventory + +| Metric | Count | +|--------|-------| +| Remote repos on Gitea | 42 | +| Local clones in `/root/projects/` | 59 | +| On Gitea AND cloned locally | 36 | +| On Gitea but NOT cloned locally | 6 | +| Cloned locally but NOT on Gitea | 23 | +| Public repos | 30 | +| Private repos | 12 | +| Repos using `master` as default branch | 30 | +| Repos using `main` as default branch | 9 | +| Other (HEAD/detached) | 20 | + +**Repos on Gitea but not cloned locally:** `cartmylist`, `mcp-browser`, `mcp-email`, `mcp-filesystem`, `mcp-git`, `super-search` + +**Local-only repos (no remote — no off-server backup):** `assistant`, `auth`, `capabilities`, `hear-read`, `intelsight`, `intelsight-landing`, `internal`, `mockup`, `my-itpropartner-portal`, `ops`, `ops-v2-portal`, `osint`, `proposals`, `pry`, `research-search-mcp`, `schedule`, `shonuff`, `shonuff-caller`, `static`, `status`, `voice-previews`, `itpp-infra`, `cartmylist-repo` + +### Step 2 — Per-Repo Deep Scan + +#### Hygiene Check: `.gitignore` and `README.md` + +| Status | Count | +|--------|-------| +| Has `.gitignore` | 8 of 59 (13.6%) | +| Has `README.md` | 56 of 59 (94.9%) | + +**Repos missing `.gitignore`:** 51 repos. This is the single biggest hygiene gap. + +**Repos missing `README.md`:** `cartmylist-repo`, `voipsimplicity-manual`, `auth` + +#### Repos with Dirty Working Trees + +| Repo | Dirty Files | Severity | +|------|-------------|----------| +| `hermes-skills` | 33 | **HIGH** — cache artifacts not committed | +| `hermes-recovery` | 26 | **HIGH** — uncommitted recovery scripts | +| `voipsimplicity-manual` | 11 | **MEDIUM** | +| `research-search-mcp` | 10 | **MEDIUM** | +| `auth` | 9 | **MEDIUM** | +| `digital-signage` | 6 | **LOW** | +| `itpp-infra` | 5 | **LOW** | +| `pipeline` | 5 | **LOW** | +| `disaster-recovery` | 4 | **LOW** | +| `mooresunnydaze` | 4 | **LOW** | +| `verdicttank` | 4 | **LOW** | +| `itpp-infrastructure` | 3 | **LOW** | + +**13 repos** have uncommitted changes. `hermes-skills` (33 files) and `hermes-recovery` (26 files) are the worst offenders. + +### Step 3 — Secrets Scan + +**CRITICAL findings in 2 repos:** + +#### `scripts` — 10 potential secrets +Real, hardcoded credentials found in Windows provisioning scripts: +``` ++Password="LoveMyBoys73!" ++Password="Liberty4All!" ++Password="tire" ++Username="ippadmin" ++Username="liberty-admin" +``` + +These are active Windows admin credentials embedded in PowerShell unattend scripts. **This is a data breach risk.** If these repos ever go public or are cloned outside ITPP infrastructure, client credentials are exposed. + +#### `hermes-recovery` — 8 potential secrets +Includes the Gitea API token used for this audit: +``` ++TOKEN="1761daa2c537fb72b365e54619208329d8e3ad33" ++TELEGRAM_BOT_TOKEN="8359374835:***" ++password="K3E1ZZWvHDu0q8ZmoBCAhzKUZawEapdGBlbaPME1sOTKgGk9FCuYS" ++token = "Ta9f9d1b462271a2f4-8d63a3f025eb89451edb16f2308c2e40" +``` + +The Gitea token itself is committed. This means `hermes-recovery` as a public repo exposes admin credentials. + +#### `hermes-skills` — 15 potential hits +Most are false positives (example values, `process.env.` references, placeholder text). One real hit: a Comfy CLI API key in a SKILL.md. + +### Step 4 — Structural Checks + +#### Remote URL Audit + +| Remote Type | Count | Action | +|-------------|-------|--------| +| HTTPS to Gitea | 36 | OK | +| GitHub (upstream) | 1 | OK (`msp-claude-skills`) | +| SSH to Gitea | 2 | **FIX** — `itpp-infra`, `cartmylist-repo` | +| No remote | 23 | **FIX** — local-only, no backup | + +`itpp-infra` uses `git@git.itpropartner.com:ippadmin/itpp-infra.git` (SSH) — this repo has no corresponding HTTPS clone and appears to be a stale/abandoned repo (1 commit, 5 dirty files). + +`cartmylist-repo` (local) vs `cartmylist` (Gitea) is a naming mismatch. The local clone has an SSH remote to what is likely a different repo. + +#### Branch Naming + +- **30 repos use `master`** — industry standard is now `main` +- **9 repos use `main`** +- **20 repos have detached HEAD or no commits** + +**Branch mismatch:** `itpp-infrastructure` has `main` locally but `master` on Gitea. This means the remote may have both branches. + +#### Large Files + +| Repo | File | Size | +|------|------|------| +| `hermes-skills` | `.hub/index-cache/hermes-index.json` | 38.9 MB | +| `hermes-skills` | `.curator_backups/2026-07-12T15-48-44Z/skills.tar.gz` | 2.7 MB | + +Both are cache artifacts that should be in `.gitignore`, not tracked. + +#### Public vs Private + +**30 of 42 repos (71%) are public.** This is a concern because: +- `scripts` contains client admin passwords — **public** +- `hermes-recovery` contains Gitea admin token — **public** +- Many repos with sensitive infrastructure details are public + +### Step 5 — Commit Quality + +#### Commit Message Quality + +| Pattern | Count | Assessment | +|---------|-------|------------| +| `Initial commit — YYYY-MM-DD` | 16 | Poor — conveys nothing | +| `Update YYYY-MM-DD — root` | 5 | Meaningless | +| `Initial: ` | 8 | Barely adequate | +| Descriptive conventional commits | 4 | Good (`homelab`, `verdicttank`, `forefront-wireless-portal`) | + +**32 repos have only 1 commit** — these are documentation stubs, not developed projects. + +#### Active vs Abandoned + +| Status | Criteria | Repos | +|--------|----------|-------| +| **Active** | 3+ commits, recent activity | `itpp-infrastructure` (52), `scripts` (11), `homelab` (6), `forefront-wireless-portal` (5), `dre` (4), `verdicttank` (4), `personal-assistant` (3), `super-search-business` (3), `voipsimplicity` (3) | +| **Stub** | 1–2 commits, last push July 2025 | 32 repos | +| **Abandoned** | No commits or stale >3 months | `itpp-infra`, `auth`, `cartmylist-repo` | + +### Step 6 — Local-Only Repos + +23 repos in `/root/projects/` have no remote. Breakdown: + +| Category | Repos | Action | +|----------|-------|--------| +| Uncommitted stubs (0 commits) | 17 | Push to Gitea or archive | +| Has commits, no remote | 1 (`shonuff-caller`) | Push to Gitea | +| Stale noise | 5 | Archive and delete (`auth`, `itpp-infra`, `cartmylist-repo`, etc.) | + +The 17 repos with 0 commits and only detached HEAD are effectively just directories with a `.git` folder — not real repos. They should be either pushed as proper repos or archived. + +--- + +## Prioritized Action Plan + +### 🔴 Immediate (This Week) + +| # | Action | Severity | +|---|--------|----------| +| 1 | **Rotate all credentials exposed in `scripts` repo** — Windows passwords, Gitea token, Telegram bot token. Then purge from Git history with `git filter-branch` or `bfg-repo-cleaner` | **CRITICAL** | +| 2 | **Rotate Gitea API token** in `hermes-recovery` — it's publicly visible. Generate new token, update all consumers, purge old from history | **CRITICAL** | +| 3 | **Make `scripts` and `hermes-recovery` PRIVATE** — they contain live credentials visible to anyone | **CRITICAL** | +| 4 | **Add `.gitignore` to all 51 repos missing one** — start with the active repos first | **HIGH** | +| 5 | **Commit or stash all dirty working trees** — 13 repos have uncommitted work at risk of loss | **HIGH** | + +### 🟡 Short-Term (This Month) + +| # | Action | Severity | +|---|--------|----------| +| 6 | **Reorganize `itpp-infrastructure/docs/`** into nested folders (audit/, clients/, infrastructure/, monitoring/, projects/, super-search/) | **MEDIUM** | +| 7 | **Consolidate 4 MCP repos into `mcp-servers/`** as subdirectories — delete empty stubs after merge | **MEDIUM** | +| 8 | **Merge 14 single-commit business idea repos** into a `project-ideas` monorepo | **MEDIUM** | +| 9 | **Delete `auth`** (empty repo, 0 commits) | **MEDIUM** | +| 10 | **Resolve `itpp-infra` vs `itpp-infrastructure`** — archive `itpp-infra`, standardize on `itpp-infrastructure` | **MEDIUM** | +| 11 | **Add `.gitignore` entries to `hermes-skills`** for `.hub/`, `.curator_backups/` | **MEDIUM** | +| 12 | **Rename `master` → `main` on repos where it matters** (at minimum `itpp-infrastructure` to fix branch mismatch) | **LOW** | + +### 🔵 Pre-Public / Pre-Open-Source + +| # | Action | Severity | +|---|--------|----------| +| 13 | **Audit all 30 public repos** — ensure no private infrastructure details, client names, IPs, or credentials are exposed | **HIGH** | +| 14 | **Decide public/private policy** — which repos genuinely need to be public? Currently 71% are public. | **MEDIUM** | +| 15 | **Push 23 local-only repos to Gitea** or archive them. No code living only on a single server. | **HIGH** | +| 16 | **Clean commit history** — rebase repos with "Update YYYY-MM-DD — root" messages into meaningful commits | **LOW** | + +--- + +## Template: Standard `.gitignore` + +For any new or cleaned repo, use: + +```gitignore +# OS +.DS_Store +Thumbs.db + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# Python +__pycache__/ +*.py[cod] +*.egg-info/ +.venv/ +venv/ + +# Node +node_modules/ + +# Secrets — NEVER commit these +.env +.env.* +*.pem +*.key +credentials.json +*.token + +# Cache / generated +.hub/ +.curator_backups/ +*.tar.gz +*.zip + +# Data +*.db +*.sqlite +*.sqlite3 +``` + +--- + +## Appendix: Full Repo Inventory + +### Active Repos (keep as standalone) + +| Repo | Commits | Last Commit | Branch | `.gitignore` | Assessment | +|------|---------|-------------|--------|-------------|------------| +| `itpp-infrastructure` | 52 | 2026-08-07 | main/master mismatch | YES | **Primary hub** — healthy | +| `hermes-skills` | 1 | 2026-07-15 | master | NO | Active mirror, 13.6MB | +| `hermes-recovery` | 1 | 2026-07-15 | master | YES | Critical backup kit | +| `scripts` | 11 | 2026-07-25 | master | NO | Active, **has secrets** | +| `homelab` | 6 | 2026-07-24 | main | NO | Active, good commits | +| `dre` | 4 | 2026-07-25 | master | NO | Active development | +| `verdicttank` | 4 | 2026-08-07 | main | NO | Active, good commits | +| `forefront-wireless-portal` | 5 | 2026-07-25 | master | NO | Active, good commits | +| `super-search-business` | 3 | 2026-07-25 | main | NO | Active | +| `voipsimplicity` | 3 | 2026-07-24 | master | NO | Active client work | +| `voipsimplicity-manual` | 1 | 2026-08-05 | master | NO | Active client work | + +### Stub Repos (consolidate) + +All 32 repos below are single-commit documentation stubs with no ongoing development. Consolidate into `project-ideas/` monorepo or relevant parent repo: + +`apex-track`, `backup-restore`, `boxpilot`, `content-creation-pipeline`, `digital-signage`, `disaster-recovery`, `fleettracker360`, `gift-a-roast`, `hudu`, `itpropartner-website`, `launchcheck`, `mcp-browser`, `mcp-email`, `mcp-filesystem`, `mcp-git`, `mcp-servers`, `model-fallback`, `mooresunnydaze`, `nvr-shield`, `ops-portal`, `osint-tool`, `personal-assistant`, `pipeline`, `shark-game`, `startup-studio`, `super-search`, `track-a-flock`, `unifi`, `unms`, `cartmylist` + +### To Delete or Archive + +| Repo | Reason | +|------|--------| +| `auth` | Empty (0 commits, 0 content) | +| `itpp-infra` | Stale duplicate of `itpp-infrastructure`, SSH-only remote, 1 commit | +| `cartmylist-repo` | Local clone with SSH remote, mismatched name (real one is `cartmylist` on Gitea) | + +### Local-Only (push or archive) + +`assistant`, `auth`, `capabilities`, `hear-read`, `intelsight`, `intelsight-landing`, `internal`, `mockup`, `my-itpropartner-portal`, `ops`, `ops-v2-portal`, `osint`, `proposals`, `pry`, `research-search-mcp`, `schedule`, `shonuff`, `shonuff-caller`, `static`, `status`, `voice-previews` + +--- + +*Report generated by Hermes Agent git-audit workflow. Next audit recommended: 2026-11-08.*