15 KiB
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:
- Merge 4 MCP stubs (
mcp-browser,mcp-email,mcp-filesystem,mcp-git) intomcp-servers/as subdirectories - Merge related business ideas into a
project-ideasmonorepo: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
- Merge related operational repos:
disaster-recovery+backup-restore→disaster-recovery/withbackup-restore/subdir - Merge website/docs stubs:
itpropartner-website,content-creation-pipeline,ops-portal→ subdirectories initpp-infrastructure - Resolve
itpp-infra(stale, SSH-only, 1 commit) → archive; useitpp-infrastructureas primary - Delete
auth(empty repo withauth.db— never committed) - 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="[REDACTED]"
+Password="[REDACTED]"
+Password="[REDACTED]"
+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="[REDACTED]"
+TELEGRAM_BOT_TOKEN="[REDACTED]"
+password="***"
+token = "[REDACTED]"
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 nowmain - 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:
scriptscontains client admin passwords — publichermes-recoverycontains 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: <project name> |
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:
# 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.