npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@anarchitects/nx-governance

v0.1.0

Published

Nx governance plugin for workspace health, boundaries, ownership, and architecture reporting.

Readme

@anarchitects/nx-governance

An Nx plugin that turns your workspace's own project graph into an auditable, scored, and actionable governance report. It evaluates architectural boundaries, team ownership, documentation coverage, and dependency health — and surfaces everything as structured CLI output or machine-readable JSON that can gate CI pipelines.


Why governance-as-code?

Large Nx monorepos accumulate structural debt silently: cross-domain imports slip in, projects lose clear owners, layer contracts erode over time. Traditional linting catches individual file violations but cannot reason about workspace-level architecture intent — which teams own which domains, which layers may depend on which, or whether the overall dependency topology is growing in complexity.

@anarchitects/nx-governance introduces a governance profile — a single JSON file that declares architectural intent — and evaluates the entire workspace against it on every run. The result is a graded health score with per-metric breakdown, actionable violation details, and prioritized recommendations.


Table of contents


Installation

Use nx add — the standard Nx way to adopt a plugin. It installs the package and automatically runs the plugin's init generator in one step:

nx add @anarchitects/nx-governance

This is equivalent to installing the package and then running nx g @anarchitects/nx-governance:init, but without the manual steps. You will be prompted whether to also configure the ESLint integration (recommended).

If you need to re-run the init generator later (e.g. to add the ESLint integration to an existing install):

nx g @anarchitects/nx-governance:init

Quick start

# 1. Install the plugin and scaffold governance configuration
nx add @anarchitects/nx-governance

# 2. Tag each project with its domain and layer (see Domain tags below)
#    Add to each package.json > nx.tags:
#    ["type:plugin", "domain:billing", "layer:feature"]

# 3. Run the full workspace health check
nx repo-health

# 4. Drill into specific concerns
nx repo-boundaries
nx repo-ownership
nx repo-architecture

Concepts

Profiles

A governance profile is a JSON file at tools/governance/profiles/<name>.json. It is the single source of truth for what the workspace architecture should look like. Every run of any governance executor reads this file and evaluates the live project graph against it.

The built-in preset is angular-cleanup, modelled on Angular workspace conventions (layered architecture, domain-driven boundaries). You can adjust every aspect of it by editing the JSON file — no TypeScript required.

Boundary policy source

Every profile has a boundaryPolicySource setting:

| Value | Behaviour | | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | "profile" | The allowedDomainDependencies map in the profile JSON is the authoritative rule set. | | "eslint" | The runtime helper tools/governance/eslint/dependency-constraints.mjs is loaded at assessment time and its merged constraints are used as the primary rule set. The profile map acts as a fallback/override layer. A warning is surfaced in every report. |

Use "eslint" when you want ESLint's @nx/enforce-module-boundaries and the governance report to share a single source of truth, eliminating drift between the two enforcement layers.

Domain tags

Domains represent bounded business or technical areas. Tag each project in its package.json:

{
  "nx": {
    "tags": ["type:plugin", "domain:billing"]
  }
}

Equivalent project.json configuration is also supported:

{
  "name": "billing-api",
  "tags": ["type:plugin", "domain:billing"]
}

The governance engine extracts the value after domain: and uses it to evaluate cross-domain dependency rules. Projects without a domain tag are not evaluated for domain-boundary violations — they participate in ownership and documentation checks only.

Layer tags

Layers represent architectural tiers within a domain (e.g. Angular-style: app → feature → ui → data-access → util). Tag projects:

{
  "nx": {
    "tags": ["domain:billing", "layer:feature"]
  }
}

Equivalent project.json configuration is also supported:

{
  "name": "billing-feature",
  "tags": ["domain:billing", "layer:feature"]
}

The profile defines the ordered list of layers. A dependency from a project at position i to one at position j < i (i.e. a lower-index, higher-level layer) is flagged as a layer-boundary violation.

Ownership signals

The plugin resolves ownership from two complementary sources and merges them:

  1. Project metadata — the nx.metadata.ownership.team field in a project's package.json:

    { "nx": { "metadata": { "ownership": { "team": "@org/platform" } } } }

    The same ownership metadata can also live in project.json:

    {
      "name": "platform-core",
      "metadata": {
        "ownership": {
          "team": "@org/platform"
        }
      }
    }
  2. CODEOWNERS.github/CODEOWNERS, CODEOWNERS, or docs/CODEOWNERS at the workspace root. The plugin parses this file and matches project roots against patterns using full glob semantics (anchored paths, wildcards, double-star). The last matching rule wins, consistent with how GitHub evaluates CODEOWNERS.

When both sources provide information the ownership record is tagged source: "merged". When only one is present the source is "project-metadata" or "codeowners" respectively. Projects with no ownership signal are tagged source: "none" and a violation is raised when ownership.required: true in the profile.

Documentation signals

Documentation completeness is resolved from three places in priority order:

  1. projectOverrides.<projectName>.documentation in the profile JSON — useful for projects that carry documentation in non-standard locations.
  2. metadata.documentation in project.json or nx.metadata.documentation in package.json.
  3. Absense of either results in documentation: false for that project.

Generators

init generator

Scaffolds governance configuration into any Nx workspace and registers governance, snapshot/drift, and deterministic AI root targets.

nx g @anarchitects/nx-governance:init

What it does:

  • Registers @anarchitects/nx-governance in nx.json plugins.
  • Writes root targets into package.json > nx.targets for health checks, snapshot/drift, and deterministic AI analysis workflows.
  • Creates tools/governance/profiles/angular-cleanup.json with sensible defaults (if it does not already exist).
  • Optionally runs the eslint-integration generator (prompted, default: yes).

Options:

| Option | Type | Default | Description | | ----------------- | --------- | ------- | ---------------------------------------------------------------------------- | | configureEslint | boolean | true | Generate the ESLint integration helper and wire it into eslint.config.mjs. | | skipFormat | boolean | false | Skip Prettier formatting of generated files. |


eslint-integration generator

Generates the shared runtime policy module that prevents drift between ESLint module-boundary enforcement and governance boundary rules.

nx g @anarchitects/nx-governance:eslint-integration

What it does, in order:

  1. Migrates any existing inline depConstraints array from eslint.config.mjs into tools/governance/profiles/angular-cleanup.json. This happens before ESLint is modified, making the profile the authoritative source first.
  2. Writes tools/governance/eslint/dependency-constraints.mjs — a pure ES module that reads all governance profile JSON files at import time, merges their allowedDomainDependencies maps, and exports a governanceDepConstraints array in the shape that @nx/enforce-module-boundaries expects.
  3. Patches eslint.config.mjs to import governanceDepConstraints from the helper and use it as the depConstraints value, replacing any previous inline array.

After running this generator, adding or changing domain dependency rules in a profile JSON automatically updates both governance reports and ESLint enforcement on the next run — with no manual synchronisation required.

Options:

| Option | Type | Default | Description | | ------------ | --------- | ------- | -------------------------------------------- | | skipFormat | boolean | false | Skip Prettier formatting of generated files. |


Executors

Base options used by governance and AI executors:

| Option | Type | Default | Description | | ----------------- | ------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------- | | profile | string | "angular-cleanup" | Name of the governance profile to load from tools/governance/profiles/. | | output | "cli" | "json" | "cli" | Output format. cli prints a human-readable report via Nx logger. json writes structured JSON to stdout. | | failOnViolation | boolean | false | Exit with a non-zero code when any violation is found. Use this to gate CI. |

Additional options are listed per command where applicable (snapshotDir, snapshotPath, topViolations, topProjects, baseRef, headRef, ...).

repo-health

Intent: Give a full workspace health overview — the "dashboard" view. Every metric is computed and combined into a single weighted score with a letter grade.

nx repo-health
nx repo-health --output=json
nx repo-health --failOnViolation

Metrics included: all six (Architectural Entropy, Dependency Complexity, Domain Integrity, Ownership Coverage, Documentation Completeness, Layer Integrity).

Use when: you want a single number that summarises overall workspace quality, or when running a health gate in CI.


repo-boundaries

Intent: Focus exclusively on structural boundary violations — where the project graph breaks the declared domain and layer contracts.

nx repo-boundaries
nx repo-boundaries --output=json --failOnViolation

Metrics included: Architectural Entropy, Domain Integrity, Layer Integrity.

Violations surfaced:

  • domain-boundary (severity: error) — a project in domain A imports a project in domain B, and B is not listed in A's allowedDomainDependencies.
  • layer-boundary (severity: warning) — a project at layer position i imports a project at a higher-level layer position j < i.

Use when: doing an architecture review, onboarding a new domain, or validating that a refactor did not introduce forbidden cross-domain imports.


repo-ownership

Intent: Report which projects lack a clear owner and surface the merged ownership map across metadata and CODEOWNERS.

nx repo-ownership
nx repo-ownership --output=json

Metrics included: Ownership Coverage.

Violations surfaced:

  • ownership-presence (severity: warning) — a project has neither an ownership.team metadata field nor a matching CODEOWNERS entry.

Use when: running an incident post-mortem, onboarding a new team member, or auditing accountability across a growing monorepo.


repo-architecture

Intent: Report on structural complexity and entropy without the ownership signal — purely the architectural topology health.

nx repo-architecture
nx repo-architecture --output=json

Metrics included: Architectural Entropy, Dependency Complexity, Domain Integrity.

Violations surfaced: all violation types except ownership-presence.

Use when: you want to track architectural drift over time and are not concerned with team assignment in this particular run.


repo-snapshot

Intent: Persist a point-in-time governance snapshot for trend and drift analysis.

nx repo-snapshot
nx repo-snapshot --output=json
nx repo-snapshot --snapshotDir=.governance-metrics/snapshots

Additional options:

  • snapshotDir (default: .governance-metrics/snapshots)
  • metricSchemaVersion (default: 1.0)

Use when: you want historical governance baselines for CI trend monitoring and AI analysis.


repo-drift

Intent: Compare two snapshots and classify drift signals as improving, stable, or worsening.

nx repo-drift
nx repo-drift --output=json
nx repo-drift --baseline=.governance-metrics/snapshots/<older>.json --current=.governance-metrics/snapshots/<newer>.json

Additional options:

  • snapshotDir (default: .governance-metrics/snapshots)
  • baseline (optional explicit baseline snapshot path)
  • current (optional explicit current snapshot path)

Use when: you need deterministic drift trend signals from recent governance runs.


repo-ai-root-cause

Intent: Build deterministic root-cause payloads from prioritized violations and graph context.

nx repo-ai-root-cause --output=json
nx repo-ai-root-cause --snapshotPath=.governance-metrics/snapshots/<file>.json --topViolations=10

Additional options: snapshotDir, snapshotPath, topViolations.

Model 1 handoff artifacts:

  • .governance-metrics/ai/root-cause.payload.json
  • .governance-metrics/ai/root-cause.prompt.md

After command execution, the CLI prints concise usage instructions for external AI assistants. The plugin does not call provider APIs directly; developers paste the generated prompt and payload into their assistant of choice.


repo-ai-drift

Intent: Prepare deterministic drift interpretation payloads from snapshot deltas and trend signals.

nx repo-ai-drift --output=json
nx repo-ai-drift --baseline=.governance-metrics/snapshots/<older>.json --current=.governance-metrics/snapshots/<newer>.json

Additional options: snapshotDir, baseline, current.

Model 1 handoff artifacts:

  • .governance-metrics/ai/drift.payload.json
  • .governance-metrics/ai/drift.prompt.md

repo-ai-pr-impact

Intent: Build deterministic PR impact payloads from git diff scope and dependency signals.

nx repo-ai-pr-impact --output=json
nx repo-ai-pr-impact --baseRef=main --headRef=HEAD

Additional options: baseRef, headRef.

Model 1 handoff artifacts:

  • .governance-metrics/ai/pr-impact.payload.json
  • .governance-metrics/ai/pr-impact.prompt.md

repo-ai-cognitive-load

Intent: Build deterministic cognitive-load payloads from fanout, coupling, and scope breadth.

nx repo-ai-cognitive-load --output=json
nx repo-ai-cognitive-load --domain=orders --topProjects=10
nx repo-ai-cognitive-load --project=orders-state

Additional options: project, domain, topProjects.


repo-ai-recommendations

Intent: Generate deterministic architecture recommendations from prioritized violations and trend signals.

nx repo-ai-recommendations --output=json
nx repo-ai-recommendations --topViolations=10

Additional options: snapshotDir, topViolations.


repo-ai-smell-clusters

Intent: Cluster deterministic architecture smell signals and highlight persistent patterns.

nx repo-ai-smell-clusters --output=json
nx repo-ai-smell-clusters --topViolations=10

Additional options: snapshotDir, topViolations.


repo-ai-refactoring-suggestions

Intent: Produce deterministic refactoring suggestions from hotspots, fanout pressure, and persistence signals.

nx repo-ai-refactoring-suggestions --output=json
nx repo-ai-refactoring-suggestions --topViolations=10 --topProjects=5

Additional options: snapshotDir, topViolations, topProjects.


repo-ai-scorecard

Intent: Prepare deterministic governance scorecards from health, violations, and drift trend metadata.

nx repo-ai-scorecard --output=json
nx repo-ai-scorecard --snapshotPath=.governance-metrics/snapshots/<file>.json

Additional options: snapshotDir, snapshotPath.

Model 1 handoff artifacts:

  • .governance-metrics/ai/scorecard.payload.json
  • .governance-metrics/ai/scorecard.prompt.md

repo-ai-onboarding

Intent: Prepare deterministic onboarding briefs from repo shape, hotspots, and ownership coverage signals.

nx repo-ai-onboarding --output=json
nx repo-ai-onboarding --topViolations=10 --topProjects=5

Additional options: topViolations, topProjects.

Use when: onboarding engineers who need a deterministic architecture overview before making changes.


Reports explained

Health score and grade

Every executor computes a health score from 0–100 and assigns a letter grade:

| Score | Grade | Interpretation | | ------ | ----- | -------------------------------------------------------- | | 90–100 | A | Healthy — architecture aligns well with declared intent. | | 80–89 | B | Good — minor issues present, worth addressing. | | 70–79 | C | Acceptable — some structural debt accumulating. | | 60–69 | D | Concerning — multiple signals degraded. | | 0–59 | F | Critical — significant structural violations present. |

The score is a weighted average of individual metric scores. Weights are configured per-profile under metrics.*Weight. Equal weights (0.2 each) are the default, meaning each metric contributes evenly. Raise a weight to make a particular concern more influential in the overall grade.

Any metric scoring below 60 is listed as a hotspot in both CLI and JSON output.

Metrics

| Metric id | Name | Direction | Formula | | ---------------------------- | -------------------------- | ---------------- | ---------------------------------------------------------------------- | | architectural-entropy | Architectural Entropy | lower is better | (total violations) / max(total dependencies, 1) → inverted to score | | dependency-complexity | Dependency Complexity | lower is better | (total dependencies) / (projects × 4) → inverted to score | | domain-integrity | Domain Integrity | lower is better | (domain violations) / max(total dependencies, 1) → inverted to score | | ownership-coverage | Ownership Coverage | higher is better | (owned projects) / (total projects) → direct score | | documentation-completeness | Documentation Completeness | higher is better | (documented projects) / (total projects) → direct score | | layer-integrity | Layer Integrity | lower is better | (layer violations) / max(total dependencies, 1) → inverted to score |

All raw values are bounded to [0, 1] before scoring. "Lower is better" metrics are scored as (1 − value) × 100. "Higher is better" metrics are scored as value × 100.

How to interpret metrics

Use the overall health score for prioritization, then make decisions at the metric level.

| Metric | What it measures in practice | Watch signal | First remediation moves | | --- | --- | --- | --- | | architectural-entropy | Density of policy violations relative to dependency volume. | Rising entropy with stable project count usually means boundary discipline is eroding. | Triage top violation clusters, fix highest-fanout offenders first, then add CI gates for recurring rule ids. | | dependency-complexity | How connected the workspace is compared with its size. | High complexity with frequent cross-domain work indicates large blast radius risk. | Reduce fanout in shared nodes, split overloaded libraries, tighten public APIs. | | domain-integrity | Fraction of dependencies that break domain constraints. | Any sustained increase usually signals implicit coupling between domains. | Introduce explicit inter-domain contracts, route integrations through APIs, align reviews to domain ownership. | | ownership-coverage | Portion of projects with explicit ownership metadata or CODEOWNERS coverage. | Coverage below target slows incident response and architecture decisions. | Fill ownership gaps first in hotspot projects, then enforce ownership checks in CI. | | documentation-completeness | Portion of projects with documented architecture/context metadata. | Low documentation on high-change projects increases onboarding and regression risk. | Prioritize docs for critical and high-fanout projects, add minimum documentation policy for new projects. | | layer-integrity | Fraction of dependencies violating layer ordering rules. | Repeated layer leaks often precede test brittleness and circular dependency pressure. | Introduce layer-facing interfaces, move implementation details downward, block upward imports in lint and governance checks. |

Quick threshold guide

These are operating heuristics for decision-making (not hard scientific cutoffs):

  • Score >= 85: healthy, optimize selectively and prevent regressions.
  • Score 70-84: acceptable but trending risk, prioritize top 1-2 weakest metrics.
  • Score < 70: intervention zone, create a short burn-down plan tied to violation clusters.

Metric-specific caution points:

  • domain-integrity or layer-integrity below 80: treat as structural risk, not cosmetic debt.
  • ownership-coverage below 90 in fast-moving repos: likely coordination bottleneck.
  • dependency-complexity falling while entropy rises: architecture may be simplifying graph shape but still violating contracts.

Trend interpretation

  • Prefer trend direction over one-off snapshots: 3-4 consecutive worsening runs are more actionable than a single dip.
  • Small fluctuations can be noise after large refactors; focus on persistent movement and recurring hotspots.
  • If overall score improves while one integrity metric worsens, treat that metric as a targeted follow-up item.

Score caveat

The health score is a weighted heuristic summary, not a substitute for metric-level analysis. Always validate decisions against the weakest metrics, top violations, and hotspot projects before planning remediation work.

Violations

Each violation carries:

| Field | Meaning | | ---------------- | ------------------------------------------------------------------------------ | | id | Unique identifier for the violation instance (e.g. billing-payments-domain). | | ruleId | One of domain-boundary, layer-boundary, ownership-presence. | | project | The source project name. | | severity | error for hard boundary breaks, warning for soft signals. | | message | Human-readable description of the specific violation. | | details | Structured data (source/target domain, layer order, dependency type). | | recommendation | Actionable guidance for resolving the violation. |

Recommendations

Recommendations are generated automatically from the violation and metric set:

| id | Trigger | Priority | | ---------------------------------- | --------------------------------------------- | -------- | | reduce-cross-domain-dependencies | Any domain-boundary violation present | high | | improve-ownership-coverage | Any ownership-presence violation present | medium | | reduce-dependency-complexity | dependency-complexity metric score below 60 | medium |

Warnings

Warnings appear when the assessment contains important context that is not itself a policy violation. The most common warning is:

Boundary policy source is ESLint constraints (tools/governance/eslint/dependency-constraints.mjs). Profile allowedDomainDependencies is treated as fallback.

This is emitted whenever boundaryPolicySource is set to "eslint", reminding consumers that the live boundary rules are being read from the ESLint helper rather than the static profile JSON.

JSON output schema

When --output=json is used, the full GovernanceAssessment is written to stdout:

{
  "profile": "angular-cleanup",
  "warnings": ["..."], // runtime warnings
  "workspace": {
    "id": "workspace",
    "projects": [
      {
        "name": "billing-api",
        "root": "packages/billing-api",
        "type": "library",
        "tags": ["domain:billing", "layer:data-access"],
        "domain": "billing",
        "layer": "data-access",
        "ownership": {
          "team": "@org/billing",
          "contacts": ["@org/billing"],
          "source": "merged" // "project-metadata" | "codeowners" | "merged" | "none"
        }
      }
    ],
    "dependencies": [
      { "source": "billing-api", "target": "shared-utils", "type": "static" }
    ]
  },
  "violations": [
    {
      "id": "billing-api-payments-api-domain",
      "ruleId": "domain-boundary",
      "project": "billing-api",
      "severity": "error",
      "message": "Project billing-api in domain billing depends on payments-api in domain payments.",
      "details": { "sourceDomain": "billing", "targetDomain": "payments" },
      "recommendation": "Move the dependency behind an API or adjust domain boundaries."
    }
  ],
  "measurements": [
    {
      "id": "ownership-coverage",
      "name": "Ownership Coverage",
      "value": 0.857,
      "score": 86,
      "maxScore": 100,
      "unit": "ratio"
    }
  ],
  "health": {
    "score": 91,
    "grade": "A",
    "hotspots": []
  },
  "recommendations": [
    {
      "id": "reduce-cross-domain-dependencies",
      "title": "Reduce cross-domain dependencies",
      "priority": "high",
      "reason": "..."
    }
  ]
}

Profile reference

// tools/governance/profiles/angular-cleanup.json
{
  // "profile" | "eslint"
  // "eslint" reads boundary rules from tools/governance/eslint/dependency-constraints.mjs
  "boundaryPolicySource": "eslint",

  // Ordered layer hierarchy — lower index = higher architectural level
  "layers": ["app", "feature", "ui", "data-access", "util"],

  // Which domains may depend on which. An empty array means no cross-domain imports.
  // Use "*" as source key for a wildcard rule applied to all domains.
  // Use "*" as a value to allow any target domain.
  "allowedDomainDependencies": {
    "billing": ["shared"],
    "payments": ["shared"],
    "shared": []
  },

  "ownership": {
    "required": true, // raise ownership-presence violations when true
    "metadataField": "ownership"
  },

  // Per-metric weight in the overall health score (must be > 0, relative scale)
  "metrics": {
    "architecturalEntropyWeight": 0.2,
    "dependencyComplexityWeight": 0.2,
    "domainIntegrityWeight": 0.2,
    "ownershipCoverageWeight": 0.2,
    "documentationCompletenessWeight": 0.2
  },

  // Per-project overrides — useful for projects that cannot carry tags or metadata
  "projectOverrides": {
    "legacy-monolith": {
      "domain": "billing",
      "layer": "app",
      "ownershipTeam": "@org/billing",
      "documentation": true
    }
  }
}

ESLint alignment

Running the eslint-integration generator creates a shared runtime policy module at tools/governance/eslint/dependency-constraints.mjs. This module:

  1. Reads all tools/governance/profiles/*.json files at import time.
  2. Merges their allowedDomainDependencies maps.
  3. Converts each domain:X → [domain:Y, ...] entry into an @nx/enforce-module-boundaries depConstraint object.
  4. Exports the resulting array as governanceDepConstraints.

Your eslint.config.mjs imports and uses this export directly:

import { governanceDepConstraints } from './tools/governance/eslint/dependency-constraints.mjs';

export default [
  // ...
  {
    files: ['**/*.ts', '**/*.js'],
    rules: {
      '@nx/enforce-module-boundaries': [
        'error',
        {
          enforceBuildableLibDependency: true,
          depConstraints: governanceDepConstraints,
        },
      ],
    },
  },
];

The consequence: changing a domain rule in a profile JSON propagates automatically to both ESLint enforcement (on the next lint run) and governance reporting (on the next repo-boundaries run). No manual synchronisation, no drift.

When boundaryPolicySource is "eslint" in a profile, the governance executor also imports this module at runtime to use the same resolved constraint set as the active boundary policy, ensuring reports and lint share identical semantics.


CI integration

To fail a pipeline when governance violations are present:

# .github/workflows/ci.yml
- name: Governance health gate
  run: yarn nx repo-health --failOnViolation

- name: Boundary enforcement gate
  run: yarn nx repo-boundaries --failOnViolation

To archive the JSON report as a build artefact:

- name: Generate governance report
  run: yarn nx repo-health --output=json > governance-report.json

- uses: actions/upload-artifact@v4
  with:
    name: governance-report
    path: governance-report.json

To track health score trends over time, pipe the JSON output into your observability platform or store it alongside test coverage reports for historical comparison.