health

Computes a weighted 0-10 health score across typecheck, lint, tests, and dead code. Persists baseline in ~/.dog/health/{repo-slug}.json and reports delta vs previous run. Use when you want a quick signal on project quality or to track quality trend over time.

/dog:health — Project Health Score

Compute a 0-10 health score for the project, persist a baseline, and report the delta vs the previous run.

When to Use

  • Before starting a new feature (get a quality baseline)
  • After a large refactor (check for regressions)
  • In CI to track quality trend over time
  • When onboarding to a new project

When NOT to Use

  • As a substitute for a proper CI pipeline — it's a quick local signal, not a full test suite
  • On projects without any build tooling — the score will be 0/10 for missing tools rather than true quality

Scoring

DimensionWeightCommand
Typecheck30%tsc --noEmit / mypy / go vet / cargo check
Lint20%eslint / ruff check / golangci-lint / clippy
Tests30%vitest run / pytest / go test ./... / cargo test
Dead code20%ts-prune / vulture / deadcode / cargo-udeps

Each dimension scores 0-10:

  • Tool not found: 5 (neutral — don't penalize missing optional tools)
  • Command exits 0: 10
  • Command exits non-zero: score proportional to output (0-8, based on error count)

Composite = weighted average of all four dimensions.

Language Detectors

LanguageDetector files
TypeScript/JSpackage.json, tsconfig.json, *.ts
Pythonpyproject.toml, setup.py, *.py
Gogo.mod
RustCargo.toml

Process

Step 1 — Detect project language(s)

ls package.json tsconfig.json go.mod Cargo.toml pyproject.toml 2>/dev/null

Step 2 — Run all 4 dimensions for detected language(s)

Run each tool and capture exit code + output line count. Score each dimension:

  • Exit 0 → 10
  • Exit non-zero, 0-5 errors → 7
  • Exit non-zero, 6-20 errors → 4
  • Exit non-zero, >20 errors → 0
  • Tool not found → 5

Step 3 — Compute composite score

composite = (typecheck × 0.30) + (lint × 0.20) + (tests × 0.30) + (dead_code × 0.20)

Round to 1 decimal place.

Step 4 — Load previous baseline (if exists)

SLUG=$(git remote get-url origin 2>/dev/null | sed 's|[/:.]|-|g' | sed 's|^.*github-com-||')
BASELINE_FILE=~/.dog/health/${SLUG}.json
cat "$BASELINE_FILE" 2>/dev/null

Step 5 — Report score + delta

Print a summary:

Health Score: 7.4 / 10
  Typecheck:  8.0  (weight 30%)
  Lint:       6.0  (weight 20%)
  Tests:      8.0  (weight 30%)
  Dead code:  7.0  (weight 20%)
Delta vs last run: Δ +0.4 ▲  (was 7.0 on 2026-04-10)

If no previous baseline: print (first run — baseline saved).

Step 6 — Save/update baseline

mkdir -p ~/.dog/health
cat > "$BASELINE_FILE" <<EOF
{
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "score": 7.4,
  "subscores": {"typecheck": 8.0, "lint": 6.0, "tests": 8.0, "dead_code": 7.0},
  "commit_sha": "$(git rev-parse HEAD 2>/dev/null || echo 'unknown')"
}
EOF

Verification

After running /dog:health, verify:

cat ~/.dog/health/*.json | head -5   # baseline file exists

The command must print a score in the format Health Score: X.X / 10.

Related

  • Skill: dog:verification-before-completion
  • Command: /dog:build-fix
  • Agent: typescript-build-resolver, python-build-resolver