feat: comprehensive repo health check updates
Branch Protection Setup / Apply Branch Protection Rules (push) Successful in 24s
Sync Wikis to GitHub / Export wikis to GitHub (push) Successful in 7s

- Security: flag renovate.json as disallowed (removed from ecosystem)
- Disallowed: add .claude/, .mcp.json, renovate.json, profile.ps1
- Manifest: check .gitignore has required exclusions (.claude/, TODO.md, *.min.css/js)
- Manifest: check CLAUDE.md has project context + MokoStandards reference
- Updated scoring and header documentation

Authored-by: Moko Consulting
This commit is contained in:
Jonathan Miller
2026-05-10 15:07:17 -05:00
parent 15de3eed96
commit aa1800e2f6
+36 -10
View File
@@ -12,13 +12,13 @@
* VERSION: 05.00.00
* BRIEF: Repository health checker — validates against current Moko standards (wiki-first, no docs/)
*
* Categories (135 total points):
* Categories:
* Required Files (40) — README, LICENSE, CHANGELOG, CONTRIBUTING, SECURITY, CLAUDE.md, .gitignore, Makefile
* Manifest & Config (15) — .moko-platform, workflows dir, README content, CODE_OF_CONDUCT
* Documentation (10) — wiki-first: docs/ must NOT exist
* Disallowed (10) — TODO.md, vendor/, node_modules/
* Manifest & Config (20) — .moko-platform, workflows, README quality, CODE_OF_CONDUCT, .gitignore content, CLAUDE.md quality
* Documentation (15) — wiki-first: docs/ must NOT exist, CHANGELOG [Unreleased]
* Disallowed (10) — TODO.md, vendor/, node_modules/, .claude/, .mcp.json, renovate.json, profile.ps1
* Workflows (15) — repo-health, sync-roadmap-wiki, CI/deploy
* Security (20) — SECURITY.md, scanning, dependency mgmt, no secrets
* Security (20) — SECURITY.md, scanning, no renovate.json, no secrets
* Rulesets (15) — main protected, dev branch, rulesets
* Deployment (10) — deploy workflow, build system
*
@@ -137,6 +137,25 @@ class RepoHealthChecker extends CliFramework
file_exists("{$p}/README.md") && strlen(file_get_contents("{$p}/README.md")) > 500, 3);
$this->addCheck($cat, 'CODE_OF_CONDUCT.md',
file_exists("{$p}/CODE_OF_CONDUCT.md"), 2);
// .gitignore must contain key exclusions
$gitignoreOk = false;
if (file_exists("{$p}/.gitignore")) {
$gi = file_get_contents("{$p}/.gitignore");
$gitignoreOk = str_contains($gi, '.claude/') && str_contains($gi, 'TODO.md')
&& str_contains($gi, '*.min.css') && str_contains($gi, '*.min.js');
}
$this->addCheck($cat, '.gitignore has .claude/, TODO.md, *.min.css/js',
$gitignoreOk, 3);
// CLAUDE.md should have project overview
$claudeOk = false;
if (file_exists("{$p}/CLAUDE.md")) {
$claude = file_get_contents("{$p}/CLAUDE.md");
$claudeOk = strlen($claude) > 200 && str_contains($claude, 'MokoStandards');
}
$this->addCheck($cat, 'CLAUDE.md has project context + MokoStandards ref',
$claudeOk, 2);
}
// ── Documentation: Wiki-First (15 pts) ───────────────────────────
@@ -167,11 +186,19 @@ class RepoHealthChecker extends CliFramework
$this->initCategory($cat, 'Disallowed Items', 10);
$this->addCheck($cat, 'No TODO.md (use issues)',
!file_exists("{$p}/TODO.md"), 5);
!file_exists("{$p}/TODO.md"), 2);
$this->addCheck($cat, 'No vendor/ committed',
!is_dir("{$p}/vendor") || file_exists("{$p}/vendor/.gitkeep"), 3);
!is_dir("{$p}/vendor") || file_exists("{$p}/vendor/.gitkeep"), 2);
$this->addCheck($cat, 'No node_modules/',
!is_dir("{$p}/node_modules"), 2);
$this->addCheck($cat, 'No .claude/ committed',
!is_dir("{$p}/.claude"), 1);
$this->addCheck($cat, 'No .mcp.json committed',
!file_exists("{$p}/.mcp.json"), 1);
$this->addCheck($cat, 'No renovate.json',
!file_exists("{$p}/renovate.json"), 1);
$this->addCheck($cat, 'No profile.ps1',
!file_exists("{$p}/profile.ps1"), 1);
}
// ── Workflows (15 pts) ───────────────────────────────────────────
@@ -207,9 +234,8 @@ class RepoHealthChecker extends CliFramework
|| !empty(glob("{$wf}/*security*.yml")));
$this->addCheck($cat, 'Security scanning workflow', $hasScan, 5);
$this->addCheck($cat, 'Dependency management',
file_exists("{$p}/renovate.json") || file_exists("{$p}/.renovaterc.json")
|| file_exists("{$p}/.github/dependabot.yml"), 5);
$this->addCheck($cat, 'No renovate.json (removed from ecosystem)',
!file_exists("{$p}/renovate.json"), 5);
$secrets = false;
foreach (['.env', '.env.local', 'credentials.json'] as $s) {