# Show HN: Argot, a Rust AI guardrail based on your codebase AST patterns

> Source: <https://argot.tmonier.com/>
> Published: 2026-08-03 12:12:51+00:00

### Learn the repository

**argot init** learns the voice, semantic neighbours, architecture, and test signals on your machine.

AI writes the code. argot harnesses it with the one thing that can’t hallucinate: **your repo’s own history**. Deterministic, measured, local.

**97.3%** of foreign patterns caught · **0.25%** of real edits flagged

checks a diff in200 ms

A concrete example

Clean, type-correct PRs can still be foreign to your repository. **This is its real output.**

Why this matters

A green check can hide a weakened test. argot pairs it with the changed code and names both.

154/164 (93.9%) — detector-specific fixture catch; controls and accepted-history results are separate. [Read the detector scope and controls.](/benchmarks)

Evidence you can reproduce

**argot audit** compares accepted changes with the repository history before them. Findings are prompts to inspect, not defect verdicts.

Then run **argot init** and choose a recurring check path.

Measured, not promised

97.3%

620/637 (97.3%) — detector-specific fixture recall; not a product-wide accuracy claim. Fixture recall; the changed symbol is visible in the diff.

36 corpora / 12 languages / visible foreign-import and foreign-api fixture symbols after excluded-host purge · d1007f50; generated_at=2026-07-28

97.1%

264/272 (97.1%) — detector-specific real recall; control result is separate. Authored internal layering violations across 25 corpora and 12 languages.

25 corpora / 12 languages; authored internal layering violations · 7886a7967c6fe5b822a249083c7871894db1efcf; generated_at=2026-07-20

93.9%

154/164 (93.9%) — detector-specific fixture catch; controls and accepted-history results are separate. Authored production fit-to-check gaming fixtures.

23 corpora / 12 languages; authored test-gaming fixtures, production fit→check · 1b0de32d; just integrity-verify, 2026-07-28

One **static binary**. Twelve languages — each with its own tree-sitter adapter and its own learned model:

Recall on patterns planted in real files; false alarms on a temporal holdout. Even the structural blind spot — masked foreign — is published, not hidden.

How it works

Run **argot init**, then choose the CLI, skills, a commit hook, or a GitHub Action. The Claude plugin adds a narrow pre-write prompt — not a full acceptance-time check.

Install the CLI

seven on-demand skills for compatible hosts:

`/argot-setup`

reads your tree, writes argot.toml, verifies the catch`/argot-refresh`

reviews scope and mutes, then refreshes the learned snapshot`/argot-check`

scores each diff, flags what’s foreign — never blocks`/argot-review-pr`

reviews one PR against your repo’s voice, no checkout`/argot-setup-ci`

a non-blocking voice score on every PR`/argot-write-rule`

turns a convention you state into a tested rule`/argot-suggest-rules`

finds your conventions, codifies oneThe Claude plugin adds optional MCP context and a narrow, fail-open pre-write prompt; agents still decide when to call Argot. [Get the plugin →](/docs/plugin/)

``` bash
$ argot init
Step 1/2: training voice model …
Step 2/2: calibrating threshold …

Corpus
  1129 files · 503 learned · 626 tests/docs skipped
Verdict: Ready

Snapshot → .argot/ · voice · semantic index · health
Review + commit → argot.toml · .argot/
Next:  argot check
```

The learned snapshot is committed; caches stay local. CI reads the base branch copy and never fits.

The whole model, in one glance

Argot’s learned state is a **reviewed snapshot in Git**, not a hosted service. Every developer, agent, and PR compares against the same repository memory.

**argot init** learns the voice, semantic neighbours, architecture, and test signals on your machine.

Review and commit **argot.toml + .argot/**. It is repository-specific learned state, like a lockfile for checks.

Local tools, agents, and CI read that snapshot. A PR is judged against the **base branch**, so it cannot teach itself.

After material accepted drift, status recommends **/argot-refresh**: review changed scope and mutes, fit locally, recommit.

Integrations

The GitHub Action reads the **committed base snapshot** and is non-blocking by default. Intentional divergence remains a human decision, recorded as an audit trail.

**Start here:** open each row in the review queue.

`crates/argot-cli/src/voice_diff.rs:202–282`

**Evidence:** option, highlighted, Move — unfamiliar vocabulary here.

**Review:** rewrite in the repository’s established form if unintended.

`crates/argot-core/src/compose.rs:1–14`

**Evidence:** `Lazy::new`

is not used by similar code here.

**Review:** compare the call with the repository’s established API.

💬 Prompts for review, not proof of defects.

`main`

· CI never fits.Findings land on the PR. Snapshot health stays visible in the same summary.

Under the hood

Four local engines, one static **Rust** binary — model included, nothing fetched — all grounded in your git history.

A 15.6 MB table argot distilled from a code encoder turns every function into a vector — how argot knows you **already wrote this**. Nothing to download, no GPU, no cloud: it ships compiled in and works air-gapped.

Two frequency tables and a callee clustering — the imports, callees, and token shapes your repo **actually uses**.

Your module-dependency topology. A new edge that **reverses the established direction** is flagged with the direction it breaks.

tree-sitter tracks what every test asserts. A test **skipped, gutted, or deleted** beside a prod change gets paired and named.

Measured on FastAPI, laptop CPU. Single static binary — no Python, no Node, no model download, no GPU.

Advanced capabilities

**argot conventions** finds the shared API and where code belongs. Turn one convention into a small, testable rule.

where each kind of code lives — learned from your layout

```
// check.rhai — a route that existed before
// this change, and is silently gone now
let now = [];
for m in ts_query(ROUTES) { now.push(m.text); }
for m in ts_query_old(ROUTES) {
  if !now.contains(m.text) {
    report(m.line, m.text + " removed —
      deprecate first (docs/api-lifecycle.md)");
  }
}
```

MIT-licensed open source. Audit first, then choose the recurring check that fits your workflow.
