Shift quality from manual review to executable change guardrails.
Choose one installation path:
/plugin marketplace add phodal/entrix
/plugin install entrix@entrixRestart Claude Code after plugin installation.
uv tool install entrix
# or
pip install entrix
entrix --helpIf you want Claude Code MCP integration in the current repository after installing the CLI:
entrix install --repo .Requires Python 3.10+. uv is only needed for the uv / uvx workflow.
What it does
- codify quality gates and architecture constraints as reusable fitness specs
- run checks by
fast/normal/deeptiers - run change-aware checks on diffs with weighted scoring and hard gates
- route risky changes to deeper validation with
review-trigger - optionally add graph-based impact, test-radius, and review context analysis
Guardrails in the change lifecycle
- checks run before risky code lands
- each run generates evidence
- policy can hard-stop, warn, or escalate to human review automatically
Additional design context:
tools/entrix/docs/adr/README.md: Entrix architecture decisions and rationale
- Python 3.10+
- Git repository context for commands that use
--base HEAD~1
Optional:
uvforuv tool install ...anduvx ...pip install entrix[graph]for graph commands
CLI invocation options
uv tool install entrix
# or
pip install entrix
uvx entrix --help
uvx entrix run --tier fast
uvx entrix run --tier normal --stream failures
uvx entrix run --tier normal --stream all
uvx entrix review-trigger --base HEAD~1Optional extras
pip install entrix[graph]
pip install entrix[mcp]
pip install entrix[dev]
uvx entrix install --repo .By default, entrix run looks for specs under the current project's:
docs/fitness/*.md
When docs/fitness/manifest.yaml is present, Entrix uses the manifest as the
source of truth. That allows nested evidence files such as
docs/fitness/runtime/observability.md and docs/fitness/runtime/performance.md.
Example docs/fitness/code-quality.md:
---
dimension: code_quality
weight: 20
threshold:
pass: 90
warn: 80
metrics:
- name: lint
command: npm run lint 2>&1
hard_gate: true
tier: fast
description: ESLint must pass
- name: unit_tests
command: npm run test:run 2>&1
pattern: "Tests\\s+\\d+\\s+passed"
hard_gate: true
tier: normal
description: unit tests must pass
---
# Code Quality
Narrative evidence, rules, and ownership notes can live below the frontmatter.Beyond the basic fields shown above, each metric in the frontmatter supports additional options:
metrics:
- name: api_contract
command: npm run test:contract 2>&1
hard_gate: false
tier: normal
description: API contract tests
# Execution scope — where this metric is authoritative
# Values: local, ci, staging, prod_observation
execution_scope: ci
# Timeout in seconds (null = no limit)
timeout_seconds: 120
# Gate severity: hard, soft, advisory
gate: soft
# Evidence type: command, test, probe, sarif, manual_attestation
evidence_type: test
# Confidence level: high, medium, low, unknown
confidence: high
# Signal stability: deterministic, noisy
stability: deterministic
# Fitness kind: atomic (single check) or holistic (system-wide)
kind: atomic
# Analysis mode: static (code structure) or dynamic (runtime)
analysis: dynamic
# Owner responsible for this metric
owner: team-platform
# Only run when these file patterns change
run_when_changed:
- "src/api/**"
- "openapi.yaml"
# Temporary waiver to bypass a failing metric
waiver:
reason: "Known flaky test, fix tracked in issue #42"
owner: team-platform
tracking_issue: 42
expires_at: "2025-06-01"entrix run --tier fast
entrix run --tier normal
entrix run --tier normal --scope ci --dimension code_quality --dimension testability
entrix run --tier fast --metric eslint_pass --metric ts_typecheck_pass
entrix run --changed-only --base HEAD~1
entrix validateUse --metric when you want to run only specific metric names without creating a temporary dimension file split. Commands that use --base HEAD~1 must run inside a git repository with a valid base revision.
By default, review-trigger loads the current project's:
docs/fitness/review-triggers.yaml
Example docs/fitness/review-triggers.yaml:
review_triggers:
- name: high_risk_directory_change
type: changed_paths
paths:
- src/core/acp/**
- src/core/orchestration/**
- services/api/**
severity: high
action: require_human_review
- name: oversized_change
type: diff_size
max_files: 12
max_added_lines: 600
max_deleted_lines: 400
severity: medium
action: require_human_reviewRun it:
entrix review-trigger --base HEAD~1
entrix review-trigger --base HEAD~1 --jsonExample output:
{
"human_review_required": true,
"base": "HEAD~1",
"changed_files": [
"services/api/src/routes/acp_routes.rs"
],
"diff_stats": {
"file_count": 13,
"added_lines": 936,
"deleted_lines": 20
},
"triggers": [
{
"name": "high_risk_directory_change",
"severity": "high",
"action": "require_human_review",
"reasons": [
"changed path: services/api/src/routes/acp_routes.rs"
]
}
]
}If you are using the copy of entrix vendored in the Routa.js monorepo, the
current repository workflow is:
pip install -e tools/entrix
PYTHONPATH=tools/entrix python3 -m entrix --help
PYTHONPATH=tools/entrix python3 -m entrix run --tier fast
PYTHONPATH=tools/entrix python3 -m entrix review-trigger --base HEAD~1Most local hooks and helper scripts in this repository use the
PYTHONPATH=tools/entrix python3 -m entrix ... form so they can run directly
from the monorepo checkout without requiring a separately installed global
binary.
If you are working on the entrix package source itself, clone this repository and install it from the repository root.
From the repository root:
git clone https://github.com/phodal/entrix.git
cd entrix
uv pip install -e .With pip:
git clone https://github.com/phodal/entrix.git
cd entrix
pip install -e .Most repositories only need these three commands:
entrix run: execute fitness checks fromdocs/fitness/*.mdentrix validate: validate the fitness configurationentrix review-trigger: escalate risky diffs to human review
Use entrix analyze long-file for oversized-file structure analysis and entrix graph ... for graph-backed impact analysis.
Entrix includes copyable examples under examples/:
examples/file-length-hook/: pre-commit file budget hookexamples/frontend-quality-pack/: layered frontend quality gates with review-trigger guidance
Runs dimension-based fitness checks loaded from docs/fitness/*.md.
Common flags:
entrix run --tier fast
entrix run --parallel
entrix run --dry-run
entrix run --verbose
entrix run --format ascii
entrix run --format rich
entrix run --changed-only --base HEAD~1
entrix run --files src/app.ts src/lib.ts
entrix run --output report.json
entrix run --output - # JSON to stdout
entrix run --min-score 90Use --output to write a JSON report to a file (or - for stdout), useful for CI artifact collection. Use --files to pass an explicit list of changed files for incremental metric selection. Use --format ascii for a zero-dependency visual scorecard, or --format rich for richer terminal rendering when rich is installed (pip install entrix[visual]).
Generate .mcp.json for Claude Code MCP integration in a target repository.
entrix install --repo .
entrix init --dry-runRun the Entrix MCP server over stdio.
entrix serveChecks that dimension weights sum to 100%.
entrix validateEvaluates governance-oriented trigger rules for risky changes.
Common flags:
entrix review-trigger --base HEAD~1
entrix review-trigger --json
entrix review-trigger --fail-on-trigger
entrix review-trigger --config docs/fitness/review-triggers.yamlStructural analysis for oversized or explicit source files. Returns ClassMap / FunctionMap payloads showing classes, methods, and standalone functions with line spans.
Supported languages: Python, Rust, Go, Java, and TypeScript/JavaScript
(including tsx / jsx files).
entrix analyze long-file --files src/app.ts src/lib.ts
entrix analyze long-file --json
entrix analyze long-file --config file_budgets.json --strict-limit
entrix analyze long-file --min-lines 100When no --files are given, the command auto-discovers files that exceed their configured line budget.
Graph-backed commands support building the code graph, querying relationships, impact analysis, test radius estimation, commit history analysis, and AI-friendly review context generation.
Requires the optional graph dependency: pip install entrix[graph].
Build or update the code graph.
entrix graph build --base HEAD~1
entrix graph build --build-mode full --jsonShow graph statistics (node and edge counts).
entrix graph stats
entrix graph stats --jsonAnalyze the blast radius of changed files.
entrix graph impact --base HEAD~1
entrix graph impact --base HEAD~1 --depth 3 --jsonEstimate which tests are affected by changed files.
entrix graph test-radius --base HEAD~1
entrix graph test-radius --base HEAD~1 --max-targets 50 --jsonRun a structural query against the code graph.
Available patterns: callers_of, callees_of, imports_of, importers_of, children_of, tests_for, inheritors_of, file_summary.
entrix graph query callers_of "mymodule.MyClass.my_method"
entrix graph query tests_for "src/core/engine.py" --jsonEstimate test radius for recent commits using the current graph.
entrix graph history --count 20 --ref main
entrix graph history --jsonBuild an AI-friendly review context from the current graph.
entrix graph review-context --base HEAD~1 --json
entrix graph review-context --base HEAD~1 --max-files 20 --no-source
entrix graph review-context --base HEAD~1 --output context.jsonEntrix uses a preset system to adapt behavior to different project layouts. The default ProjectPreset looks for fitness specs in docs/fitness/ and review triggers in docs/fitness/review-triggers.yaml.
Custom presets can override:
fitness_dir(project_root)— where to find fitness spec filesreview_trigger_config(project_root)— path to the review trigger YAMLshould_ignore_changed_file(file_path)— filter out irrelevant changed filesdomains_from_files(files)— extract domain tags from changed file paths
A built-in RoutaPreset is included as a reference implementation for monorepo layouts.
If an AI agent is generating or updating fitness specs, these conventions work best:
- keep one dimension per file
- make the frontmatter executable and the body explanatory
- prefer stable command outputs over fragile text matching
- use
hard_gate: trueonly when failure should really block progress - keep review-trigger rules separate from scoring metrics
- treat markdown as the narrative layer, not the only source of structure
Recommended file layout:
your-project/
docs/
fitness/
README.md
manifest.yaml
code-quality.md
security.md
runtime/
observability.md
performance.md
review-triggers.yaml
Minimal bootstrap flow for a new repository:
mkdir -p docs/fitness
cat > docs/fitness/code-quality.md <<'EOF'
---
dimension: code_quality
weight: 100
threshold:
pass: 100
warn: 80
metrics:
- name: lint
command: npm run lint 2>&1
hard_gate: true
tier: fast
---
# Code Quality
EOF
entrix validate
entrix run --tier fastBootstrap authoring rules:
- keep default local
entrix rungreen on a fresh machine - if a command is authoritative only in CI or a provisioned environment, model
it with
execution_scope: ciinstead of leaving it in the default local path - update every existing agent entry document consistently:
AGENTS.md,CLAUDE.md, or both - if neither entry document exists, create only
AGENTS.md
Recommended bootstrap policy:
- do not stop at a plausible draft; the bootstrap is done only after local
entrix validateand plain localentrix runpass - keep default local runs backed by repo-safe wrappers or cheap smoke checks
- move authoritative but provisioned checks into
execution_scope: ci - treat
AGENTS.mdandCLAUDE.mddiscoverability as part of the bootstrap, not optional follow-up cleanup
The repository also ships a bundled skill at skills/entrix/ for agents that
need to generate or repair docs/fitness/ automatically. The skill follows the
same bootstrap rules above and is validated against multiple real repositories.
The bundled /entrix skill ships with two regression modes:
bash scripts/skill_regression.sh --fixtures
bash scripts/skill_regression.sh /abs/path/to/repo-a /abs/path/to/repo-b--fixturesvalidates bundled repository profiles undertests/fixtures/skill_regression/- path mode injects the bundled skill into each target repository, runs
claude -p /entrix, then verifies the result withentrix validate,entrix run --dry-run,entrix run --tier fast, and plainentrix run
Use fixture mode in CI and path mode for local forward validation against real repositories before publishing skill changes.
from pathlib import Path
from entrix.review_trigger import (
collect_changed_files,
collect_diff_stats,
evaluate_review_triggers,
load_review_triggers,
)
repo_root = Path(".").resolve()
rules = load_review_triggers(repo_root / "docs" / "fitness" / "review-triggers.yaml")
changed_files = collect_changed_files(repo_root, "HEAD~1")
diff_stats = collect_diff_stats(repo_root, "HEAD~1")
report = evaluate_review_triggers(rules, changed_files, diff_stats, base="HEAD~1")
print(report.to_dict())from pathlib import Path
from entrix.evidence import load_dimensions
dimensions = load_dimensions(Path("docs/fitness"))
for dimension in dimensions:
print(dimension.name, len(dimension.metrics))For generic repositories, a practical pattern is:
pre-commit: runentrix hook file-lengthfirst, then quick lintpre-push: run full checks, then print review-trigger warnings- CI: run
entrix runand publish JSON/report output
That lets automation catch deterministic failures early while still escalating ambiguous risky changes to humans.
The current Routa.js monorepo intentionally uses a slightly different split:
pre-commit:npm run lintpost-commit:PYTHONPATH=tools/entrix python3 -m entrix hook file-length --config tools/entrix/file_budgets.pre_commit.json --strict-limit ...as a warning-only budget reportpre-push:./scripts/smart-check.sh, which runs a curatedentrix run --metric ...set and then evaluatesreview-trigger
This keeps commit-time friction low while still surfacing file-budget drift and enforcing the higher-signal fitness gates before push.
If Entrix is vendored into a larger repository as a git submodule:
- push the Entrix release commit first from a clean
tools/entrixworktree - update the superproject pointer in its own commit
- prefer a clean superproject branch or worktree for the pointer bump so unrelated application fitness hooks do not block a pure submodule update
This keeps Entrix releases and superproject pointer bumps reviewable as separate changes.
entrix now exposes a reusable hook entrypoint:
python3 -m entrix hook file-length \
--config tools/entrix/file_budgets.pre_commit.json \
--staged-only \
--strict-limitUse it when you want AI-friendly oversized-file failures during pre-commit, for example:
current file length 2383 exceeds limit 1600: src/app/page.tsx
A copy-pasteable template lives in examples/file-length-hook/.
Current state:
- stable for production use in real repository workflows
- installable as a standalone PyPI package
- suitable for AI-assisted project configuration
Current boundaries:
- the default authoring format is markdown frontmatter under
docs/fitness - graph commands require the optional graph dependency:
pip install entrix[graph] - the current public CLI in this checkout exposes
run,validate,review-trigger,hook,analyze, andgraph analyze long-filestructural analysis supports Python, Rust, Go, Java, TypeScript, and JavaScript- the internal architecture is still evolving toward a cleaner core / adapter / preset split
See CONTRIBUTING.md for development guidelines and contribution workflow.
This project is licensed under the MIT License. See LICENSE for details.