vt-c-repo-health¶
Quick governance health check with traffic-light summary. Lighter than /vt-c-repo-audit, meant for regular use at workflow entry points.
Plugin: core-standards
Category: Governance
Command: /vt-c-repo-health
/vt-c-repo-health — Governance Health Check¶
Called automatically by
/vt-c-0-startat workflow entry. Can be run anytime.For full audit with fix capability, use
/vt-c-repo-audit.
Purpose¶
Quick, non-blocking governance compliance check that produces a traffic-light summary. Designed to run fast and give an at-a-glance view of repository health.
When to Use¶
- At the start of any work session
- Called automatically by
/vt-c-0-start - Before committing significant changes
- Anytime you want a quick status check
Prerequisites¶
.repo-manifest.yaml must exist. If absent:
Governance not active (no .repo-manifest.yaml).
Run /vt-c-repo-init to enable unified repo governance.
Invocation¶
Execution Steps¶
Step 1: Validate Manifest¶
Check .repo-manifest.yaml exists and is valid YAML:
- File exists → check
- Valid YAML → check
- governance: unified-repo-v1 present → check
- partitions section defined → check
Step 2: Check Partition Integrity¶
Quick scan for obvious violations:
- Context in deployable: Check for
.mdfiles insrc/that match context patterns (research, persona, PRD files — excluding README.md, CHANGELOG.md) - Code in context: Check for
.ts,.js,.pyfiles indocs/or02-Knowledge/ - Count violations (don't list every file — just counts)
Step 3: Check Binary Management¶
- Git LFS active:
git lfs envreturns successfully - .gitattributes exists: Contains LFS rules
- Oversized files: Quick check for files >500KB not in LFS (limit to 10 results)
Step 4: Check Traceability¶
- Active Spec: Derive from branch name (
feature/spec-NNN-*→ SPEC-NNN) or.active-specfile - Recent commits: Check last 5 commits to
src/for SPEC- references - specs progress: Aggregate status from per-spec
specs/*/state.yamlfiles (static metadata from.design-state.yaml)
Step 5: Check Security Configuration¶
Quick security configuration audit against the baseline in configs/security/baseline-settings.json.
Check 1: Deny rules present
Search for deny rules in settings files (in order of precedence):
1. .claude/settings.json (project-level)
2. configs/user-global/settings.json (toolkit user-level template)
3. configs/user-global/settings.local.json (local overrides)
Look for a "deny" array inside "permissions". Deny rules are aggregated across all settings files (union semantics — a rule present in any file counts as covered). Check coverage against the 11 baseline categories (SPEC-114):
1. Network exfiltration (curl, wget, nc, WebFetch)
2. Credential file access (~/.ssh, ~/.aws, .env variants, secrets/, Grep/Glob mirrors, Bash(cat))
3. Destructive commands (rm -rf, sudo, mkfs)
4. Shell config modification (~/.bashrc, ~/.zshrc)
5. Untrusted package execution (npx -y, npm publish, .npmrc, .pypirc)
6. Git safety (git push --force, git reset --hard, git clean -f) — SPEC-114
7. Code execution (python -c, node -e, perl -e) — SPEC-114
8. Database destructive (DROP DATABASE, rails db:drop, prisma migrate reset) — SPEC-114
9. Infrastructure (terraform destroy, kubectl delete namespace) — SPEC-114
10. Self-modification (global ~/.claude/settings.json, ~/.claude/CLAUDE.md, .git/**) — SPEC-114
11. Agent governance (--dangerously-skip-permissions, crontab) — SPEC-114
Check 2: MCP server whitelisting
Search settings files for MCP-related keys:
- enableAllProjectMcpServers — flag true as a security warning
- allowedMcpServers or enabledMcpjsonServers — report as properly whitelisted
Check 3: Env secret patterns
Scan "env" values in all settings files for secret patterns:
- Values containing sk-, ghp_, ghs_, AKIA, Bearer
- Keys matching *_KEY, *_SECRET, *_TOKEN, *_PASSWORD
Check 4: Configuration Drift Detection (requires configs/security/config-snapshot.yaml)
If configs/security/config-snapshot.yaml does not exist, report:
If configs/security/config-snapshot.yaml exists, run these four drift checks:
Check D1 — Deny Rule Drift (compares current settings against snapshot)
1. Read deny_rules_snapshot.categories from configs/security/config-snapshot.yaml
2. For each category, check whether all listed patterns are still present in the current settings deny rules (same union semantics as Check 1 — aggregate across all settings tiers)
3. Report removed rules as WARN: "Deny Rule Drift: [WARN] N rules removed since baseline" — list the specific removed rules
4. Report added rules (in current but not in snapshot) as INFO: "Deny Rule Drift: [INFO] N rules added since baseline"
5. If no changes: "Deny Rule Drift: ✅ No drift detected"
Check D2 — MCP Server Drift (compares current MCP servers against approved list)
Scope: checks project-level .mcp.json and allowedMcpServers in project settings (.claude/settings.json). User-level MCP config (~/.claude/settings.json) is per-machine — each team member should run /vt-c-repo-health on their own machine. The approved_servers list represents the project-agreed set.
- Read
mcp_servers_snapshot.approved_serversfromconfigs/security/config-snapshot.yaml - Discover current MCP servers from project settings files and
.mcp.json(if present) - Report servers in current but NOT in approved list as WARN:
"MCP Server Drift: [WARN] N unapproved server(s) added: <names>" - Report servers in approved list but NOT in current as INFO:
"MCP Server Drift: [INFO] N server(s) removed: <names>" - If no changes:
"MCP Server Drift: ✅ All servers approved"
Check D3 — Blanket MCP Enable (already covered by Check 2, but re-flag in drift context)
1. If enableAllProjectMcpServers: true in any settings tier: "Blanket MCP: [CRITICAL] enableAllProjectMcpServers is true"
2. Also check mcp_servers_snapshot.allow_all_project_servers — if snapshot says false but current says true, flag as drift
Check D4 — Audit Freshness (time-based + change-aware)
1. Read last_audited and audit_interval_days from configs/security/config-snapshot.yaml
2. Calculate days since last_audited
3. Check for settings changes since last audit: run git log --since=<last_audited> --oneline -- .claude/settings.json configs/user-global/settings.json configs/user-global/settings.local.json
4. Apply combined logic:
- If git shows commits since last audit: "Audit Freshness: [WARN] Settings modified since last audit (N commits) — re-audit recommended" — this is the strongest signal (someone changed settings)
- If no git changes AND days > audit_interval_days: "Audit Freshness: [INFO] Last audited N days ago — consider a routine check" — informational only, does NOT count as a violation (nothing actually changed)
- If no git changes AND days <= audit_interval_days: "Audit Freshness: ✅ No changes since last audit (N days ago)"
Waiver Resolution (requires configs/security/drift-waivers.yaml)
For each drift finding (D1–D3), before reporting as a violation, check configs/security/drift-waivers.yaml:
- Construct the waiver key:
<check-type>:<specific-item>— e.g.,deny-rule-removed:shell-config-modificationormcp-server-added:playwright - If a matching waiver exists:
- If
expiration_dateis null or in the future: report as"ACCEPTED"instead of WARN/CRITICAL — does NOT count toward traffic light violations - If
expiration_dateis in the past: report as the original severity + note"(expired waiver — re-evaluate or renew)" - If no matching waiver: report as the original severity
Display drift summary in this format:
Security Config — Drift Detection:
Deny Rules: ⚠️ 2 rules removed since baseline (1 waived)
MCP Servers: ✅ All servers approved
Blanket MCP: ✅ Not enabled
Freshness: ⚠️ Last audited 38 days ago (threshold: 30)
Check 5: Branch Protection (SPEC-103)
If gh CLI is available and the repo has a GitHub remote:
- Detect default branch:
git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@'(fall back tomain) - Query protection:
gh api repos/{owner}/{repo}/branches/{default-branch}/protection 2>/dev/null - If the API call succeeds, check for:
required_pull_request_reviewsexists → PR reviews requiredrequired_status_checksexists → CI checks requiredenforce_admins.enabledis true → admins not exempt- Report:
- All 3 present:
"Branch Protection: ✅ PR reviews + status checks + admin enforcement" - Some missing:
"Branch Protection: ⚠️ Missing: [list]" - API returns 404:
"Branch Protection: ⚠️ No protection rules configured on {branch}"
If gh CLI is not available or no GitHub remote:
This check is informational (yellow at most, never red) — branch protection is a GitHub-side setting, not a local enforcement.
Traffic light criteria:
- 🟢 Green: Deny rules cover all 11 categories + MCP not blanket-enabled + no env secrets + no unwaived drift violations + audit not overdue
- 🟡 Yellow: Deny rules cover some categories (or no settings file found) + no env secrets OR drift WARN findings (removed rules, unapproved MCP) OR audit overdue OR branch protection incomplete
- 🔴 Red: Env contains secret patterns OR enableAllProjectMcpServers: true OR zero deny rules with settings files present OR CRITICAL drift findings
Step 5b: Update Baseline Snapshot (triggered by --update-baseline argument)¶
If the user runs /vt-c-repo-health --update-baseline (or /vt-c-repo-health update-baseline), perform a baseline snapshot update instead of (or after) the normal audit:
- Read the current deny rules from all settings tiers (same search as Check 1)
- Extract each deny rule and classify into the 11 baseline categories by matching against
configs/security/baseline-settings.json_deny_rule_categories - Template cross-check: Compare the current deny rules against the full
baseline-settings.jsontemplate. If any template rules are missing from current settings, report BEFORE saving: This ensures the person updating the baseline sees what they are accepting. Save the snapshot regardless — the warning is informational, not blocking. - Discover current MCP servers from settings files and
.mcp.json - Read the current
git config user.nameforgenerated_by - Write/update
configs/security/config-snapshot.yamlwith: snapshot_version: "1"generated_at: current ISO-8601 datetimegenerated_by: git user.namelast_audited: today's date (YYYY-MM-DD)audit_interval_days: preserve existing value or default to 30deny_rules_snapshot: categorized rules from current settingsmcp_servers_snapshot: current servers withallow_all_project_serversstatus
Report:
Baseline snapshot updated:
Deny rules: 128 rules across 11 categories
MCP servers: 5 approved servers
Last audited: 2026-03-04
Snapshot: configs/security/config-snapshot.yaml
After updating, re-run the drift checks — they should now show zero drift (clean baseline).
Step 6: Display Traffic-Light Summary¶
Repo Health Check
═════════════════════════════════
Manifest: 🟢 Valid
Partitions: 🟢 Clean (0 violations)
Binary/LFS: 🟡 Warning (LFS not initialized)
Traceability: 🟡 Warning (2/5 commits lack SPEC ref)
Security Config: 🟡 Warning (2/5 deny categories covered)
Config Drift: 🟡 Warning (2 deny rules removed, audit overdue)
Branch Protection: ℹ️ Skipped (gh CLI not available)
Active: SPEC-003 — Data Import (in progress)
Progress: 2/6 specs completed
Overall: 🟡 WARNINGS — run /vt-c-repo-audit for details
═════════════════════════════════
Traffic light rules: - 🟢 Green: Check passes completely - 🟡 Yellow: Non-critical warnings (won't block deployment but should be addressed) - 🔴 Red: Critical violations (context bleed in deployable paths, broken manifest, env secrets detected)
Overall status: - 🟢 All green → "Healthy" - 🟡 Any yellow, no red → "Warnings — run /vt-c-repo-audit for details" - 🔴 Any red → "Violations detected — run /vt-c-repo-audit --fix"