Skip to content
Arxo Arxo

Monorepo Governance

monorepo analyzes architecture governance across workspace packages. It emits keys under monorepo.* and deterministic findings for dependency-policy violations, build/task graph drift, blast-radius risk, and ownership gaps.

  • Current public contract: monorepo v2.0.0
  • Category: synthesis metric

monorepo currently requires:

  • Import graph
  • Workspace config
  • Git history
  • Build graph

Build graph is derived from workspace task configuration (currently Turbo/Nx task graphs). If no build graph is available, this metric returns an error.

For monorepos without task graph support, use package_metrics, scc, and propagation_cost as a fallback structural baseline.

  • monorepo.inventory.package_count
  • monorepo.policy.edge_violations_count
  • monorepo.policy.transitive_violations_count
  • monorepo.policy.external_banned_count
  • monorepo.policy.compliance_ratio
  • monorepo.structure.cycle_count
  • monorepo.structure.packages_in_cycles_count
  • monorepo.structure.blast_radius.max
  • monorepo.structure.blast_radius.avg
  • monorepo.structure.blast_radius.p95
  • monorepo.build.task_count
  • monorepo.build.task_cycle_count
  • monorepo.build.cache_disabled_count
  • monorepo.build.missing_dependency_edges_count
  • monorepo.build.overdeclared_dependency_edges_count
  • monorepo.affected.precision_avg
  • monorepo.affected.recall_avg
  • monorepo.affected.f1_avg
  • monorepo.affected.low_f1_packages_count
  • monorepo.deps.undeclared_workspace_count
  • monorepo.deps.version_divergence_count
  • monorepo.deps.catalog_drift_count
  • monorepo.deps.workspace_protocol_violations_count
  • monorepo.ownership.avg_contributors
  • monorepo.ownership.avg_gini
  • monorepo.ownership.unowned_packages_count
  • monorepo.ownership.high_risk_count
  • monorepo.ownership.high_blast_unowned_count

monorepo emits deterministic findings with these rule_id values:

  • monorepo.policy.edge_violation
  • monorepo.policy.transitive_violation
  • monorepo.build.missing_edge
  • monorepo.build.overdeclared_edge
  • monorepo.affected.low_f1
  • monorepo.deps.version_divergence
  • monorepo.deps.workspace_protocol
  • monorepo.ownership.unowned_critical
  • monorepo.structure.cycle
  • monorepo.structure.high_blast

Enable metric:

metrics:
- id: monorepo

Optional config block:

monorepo:
classification:
infer_from_paths: true
tag_rules: []
package_overrides: {}
policy:
allow: []
deny: []
allow_external_by_tag: {}
deny_external_by_tag: {}
affected:
min_cochange: 2
low_f1_threshold: 0.30
dependency_governance:
enforce_workspace_protocol: true
enforce_version_convergence: true
max_major_drift: 0
ownership:
codeowners_path: ".github/CODEOWNERS"
critical_dependents_threshold: 3
policy:
invariants:
- metric: monorepo.policy.edge_violations_count
op: "=="
value: 0
message: "No direct dependency policy violations"
- metric: monorepo.build.missing_dependency_edges_count
op: "=="
value: 0
message: "Task graph must reflect package dependencies"
- metric: monorepo.structure.blast_radius.max
op: "<="
value: 12
message: "Avoid high-blast workspace packages"
- metric: monorepo.affected.f1_avg
op: ">="
value: 0.70
message: "Predicted affected sets should align with history"
{
"id": "monorepo",
"data": [
{ "key": "monorepo.inventory.package_count", "value": { "kind": "number", "v": 24 } },
{ "key": "monorepo.policy.edge_violations_count", "value": { "kind": "number", "v": 2 } },
{ "key": "monorepo.structure.blast_radius.max", "value": { "kind": "number", "v": 15 } }
],
"findings": [
{
"rule_id": "monorepo.policy.edge_violation",
"finding_type": "api_boundary_violation",
"title": "Policy edge violation: apps/web -> packages/internal-auth"
}
]
}
Legacy keyv2 replacement
monorepo.package_countmonorepo.inventory.package_count
monorepo.blast_radius.maxmonorepo.structure.blast_radius.max
monorepo.blast_radius.avgmonorepo.structure.blast_radius.avg
monorepo.boundary_violation_countmonorepo.policy.edge_violations_count
monorepo.api_boundary.violations_countmonorepo.policy.edge_violations_count

No direct one-key replacement:

  • monorepo.api_boundary.internal_import_ratio
  • monorepo.layering.apps_to_apps_count
  • monorepo.layering.shared_to_app_count

Use policy tag/rule configuration plus monorepo.policy.* counters and findings.