AI‑generated code often drifts after a few iterations: functions disappear, imports become stale, and quality metrics degrade without a concrete signal. Developers need a fast, language‑agnostic way to surface structural health so an agent can correct itself before the breakage reaches production.
What This Does
sentrux ships a single native binary (built from the sent‑rux‑bin crate) that scans a project with 52 tree‑sitter language plugins (see plugins/*/plugin.toml). It builds a dependency graph, computes metrics (fan‑in/out, modularity, DSM), and exposes a real‑time UI. Core analysis lives in sent‑rux‑core/src/analysis/* and the UI in sent‑rux‑core/src/app/*. The CLI entry points are sent‑rux‑bin/src/main.rs (calls run in main_impl.rs) and sent‑rux‑bin/src/lib.rs which expose the library API.
How It Is Wired
Execution starts at sent‑rux‑bin/src/main.rs:1 → main. main invokes run defined in sent‑rux‑bin/src/main_impl.rs:178. run traverses 257 functions, most of which are in the core crate:
insert (called from 78 places) and entry (43 places) are the primary registry mutators; they live in sent‑rux‑core/src/analysis/resolver/suffix.rs and sent‑rux‑core/src/analysis/lang_registry.rs.
compute_health (40 callers) aggregates metric scores in sent‑rux‑core/src/metrics/mod.rs.
build_graphs (33 callers) and snap_with_edges (30 callers) construct the structural graph (sent‑rux‑core/src/analysis/graph/mod.rs).
The most central module is sent‑rux‑core/src/analysis/parser/mod.rs (22 functions, referenced by 36 files). It parses source files and hands AST nodes to the resolver. The UI panels (dsm_panel.rs, metrics_panel.rs, etc.) render the graph but do not own core logic.
No circular import edges were detected, but three files (suffix.rs, main_impl.rs, metrics/mod.rs) exceed 800 lines and contain nesting depths of eight, making changes high‑risk. Duplicated 6‑line blocks appear in 18 files (e.g., test suites and panel code), inflating maintenance cost.
How To Use It
# Clone the exact repo
git clone https://github.com/moses-y/sentrux.git
cd sentrux
# Build the release binary
cargo build --release # produces target/release/sentrux
# Run the GUI on the current directory
./target/release/sentrux
# Run a CI‑friendly check (exit code 0/1)
./target/release/sentrux check .
Configuration files live under .sentrux/ (e.g., rules.toml) and can be edited to add custom quality rules. The binary respects --mcp to expose a Model‑Context‑Protocol server, as described in the README.
Real‑World Use
A CI pipeline can invoke sentrux check . after a pull request; the exit status blocks merges when health drops. An autonomous coding agent can keep a baseline with sentrux gate --save . before a generation cycle, then call sentrux gate . after the agent finishes to detect regressions and feed the diff back into its prompting loop.
Code Health & Issues
Critical – privileged checkout of PR code in .github/workflows/ci-release.yml. High – unpinned actions (softprops/action-gh-release@v2, dtolnay/rust-toolchain@stable). High – steps discard exit codes or use continue-on-error in .github/workflows/build-grammars.yml. High – lacking least‑privilege GITHUB_TOKEN permissions. Medium – no Dependabot setup. Medium – no dependency‑vulnerability scan in CI. Medium – large binary assets (demo.gif 8.9 MiB) should be moved to LFS. Medium – checkout keeps credentials; set persist-credentials: false. Medium – test coverage low (22 test files vs. 121 source files). Medium – deep nesting (max depth 8) in suffix.rs, main_impl.rs, graph/mod.rs. Medium – duplicated 6‑line blocks across 18 files. Low – three stray TODO/FIXME markers in main_impl.rs.
The Bottom Line
sentrux provides a functional Rust‑based sensor that can feed real‑time architectural metrics into AI‑assisted development workflows. The core is well‑structured, but several large, deeply nested modules and duplicated code raise the maintenance burden, and the CI configuration contains serious security gaps. Teams comfortable with Rust and willing to tighten the CI pipelines will benefit most.
Ranked by severity × confidence × production reach. Reach is the honest discriminator across a collection that is mostly other people's code: the same finding matters more in something that ships.
critical1
high3
medium6
low1
Do not check out pull request code in a privileged workflowcritical
.github/workflows/ci-release.yml
privileged trigger checks out the untrusted ref
This is the most reliably exploited Actions pattern: anyone opening a pull request gets code execution with your repository secrets.
Fix: Split into an unprivileged pull_request build and a workflow_run job that only consumes its artifact.
Pin third-party GitHub Actions to a commit SHAhigh2 occurrences
A tag can be moved, so the action running with your token and secrets is whatever its owner last pushed; this is how tj-actions/changed-files leaked secrets from thousands of repos.
Fix: Replace each @vN with the 40-character commit SHA, keep # vN as a comment, and let Dependabot bump the SHAs.
Stop discarding the exit code of steps whose failure mattershigh
.github/workflows/build-grammars.yml
lines 101 discard failure
The job reports green while the artifact it was supposed to produce was never produced, so a crash becomes a successful run built on stale data.
Fix: Let the step fail, or test the specific expected condition instead of discarding all exit codes.
Remove continue-on-error from steps that gate correctnesshigh
.github/workflows/build-grammars.yml
line 178 on a correctness step
A failing test suite reports a green check, which is precisely the path this audit exists to close.
Fix: Delete continue-on-error, or move a genuinely advisory step into a separate non-required job.
Declare least-privilege permissions for GITHUB_TOKENmedium2 occurrences
.github/workflows/ci-release.yml
2 workflow(s) declare no permissions
With no declaration the token inherits the repository default, so any injected step can push commits or mint releases from inside your own CI.
Fix: Add permissions: contents: read at the top of the workflow and widen per job only where needed.
Enable Dependabot or Renovatemedium
3 manifest(s), no update bot configured
Without a bot a published advisory sits unpatched until someone audits by hand, which across 1,322 repositories means never.
Fix: Commit .github/dependabot.yml covering the repo ecosystems plus github-actions.
Gate pull requests on a dependency vulnerability scanmedium
.github/workflows
no dependency scan in CI
This is the one gate that would catch a known-vulnerable package before it reaches a build, and no repository in the sample had it.
Fix: Add dependency-review-action on pull_request, or osv-scanner on push and a schedule.
Move large binaries to Git LFS or out of the repositorymedium
assets/demo.gif
1 blobs over 5MB: demo.gif 8.9MB
One repository here carries twenty blobs over 5MB including a 10.9MB spreadsheet, so every clone and every CI checkout pays for data nobody diffs.
Fix: Track those extensions with LFS, or move datasets to object storage and fetch them in a setup step.
Set persist-credentials: false on checkoutmedium
.github/workflows/build-grammars.yml
checkout keeps the token, then dependencies are installed
The token stays in .git/config for every later step, so a malicious postinstall script reads a pushable credential without one ever being passed to it.
Fix: Add with: persist-credentials: false, and pass an explicit token only to the step that pushes.
Expand the test suite; it cannot cover this codebasemedium4 occurrences
4 test files against 121 source files (ratio 0.033)
A reviewer reads "has tests" and assumes a safety net that covers two files out of eighty-five, which is how untested paths ship behind a green badge.
Fix: Add tests for the highest fan-in modules first.
Set timeout-minutes on the workflow jobslow4 occurrences
.github/workflows/build-grammars.yml
4 workflow(s) declare no job timeout
A wedged step runs to the six-hour platform default, which on a two-hourly schedule means three runs overlap behind it.
Fix: Add timeout-minutes with a realistic bound to each job.
Checked deterministically against the repository tree and a bounded set of its files: committed credentials, unpinned actions and base images, missing lockfiles and update bots, workflows that discard failures, published advisories against the declared dependencies, runtime configuration, licensing and notebook reproducibility. No language model is involved in this section.