Tenant: monorepo-health
Tenant monorepo-health
Runs bun run monorepo:health · bun run check:monorepo-health · bun tools/monorepo-health.ts
Proof claim monorepo-health-score · reports/monorepo-health-latest.json · formula unit tests
Gates pre-commit --tests-only when health sources staged · ci:core full ratchet · import-graph shares scanSourceImports
Catalog Bun-native Glob · build metafile · optional Archive · SQLite trend
Workspace graph / catalog policy sibling monorepo-workspaces.md · bun run validate:workspaces
Health = 100
− (duplicateDepCount × 2)
− (deadCodePercent × 0.5)
− (largeFilePercent × 1)
− (testFailureRate × 5)
− (cyclicDependencyCount × 1.5)
+ (testCoveragePercent × 0.2)
| Grade |
Score |
| healthy |
≥ 90 |
| needs-improvement |
60–89.9 |
| critical |
< 60 (CLI exit 1) |
Collection (Bun APIs)
| Metric |
Source |
| duplicateDepCount |
workspace + root package.json dependency version sets |
| deadCodePercent / cycles |
Bun.Transpiler.scanImports (prefers over scan — captures require() on Bun 1.4) · ESM + dynamic import() · type-only ignored · relative edges for orphans/cycles |
| largeFilePercent |
Bun.Glob + line count (> 200 default) |
| testFailureRate |
optional --with-tests / --with-coverage focused bun test sample |
| testCoveragePercent |
--with-coverage → bun test --coverage; parse All files line % (bonus ×0.2) |
Not a full AST. Bun has no public ESTree walk API; scan / scanImports are the native module-graph surface (transpiler). Cyclomatic complexity still uses the TypeScript compiler API.
Health score vs import-graph gate
Two tools consume one import SSOT — scanSourceImports in lib/harness/monorepo-health.ts (Bun.Transpiler.scanImports: ESM + require() + dynamic import(), type-only ignored). They own different decisions:
| Tool |
Owns |
Verdict feeds |
monorepo:health / check:monorepo-health |
Advisory trend — 0–100 score; cycles are one capped linear penalty (×1.5) |
dashboards · SQLite trend · /api/health · portal boards |
check:import-graph (scripts/check-import-graph.ts) |
Hard fail — strong/weak cycle + deep-relative counts vs scripts/import-graph-baseline.json may only go down |
commit blocking (pre-commit + ci:core) |
- The score tolerates a flat cycle count; the gate does not — one new strong cycle fails the commit even at score ≥ 90.
- Use
monorepo-health for trends and operator triage; use check:import-graph when deciding whether a commit may land.
- Never hand-roll import scanning in a third tool — extend
scanSourceImports so cycle definitions (strong = all-static edges, weak = ≥1 lazy import() edge) cannot drift between tools.
- Re-pin authority is separate per tool:
check-import-graph --write-baseline (owners, after intentional restructuring) never re-pins the score baseline, and vice versa.
CLI
# Continuous gate (ci:core + claim monorepo-health-score)
bun run check:monorepo-health # unit tests + collect + schema + baseline ratchet
bun scripts/check-monorepo-health.ts --tests-only # pre-commit when health files staged
bun scripts/check-monorepo-health.ts --write-baseline # owners: re-pin floors after intentional change
bun run check:import-graph # cycle/deep-relative (shares scanSourceImports)
# Operator CLI (not a commit gate by itself)
bun run monorepo:health # human table + latest JSON + SQLite trend
bun run monorepo:health:json # stdout JSON only
bun run monorepo:health:full # --with-coverage --archive
bun run monorepo:health:watch
bun tools/monorepo-health.ts --no-build
bun tools/monorepo-health.ts --with-tests
bun tools/monorepo-health.ts --with-coverage # tests + All-files line % bonus
bun tools/monorepo-health.ts --archive # tar report when Bun.Archive available
bun tools/monorepo-health.ts --watch --interval=30
bun tools/monorepo-health.ts --interactive
bun tools/monorepo-health.ts --inspect
bun tools/monorepo-health.ts --validate reports/monorepo-health-latest.json
Integration
| Surface |
Behavior |
| Husky pre-commit |
When lib/harness/monorepo-health* / tools/monorepo-health.ts / gate/baseline/tests staged → check-monorepo-health --tests-only |
| Husky pre-commit |
Always (lib/scripts staged): check:import-graph (same Transpiler SSOT) |
ci:core |
Full check:monorepo-health after import-graph (+ writes /registry/monorepo-health.json) |
ops:snapshot |
Bakes monorepo-health before ops-summary (--no-monorepo-health to skip) |
ops-summary.json |
monorepoHealth compact slice |
/api/health |
artifacts.monorepoHealth + top-level monorepoHealth (Pages edge) |
| TOC portal |
/portal/toc/ Harness glance · footer links |
| Packages portal |
/portal/packages/ graph map |
| Proton / vault |
Separate plane — audit:packages:env · env:inventory · vault:gap:* · proton-integration.md |
bun run monorepo:health:bake # → public/registry/monorepo-health.json
bun run ops:snapshot --no-routing # includes monorepo-health + ops-summary.monorepoHealth
bun run check:monorepo-health # gate + bake
CLI I/O model
| Surface |
Use |
process.stdout / stderr |
tables, help, host spinner (not Bun.Terminal) |
Bun.inspect / .table |
structured dumps; depth via BUN_CONSOLE_DEPTH / --console-depth |
Bun.Terminal |
child PTY only — lib/terminal.ts |
bun:sqlite |
reports/monorepo-health-history.sqlite score trend |
Bun.semver |
warn if runtime < 1.3.0 |
Bun.which |
probe bun / git / tar on PATH |
Bun.sleep |
--watch interval |
Bun.stdin |
--interactive prompts |
Code
Focused packages/*/src graph (Bun.build metafile), complementary to this tenant:
bun run audit:packages # score/grade + deep map (schema v13; board accepts v12+)
bun run audit:packages:full # --cross-check --diff --md --map --bake --vault --env
bun run audit:packages:env # --env --vault-gap + bake packages + env-inventory
bun run audit:packages:vault # --vault --vault-gap (live pass-cli status) + bake
bun run audit:packages:apply # wire open wire-root-dep actions + bake
bun run env:inventory # scans packages/ · owners · packages plane
bun run env:inventory:bake # → /registry/env-inventory.json (schemaVersion 4, +toml plane)
Claim packages-graph-map-v13 · multi-surface inventory v3 (workspaces, lib/ dirs, STO nested, portal chrome/brand/theme, registry families, page→registry edges, lib import hubs, orphan triage wire/document/review) via lib/harness/monorepo-surfaces.ts · ratchet: bun test tests/packages-graph-map.test.ts tests/monorepo-surfaces.test.ts tests/packages-metafile-audit.test.ts tests/packages-vault-map.test.ts tests/env-inventory-compact.test.ts tests/packages-board.test.ts tests/env-defaults-scan.test.ts · bun run audit:packages:env · bun run portal-cli pm graph
--env attaches compact inventory (owners, missingNeedsInject vs coveredByTemplateDefault) and bakes /registry/env-inventory.json. Placeholder @factorywager/package removed. Companion: proton-integration.md · bun run env:inventory:ratchet · bun run proton:inject:factorywager.