Set up with your agent
One copy-pasteable prompt that walks any coding agent through setting argot up properly — audit, scope, fit, verify, tune, wire.
Argot learns how your repository writes code. Everything downstream depends on one judgment — which code is the voice — and getting it wrong fails quietly: false alarms people learn to scroll past, or real problems never flagged.
If your agent supports skills, install them and ask for argot-setup:
npx skills add get-tmonier/argot
If it does not, or you would rather not install anything, paste the prompt below into any coding agent in your repository. It is the same procedure.
The prompt
Copy everything in this block.
Set up argot in this repository. Argot learns how this repo writes code and
flags what looks foreign to it, so the quality of every future result depends
on scoping it correctly now. Work through the phases below in order. At each
one, show me the evidence and let me decide — do not apply changes you cannot
justify in one sentence. Any phase can be skipped if I say so.
0. PREFLIGHT
Run `argot --version` (if missing, stop and point me at
https://argot.tmonier.com/docs/getting-started/). Confirm this is a git repo
with real history, that I am on the default branch, and that the tree is
clean — fitting a feature branch bakes unmerged commits into the voice.
Tell me setup will write argot.toml and a committed .argot/ fit snapshot.
The snapshot contains the learned voice, semantic index and other detector
artifacts; only caches/one-run state are gitignored. After fitting, show me
its size and exact Git diff, then ask me to review and commit it. CI only
reads this committed snapshot; it never fits or rebuilds it.
If CI is requested, its workflow comes only after that commit has been
merged into the branch future PRs target (normally the default branch). A
snapshot committed only in the setup PR cannot bootstrap its own CI run.
1. PROOF FIRST
Run `argot audit --format json`, SAVE IT TO A FILE, and show me a readable
summary. It needs no configuration and changes nothing.
TELL ME THE COST BEFORE YOU START IT, or I will kill it thinking it hung.
Audit fits the whole corpus once, so a large repo costs minutes and
gigabytes, not seconds — 924k lines of Object Pascal took 2 min 38 s and
3.6 GB. A narrower `--commits` does NOT make it cheaper: the window only
moves the base commit, the fit still reads every file. The lever is
[exclude], which is phase 2 — so on a repo that size, offer to do the
obvious exclusions first and audit second.
Then CHECK IT PRODUCED SOMETHING: exit status 0 and a non-empty JSON file.
A run that dies leaves a 0-byte file, and an empty audit reads exactly like
a clean one.
If it says the window touched no supported source, widen it with
`--commits 200` or `--since 6m`. Phase 6 reads this same file, so do not
run it twice.
2. SCOPE
Decide what should NOT shape the voice. Two sources now, a third after the
fit in phase 3:
- `argot init --suggest --format json` (generated / data-heavy dirs)
- your own read of the tree: vendored code, demo/example/playground trees,
peripheral monorepo packages, generated clients, transpiled JS in a TS
repo, committed backup/old snapshots, large data and fixtures
Show me `argot inspect --corpus` before we commit to it. Put what we agree
in argot.toml [exclude].paths, one per line, each with a trailing # reason.
Phase 3 prints more evidence and sends you back here — that is expected,
scoping is two passes, not one.
3. FIT AND CHECK HEALTH
Run `argot init`. Then run `argot inspect --format json` and read it:
- verdict "not_recommended" -> go back to phase 2, do not continue
- a reason with signal "voice_not_where_the_work_is" -> argot found a
directory that shapes much of the voice but takes almost none of the
recent changes. That is a mis-scope. Take it back to phase 2.
Also read what `argot init` PRINTED, it is evidence phase 2 could not have:
- "N files argot:recommended would exclude are shaping the voice (...)" ->
add every path it names to [exclude].paths
- "<language>: N files - too few to learn a voice" -> those files are NOT
checked at all. Tell me. If an extension is routed to the wrong language
here, exclude it.
Yellow notes on a small repo are normal. Do not chase a perfect verdict.
4. VERIFY IT CATCHES SOMETHING
Pick the package deliberately, do not guess: run `argot conventions` (or
read .argot/repo-corpus.txt) to see what this repo actually imports, then
choose something plainly outside it. In a real source file — primary source,
not a test or an example — add that import plus a line using it. Run
`argot check`, confirm it fires, then revert.
If it does NOT fire, DO NOT conclude the tool is weak. Run the diagnosis
below before anything else.
5. ADOPTION
Ask me directly: baseline or clean slate?
- baseline: `argot check --add-ignores` writes an inline ignore above
every finding that exists today, so only new code is judged from here
- clean slate: we fix or mute the existing findings now
If I baseline, remind me those ignores are a snapshot and should be
re-scored later, or the baseline silently becomes permanent.
6. TUNE FROM MY OWN HISTORY
Re-read the audit JSON you saved in phase 1 and look at `over_firing` — rules tripping more
than 2% of scanned hunks. A healthy repo sits at 0.3-0.7% per rule, so
anything above that is describing this repository rather than flagging it.
For each, propose in this order and never jump to "off":
1. scope it to the tree that trips it, e.g.
foreign-import = { severity = "error", exclude = ["**/*.bench.ts"] }
2. soften it to "warn"
3. accept it with a standing [[mute]] and a reason
If the history shows one dependency replacing another, or I tell you we are
mid-migration, propose a [[migration]] entry (from / to / reason).
7. DO NOT WRITE CUSTOM RULES DURING CORE SETUP
`argot conventions` is useful above to choose a deliberately foreign import,
but do not mine conventions or create custom rules yet. First finish scope,
fit, baseline, tuning, and integrations. A rule written before those choices
settle is usually a frozen accident. The only custom-rule exploration is the
explicit opt-in at the very end (step 11).
8. WHERE IT RUNS — ask me about local and CI together
Local: the pre-write guardrail hook (already included if I use the Claude
Code plugin), pre-commit (argot-check advisory, argot-check-gate blocking),
and the MCP server (`argot mcp`) for agent context.
CI: the GitHub Action, non-blocking by default. It extracts the committed
fit snapshot from the PR base, so a PR cannot self-certify by changing its
own `.argot/`. It never fits, downloads a model, or restores an Argot cache.
Therefore, if this is the first setup PR, do NOT add the CI workflow yet:
first review, commit, and merge argot.toml plus .argot/ into the PR base;
add the workflow in a follow-up PR or commit. Verify that base branch's
`argot status --format json` reports `snapshot.complete` and
`snapshot.committed` before enabling CI.
Its scorecard reports deterministic adaptive source/function/layout drift and
a structured next_action: fit, or review_scope_then_fit when structural paths
or fit-relevant config need attention. It points to argot-refresh; commit count
and age alone do not trigger it. Missing/incomplete snapshots are explicit setup errors.
9. PROVE IT
Give me the phase-4 fixture as a repeatable local command, so I can re-run
the catch check myself after any config change. Do not push branches or open
pull requests.
10. SUMMARIZE
What the audit found, what we excluded and why, the health verdict, what
was wired, and what my team sees on their next PR. Explain that refresh is
data-driven: Argot measures material accepted source/function/layout drift, while
commit count and age are not triggers by default. No refit is automatic:
when the scorecard recommends it, use argot-refresh locally on the accepted
branch. It re-audits excludes, structural paths and mutes, asks once before
policy changes, then fits; review `.argot/` and commit the refreshed snapshot.
11. OPTIONAL: EXPLORE ONLY THE CONVENTIONS ARGOT SHOULD ENFORCE
Only after the summary, ask me exactly once whether I want a read-only,
opt-in exploration for zero to three team conventions that are genuinely
worth custom rules. Make clear that saying no is normal, the exploration
creates no files, and selecting a candidate is a separate approval to write
a rule.
If I say yes:
- use `argot conventions --format json`, the audit saved in step 1,
`argot rules`, argot.toml, existing .argot/rules/, canonical source
examples, and targeted git history to find durable team decisions;
- reject generic syntax/style/import-order/deprecated-API/security rules
that OXLint, ESLint, or another normal linter can own; reject built-in
Argot duplicates; turn a mined migration into [[migration]], not a
script; reject weak placement, rules that need type inference or
cross-file binding resolution, and anything without a one-sentence
canonical remedy;
- keep a candidate only if Argot has a real contextual advantage: the
pre-image (`ts_query_old` / file.old_text), the other paths in this
changeset (`changeset_paths()`), a committed contract or its siblings
(`read_repo_file()` / `repo_paths()`), the fitted-history allowlist
(`import_attested()` / `callee_attested()`), or a strongly concentrated
learned placement convention (feature F belongs in location L, so F
outside L is the violation);
- show at most three candidates, or zero if none clear the bar. For each
show the counts and locations supporting it (concentration, home_files,
out_files, audit/history evidence), one canonical good example, one
plausible bad change, the exact Argot-only context, a syntactically
detectable shape, proposed scope, and why current leaks are legitimate
exceptions, debt, or a reason to reject the idea;
- ask me separately which candidate, if any, to codify. Do NOT create a
.argot/rules/ directory merely because I opted into exploration.
For each candidate I explicitly approve, use argot-suggest-rules when it
came from a mined placement convention; use argot-write-rule when I stated
the convention. Write fixtures before the script: at least one firing case
and one silent canonical case, plus old.<ext> or sibling fixture files when
a pre-image or repository read matters. Loop `argot rules test <name>` until
green, then prove it on a throwaway real diff and revert the diff. The
fixture harness has no fitted model, so import_attested/callee_attested are
false there: test the unattested path in fixtures and the attested path live.
Start every new rule at warn; promote it to error or lock it only after real
PRs show that no legitimate exception exists.
DIAGNOSIS — read this before concluding anything about argot's quality.
If it seems noisy, or seems to catch nothing, it is far more often mis-scoped
than wrong. A mis-configured argot fails SILENTLY: no error, just false alarms
I learn to scroll past, or real problems never flagged. You cannot tell by
looking at findings. Run these:
argot inspect --format json
.verdict "not_recommended" -> do not trust any finding yet
.reasons[].signal
voice_not_where_the_work_is
a directory shapes much of the voice but takes almost
none of the recent changes. THE most common cause of
both noise and silence: the model learned from code
nobody edits and is judging the code everybody does.
The message names the directory and both shares. Fix
it in phase 2, do not tune rules around it.
polyglot_mix several languages share the repo; expect weaker signal
any other reason relay it verbatim, do not summarise it away
argot audit --format json
.over_firing[] rules tripping >2% of MY OWN accepted history. A
healthy repo sits at 0.3-0.7% per rule. Above that the
rule is describing this repository rather than flagging
it — that is noise caused by scope or by the rule being
wrong here, NOT by argot being inaccurate.
what `argot init` printed
unlearnable_languages / "too few to learn a voice"
those files are NOT CHECKED. Silence there means not
looked at, not clean.
"N large hunk(s) scored above the flat threshold but not above the one
for their size" the score is a max over the hunk's tokens, so a big
hunk scores higher for free; the bar rises with size
past this repo's own p90. Those were judged against a
higher bar, not skipped. Review them by hand if they
are rewrites.
Throughout: if argot reports it did NOT judge something — a language with too
few files, an oversized hunk, a disabled rule — relay it to me. Silence that
means "not checked" must never look like silence that means "nothing found".
Why it is a conversation and not a command
Almost every step above is a measurement argot can make on its own. The one it
cannot make is the judgment: is this directory our voice, or is it demos we
happen to ship? That is why setup asks rather than assumes, and why every
[exclude].paths entry carries a written reason — so the decision is reviewable
in the pull request that adds it.
After setup
- Check a changeset — the daily review loop
- Configure — the full configuration reference
- CI and pre-commit — what the Action does and what it costs
- Health and freshness — when to re-scope