Skip to content

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-start at 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

/vt-c-repo-health

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:

  1. Context in deployable: Check for .md files in src/ that match context patterns (research, persona, PRD files — excluding README.md, CHANGELOG.md)
  2. Code in context: Check for .ts, .js, .py files in docs/ or 02-Knowledge/
  3. Count violations (don't list every file — just counts)

Step 3: Check Binary Management

  1. Git LFS active: git lfs env returns successfully
  2. .gitattributes exists: Contains LFS rules
  3. Oversized files: Quick check for files >500KB not in LFS (limit to 10 results)

Step 4: Check Traceability

  1. Active Spec: Derive from branch name (feature/spec-NNN-* → SPEC-NNN) or .active-spec file
  2. Recent commits: Check last 5 commits to src/ for SPEC- references
  3. specs progress: Aggregate status from per-spec specs/*/state.yaml files (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:

Drift Detection: ℹ️  No baseline snapshot — run /vt-c-repo-health --update-baseline to create one
Skip checks D1–D4 and proceed to the traffic light.

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.

  1. Read mcp_servers_snapshot.approved_servers from configs/security/config-snapshot.yaml
  2. Discover current MCP servers from project settings files and .mcp.json (if present)
  3. Report servers in current but NOT in approved list as WARN: "MCP Server Drift: [WARN] N unapproved server(s) added: <names>"
  4. Report servers in approved list but NOT in current as INFO: "MCP Server Drift: [INFO] N server(s) removed: <names>"
  5. 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:

  1. Construct the waiver key: <check-type>:<specific-item> — e.g., deny-rule-removed:shell-config-modification or mcp-server-added:playwright
  2. If a matching waiver exists:
  3. If expiration_date is null or in the future: report as "ACCEPTED" instead of WARN/CRITICAL — does NOT count toward traffic light violations
  4. If expiration_date is in the past: report as the original severity + note "(expired waiver — re-evaluate or renew)"
  5. 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:

  1. Detect default branch: git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' (fall back to main)
  2. Query protection: gh api repos/{owner}/{repo}/branches/{default-branch}/protection 2>/dev/null
  3. If the API call succeeds, check for:
  4. required_pull_request_reviews exists → PR reviews required
  5. required_status_checks exists → CI checks required
  6. enforce_admins.enabled is true → admins not exempt
  7. Report:
  8. All 3 present: "Branch Protection: ✅ PR reviews + status checks + admin enforcement"
  9. Some missing: "Branch Protection: ⚠️ Missing: [list]"
  10. API returns 404: "Branch Protection: ⚠️ No protection rules configured on {branch}"

If gh CLI is not available or no GitHub remote:

Branch Protection: ℹ️  Skipped (gh CLI 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:

  1. Read the current deny rules from all settings tiers (same search as Check 1)
  2. Extract each deny rule and classify into the 11 baseline categories by matching against configs/security/baseline-settings.json _deny_rule_categories
  3. Template cross-check: Compare the current deny rules against the full baseline-settings.json template. If any template rules are missing from current settings, report BEFORE saving:
    Baseline template gaps detected:
      Missing: 2 rules in "destructive-commands" (sudo, mkfs)
      Missing: 1 rule in "network-exfiltration" (nc)
    The snapshot will record the current (gapped) state.
    These gaps should have waivers in drift-waivers.yaml.
    
    This ensures the person updating the baseline sees what they are accepting. Save the snapshot regardless — the warning is informational, not blocking.
  4. Discover current MCP servers from settings files and .mcp.json
  5. Read the current git config user.name for generated_by
  6. Write/update configs/security/config-snapshot.yaml with:
  7. snapshot_version: "1"
  8. generated_at: current ISO-8601 datetime
  9. generated_by: git user.name
  10. last_audited: today's date (YYYY-MM-DD)
  11. audit_interval_days: preserve existing value or default to 30
  12. deny_rules_snapshot: categorized rules from current settings
  13. mcp_servers_snapshot: current servers with allow_all_project_servers status

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"