cargo refine · fixes for Rust code
Fix your Rust on your own machine.
The code fixer that learns.
cargo refine fixes Clippy lints, Rust performance, Dockerfiles and release profiles — plus compile errors — and keeps a fix only if your code still compiles (security, GPU-kernel and shader rules are in preview, not in the release). Logged out it is free and private — nothing leaves your machine. Opt in to mining and your secret-scanned fix records teach a shared corpus: you earn KAT, and every machine’s Refine gets better.
curl -fsSL https://raw.githubusercontent.com/gist-rs/cargo-refine/main/install.sh | shmacOS and Linux one-liner — Homebrew and Windows are under Try. Then run cargo refine in any Rust crate: it lists the fixes and changes nothing.
macOS (Apple Silicon, Intel) · Linux x86_64 + aarch64 (static) · Windows x86_64 · prebuilt, checksum-verified binaries, free to use under the Refine EULA; third-party licences ship with every release · latest release & changelog · GitHub
Why Refine
Fixes that compile — and a corpus that learns.
How is this different from cargo clippy --fix?
Every fix must compile.
Refine builds your crate after its edits and undoes any fix that breaks the build, so
--fixnever leaves you with code that no longer compiles.More than Clippy’s lints.
It also fixes Rust performance patterns, Dockerfiles, release profiles and compile errors — rules Clippy does not carry.
Your formatting and comments stay.
It edits only the span it fixes, and skips a fix that would delete a comment.
It reads your profiler.
Hand it a profile of your own workload and the code your profiler measured hottest is ranked first — no more hunting the hot loop by hand. How it works
What the network has learned so far
Rendered from the network’s own records when the page loads — nothing here is typed in. Each environment shows its own numbers. You are viewing devnet, a test network: its accounts and burns are test traffic, not traction.
what the network fixed — epoch 2961: 47 fixes by 2 coders over 19 runs — top: doc_lazy_continuation ×9 · chunks_exact_to_as_chunks ×7 · match_bool ×7 · shrink-to-fit-after-build ×6 · unreadable_literal ×4 · detail
How to read this
The pattern classes the network carries: the shipped catalog, migrated on-chain as the baseline bucket, plus what mining has observed arriving since. One square per arrival bucket (a mining epoch), two channels: hue = which domain led that bucket, shade = the bucket's volume in four steps — quartiles of the active buckets, so one bulk arrival cannot flatten every other. Rule names the mapping does not know count under other — honest, never mislabeled. Live: aggregated from the network's own records by each maintenance pass.
quality measured on a single machine
rules shipped — cumulative, per domain
ladder — hardest benchmark generation admitted
ladder steps: 2026-09-12 ▲8
fix rate — gen 1
volume — 47 fixes last epoch 2961 · 19 runs · detail
fixes by domain — clippy 38 perf 5 rust_perf 4
bars = rules shipped per domain, cumulative — a rule's removal never lowers the stack (coverage, not a live count); step line = hardest benchmark generation admitted; line = gen-1 fix rate, gaps = days with no gen-1 run. Bounded self-refinement — fixed evaluator, convergent and evaluable (arXiv:2607.07663).
16 accounts · 173 KAT burned to date · 119.699993 KAT minted to miners · epoch 2,960 · 2 KAT burned today · 0 KAT paid today · 2 KAT burned 7d
10 mint receipts · 0 KAT credit locked under vest · 119.699993 KAT released
Who counts here
Who runs Refine, and what the miners contribute.
Free = claimed the grant, never contributed (cargo refine);
mining = pushed a redacted batch (cargo refine --mine). The
tiers are the machines' own signed declarations (--mine /
--unmine); an opted-out machine stops contributing but its last
declaration stays on record. The table below lists the most recent machines
that actually pushed rows — a signed note with nothing behind it
is not a contribution, so it is counted in the totals above and left off the
table.
16 accounts · 9 free · 7 mining · 2,111 batches · 687 rows contributed · consent: 14 in / 0 out
177 mining · settles at the epoch settle, pays after the 1d vest · pool backing them: 1.400007 KAT
The mining pool grows from KAT burns; trial (TUNA) burns fund nothing — the KAT ledger carries the flows.
| machine | tier | account | last note | success% (pushed/earned/dup/queued) |
| in | c79c…5345 | 2026-10-05 | 60% (655/395/260/0) | |
| in | 8f5a…a427 | 2026-10-05 | 100% (3/3/0/0) | |
| in | 7161…bd29 | 2026-09-16 | 4% (7210/287/6923/0) | |
| in | 518a…8176 | 2026-09-17 | 100% (2/2/0/0) |
4 contributing machines · 14 machines seen
How it works
Dry run first. Then only the fixes that compile.
A real run on a sample crate, replayed line by line: cargo refine lists what it would fix and writes nothing; cargo refine --fix applies the edits, re-checks the build, and keeps only what still compiles.
$ cargo refine
cargo refine: dry run — reviewing the current directory (no edits). Real fixes: cargo refine --fix
clippy oracle (auto): linting <sample crate> at default features, all targets (tests/benches/examples included) — this compiles the project, first run can take a while (RIIR_REFINE_AUTO_ORACLE=0 disables)
clippy oracle (auto): 5 real diagnostic(s) anchored ahead of ranking
./src/lib.rs:19-19 (routed: clippy) [oracle]
[clippy] needless_return oracle finding → fn foo() -> i32 { 42 }
./src/lib.rs:24-24 (routed: clippy) [oracle]
[clippy] clone_on_copy oracle finding → fn f(hits: &mut Vec<u8>, x: u64) -> u64 { hits.push(0); x }
./src/lib.rs:33-33 (routed: clippy) [oracle]
[clippy] bool_comparison oracle finding → fn flag(x: bool, hits: &mut Vec<bool>) -> bool { hits.push(x); x }
./src/lib.rs:38-38 (routed: clippy) [oracle]
[clippy] from_str_radix_10 oracle finding → fn num(s: &str, hits: &mut Vec<u32>) -> Result<u32, std::num::ParseIntError> { hits.push(0); s.parse::<u32>() }
./src/lib.rs:43-43 (routed: clippy) [oracle]
[clippy] collapsible_if oracle finding → fn work() {}
… (similarity-ranked [heuristic] suggestions trimmed — the [oracle] rows above are the clippy findings)
scanned 1 file · 6 spans · 6 with suggestions (top-3 per domain) · 5 oracle-anchored · 0 no-corpus-rule
fixed 317 tokens → 0.0003 KAT (1 TUNA or KAT / 1M tokens)
sync local only — not logged in · nothing pushed (`cargo refine login`)
$ cargo refine --fix
verify: 1 file(s) / 7 edit(s) — baseline + compile-gated apply
verify: 2 cargo check(s) — kept 1 file(s) / 7 edit(s), reverted 0 edit(s)
self-evolve: memory-only (learning disabled: built without the clippy_verify oracle)
fix ./src/lib.rs (7 edit(s) verified):
[needless_return ] line 18
[collapsible_if ] line 42
[from_str_radix_10 ] line 37
[bool_comparison ] line 32
[clone_on_copy ] line 23
[let_and_return ] line 18
[let_and_return ] line 17
fmt: formatted
scanned 1 file · 6 spans · 6 with suggestions (top-3 per domain), fixed 1 file(s) / 7 edit(s) (verified — compile-gated), fmt: 1 formatted · 5 oracle-anchored · 0 no-corpus-rule · 1 oracle edit applied
fixed 317 tokens → 0.0003 KAT (1 TUNA or KAT / 1M tokens)
sync local only — not logged in · nothing pushed (`cargo refine login`)
Captured with cargo-refine 0.2.1 by scripts/gen_refine_capture.sh — run it yourself: cargo refine (dry run) is free and anonymous.
Point it at your profile — the code your workload actually hammers, ranked first
A profiler tells you where the time and allocations go; fixing that by hand is the slow part. Refine reads the report the open-source hotpath profiler writes and puts the functions your workload measured hottest at the top of its review, with the profiler’s own numbers printed beside each fix. Every edit is still compile-gated. The timing only ranks the list — never take a speedup on faith; measure it yourself.
1 — instrument, then run your workload as usual.
cargo add hotpath --features hotpath,hotpath-allocPut #[hotpath::main(format = "json", output_path = "hotpath-report.json")] on main and #[hotpath::measure] on the functions on your suspect list. Run your workload; the report lands next to it.
2 — dry-run against the report.
cargo refine --hotpath-json hotpath-report.jsonThe review shows each fix with the profiler’s row beside it — calls, average time, share of the run, allocations — hottest first. Review the hunks as usual: a fix can match the same shape elsewhere in the file, so read everything it touched, not just where the profile pointed.
3 — apply, then re-profile.
cargo refine --hotpath-json hotpath-report.json --fixYour second profile is the verdict. Run the same workload on the same inputs and diff the two reports — and treat “nothing moved” as a valid result: allocations that come from how your data is owned are out of scope. Re-profile after you change code, too; an old report describes old code.
Honest scope: Refine fixes mechanical waste the profile points at — copies a borrow would replace, buffers sized wrong, results computed and dropped. It does not redesign how your data is owned, and the profiler stays the source of truth for what is hot.
How it learns — every verified fix teaches the next one
Your fixes run locally. If you opt in, redacted records of how they went join the network’s corpus, and better rules come back to every machine.
Step by step: what goes in and what comes out
1 · Scan
cargo refine scans your crate and collects the spans a fix could touch — the bare dry run writes nothing. No listing is published here: your code never leaves the machine, so the walk shows real bytes only where a step crosses to the fleet.
2 · Retrieve
Corpus rules and your own past fixes are ranked against each span (top-K). The fleet corpus arrives through the lease (step 7), so a fresh machine already retrieves what the network learned.
3 · Draft + validate
Modelless proposers draft fixes from the retrieved rules; a real-clippy oracle judges each draft before anything is written. No LLM is on this path.
4 · Fix, compile-gated
--fix writes only what the compile gate keeps: a fix that breaks your crate's build is reverted automatically. Divergence classes the gate cannot judge stay manual.
5 · Record
Every applied fix becomes a trajectory row — the span, the rule, the verdict — in the local memory store. Recording runs in every build; nothing is uploaded by default.
6a · Learn
Learning is measured, not claimed: after corpus and memory changes the score bench re-runs the fixture corpus and appends a row to the recorded history — heal rate, parse safety, the rule vocabulary. This row is the last simple-shape row in that history.
OUT · one recorded score-bench row
{ "ts": "2026-09-06T06:52:06", "sha": "d4aad878", "n_ran": 35, "n_healable": 29, "n_clean": 6, "heal_rate": 0.9622642, "created_rate": 0.018867925, "parse_safety": 1.0, "decline_correctness": 1.0, "edits_total": 66, "vocab_size": 38 }one recorded score-bench run, 2026-09-06T06:52:06 (crate d4aad878) — the last row of the simple shape in the recorded history
6b.1 · The mining batch (opt-in)
Only with consent do redacted records queue to leave: rule verdicts plus the short snippets each fix touched, secret-scanned, never whole files, never your paths, signed with your key. This is the network's published sample batch — inspect what mining uploads before opting in.
IN · one --mine batch (published sample)
{ "payload_version": 3, "redact_version": 3, "origin": "own-repo", "created_unix": 1791028699, "rows_included": 4, "rows_blocked": 0, "batch_commitment": "9c0e4935070db7b4b2ce346758824b3efbcc9d9a603bb4143d36f70080b63d58", "account_pubkey_hex": "f57d1724269522a6ce74493d99997cafa6888820fd8f6f33899273f4299460f8", "signature_hex": "08043514c985b9d28aae54630a66639b713de74a0831b2b2d5c1d327b494c120ab02e0dbba7c9b1381ed4a6d4cc13366087b48b113f44bf6e87b183d118a7a0b" } { "shape_id": "7819c50b7076", "lint_key": "filter_next", "domain": "clippy", "shape": "values.iter().filter(|v| *v % 2 == 0).next()", "fix": "values.iter().find(|v| *v % 2 == 0)", "direction": [-0.9384366, 0.010083847, -0.044518255, -0.35203317, 0.107131176, 0.60174465, -0.8606558, 0.07532138], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "c3a6997f234a", "lint_key": "needless_range_loop", "domain": "clippy", "shape": "for i in 0..values.len() {\n total += values[i];\n }", "fix": "for value in values {\n total += *value;\n }", "direction": [-0.31596875, 0.74847627, -0.25766408, -0.7536681, -0.8198199, -0.5253514, 0.24328057, 0.40595883], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "2bd8a283534f", "lint_key": "needless_return", "domain": "clippy", "shape": "return total;", "fix": "total", "direction": [0.6863015, -0.76078856, -0.73800665, 0.8010406, 0.87747365, 0.82867664, 0.25373134, -0.0011432369], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "34fc9d1c297e", "lint_key": "vec-with-capacity", "domain": "rust_perf", "shape": "Vec::new()", "fix": "Vec::with_capacity(words.len())", "direction": [0.7280237, -0.24283206, -0.594867, 0.99811685, 0.058567684, 0.06598411, 0.8178545, -0.09290348], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } }cargo refine sync --export on a ~30-line demo crate (4 fixes), signed with the export's throwaway key — published at ai.gist.rs/sample-mine-batch.ndjson and ingest-verified by the worker's test
6b.2 · Proof + payout
On sync, rows enter the proof queue and are credited at a real clippy re-run; the epoch settle pays KAT to miners (mining = processing, minted = paid). Test network today.
7 · The lease-back
The fleet corpus — every verified pattern class the network observed — refreshes retrieval on every machine. This is the newest row of the recorded corpus history: rules per domain, today.
OUT · the fleet corpus per domain
{ "clippy_lints": 100, "dist": 6, "docker": 31, "kernel_opt": 746, "rust_perf": 168, "sec": 16, "shader_perf": 8, "ts": "2026-10-03" }the fleet corpus per domain, 2026-10-03 — the newest row of the recorded corpus history
- dry run
cargo refinewith no flags: lists what it would fix and writes nothing.- compile-gated
- a fix is kept only if your code still compiles after it; otherwise it is undone.
- mining
- opting in (
--mine) to share records of your runs — rule names, counters and the code spans each fix touched (secret-scanned; never whole files, never your paths; proven pairs become public — see what mining sends). - epoch
- the network’s one-week accounting period; mining pays out at each epoch’s settle.
- profile-guided
- aiming fixes at the functions your own profiler measured as hot — you run the workload, the profiler counts, Refine reads the counts (above).
- KAT
- the network’s metered service credit — details below.
- TUNA
- free trial credit for new accounts, spent before KAT.
- cost
- Every run that reads your code — the dry run included — is metered on your machine at 1 KAT-equivalent per million code-word tokens (a code-word token is one whitespace-separated word of code). Logged out (the lite tier), nothing is reported or billed at run time: free, anonymous, earns nothing. The runs still accumulate in the crate’s local
.refine/meter — logging in later in the same crate reports that accumulated total (deleting.refine/starts fresh). Logged in, each run’s metered total is reported and billed to your account — free trial credit (TUNA) first where the network funds it, then KAT; an emptied account that has never contributed is refused until you contribute (--mine) or top up (and what the credit itself is — and is not: token & staking risk).
Trust
Private by default, shared by consent.
Fixing never leaves your machine. Sharing is opt-in and secret-scanned, and what it shares is public once proven — the exact data path and the hard questions are below. The same one gist.rs account covers the whole network, Rethink included.
Local fixing free · no account
The dry run and the compile-gated fix run on your machine, logged out: anonymous, nothing uploaded, and nothing reported or billed at run time. The runs still accumulate in the crate’s local .refine/ meter — a later login in the same crate reports that accumulated total (deleting .refine/ starts fresh).
The shared corpus opt-in
Log in and consent (--mine) and your secret-scanned fix spans teach the fleet; proven before/after pairs join a public corpus that leases back to every machine. Off until you switch it on, and --unmine stops the push half.
What mining sends — from your machine to the public corpus, end to end
Only when you opt in. Every step is numbered in the order it happens; the lanes say who can read the data at that step. Open the step-by-step under the figure for a real batch.
Step by step: what goes in and what comes out
1 · Your fix run
`cargo refine --fix` runs on your machine and keeps only fixes that still compile. Each fix is recorded locally under `.refine/`. Logged out, this is where the story ends: nothing is uploaded.
2 · One row per fix
A mining row is the exact code span a fix replaced and its replacement, plus the rule name, a short numeric shape fingerprint and counters. File paths, crate names, repo URLs, git remotes and usernames are not fields. A span is your code verbatim, and one field may be up to 64 KiB — a long function a fix rewrote travels whole.
3 · Secret scan + sign
Every span runs through the secret scanner (cloud and API keys, private-key blocks, connection strings, bearer tokens, env secrets, long hex and base64 runs). Under the default policy any finding drops the whole row — it is never sent. The batch is signed with your account key, so the network can prove it is yours and untampered.
4a · Export only
`cargo refine sync --export batch.ndjson` writes the exact batch to a file and sends nothing, no login needed. Read it before you join; this is a real published sample of the same shape.
IN · one batch (published sample)
{ "payload_version": 3, "redact_version": 3, "origin": "own-repo", "created_unix": 1791028699, "rows_included": 4, "rows_blocked": 0, "batch_commitment": "9c0e4935070db7b4b2ce346758824b3efbcc9d9a603bb4143d36f70080b63d58", "account_pubkey_hex": "f57d1724269522a6ce74493d99997cafa6888820fd8f6f33899273f4299460f8", "signature_hex": "08043514c985b9d28aae54630a66639b713de74a0831b2b2d5c1d327b494c120ab02e0dbba7c9b1381ed4a6d4cc13366087b48b113f44bf6e87b183d118a7a0b" } { "shape_id": "7819c50b7076", "lint_key": "filter_next", "domain": "clippy", "shape": "values.iter().filter(|v| *v % 2 == 0).next()", "fix": "values.iter().find(|v| *v % 2 == 0)", "direction": [-0.9384366, 0.010083847, -0.044518255, -0.35203317, 0.107131176, 0.60174465, -0.8606558, 0.07532138], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "c3a6997f234a", "lint_key": "needless_range_loop", "domain": "clippy", "shape": "for i in 0..values.len() {\n total += values[i];\n }", "fix": "for value in values {\n total += *value;\n }", "direction": [-0.31596875, 0.74847627, -0.25766408, -0.7536681, -0.8198199, -0.5253514, 0.24328057, 0.40595883], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "2bd8a283534f", "lint_key": "needless_return", "domain": "clippy", "shape": "return total;", "fix": "total", "direction": [0.6863015, -0.76078856, -0.73800665, 0.8010406, 0.87747365, 0.82867664, 0.25373134, -0.0011432369], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "34fc9d1c297e", "lint_key": "vec-with-capacity", "domain": "rust_perf", "shape": "Vec::new()", "fix": "Vec::with_capacity(words.len())", "direction": [0.7280237, -0.24283206, -0.594867, 0.99811685, 0.058567684, 0.06598411, 0.8178545, -0.09290348], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } }cargo refine sync --export on a ~30-line demo crate (4 fixes), signed with the export's throwaway key — published at ai.gist.rs/sample-mine-batch.ndjson and ingest-verified by the worker's test
4b · Sent over HTTPS
`--mine` (and every run after joining, or `cargo refine sync` itself) sends the signed batch over HTTPS. The signature proves who sent it; it does not hide the content — the network must read a row to verify it.
5 · Proof queue
Rows wait in the proof queue until a real clippy re-run confirms the fix. A verdict is measured, never trusted from the client. Unproven rows stay with the operator.
6 · Public corpus
A proven row's before/after pair is published verbatim into the corpus segment — a public URL anyone can download without logging in. This is the shared corpus the flywheel promises; it is also why confidential code should not be mined.
7 · Lease back
Every machine's corpus pull downloads the segment. The request carries only the version your machine already has — no code, no account — and your next run retrieves from what the fleet proved.
Logged out, nothing leaves your machine.
check it: run it with the network off and your dependencies already fetched — every fix still works. A plain cargo refine or --fix never dials out logged out (update and sync download the public corpus, and a developer service-URL override makes every run do it); the toolchain it runs (cargo fetching crates, docker resolving base images) behaves as it always does — watch it yourself with nettop or your firewall log.
Every fix must compile.
check it: --fix builds your crate after its edits and undoes any fix that breaks the build.
You can read exactly what mining would send, before you join.
check it: a real, redacted sample batch is published and linked in the miner tab — and cargo refine sync --export writes your own crate's exact batch to a file (in v0.2.1 and later; the sample works today).
Opt-in is reversible.
check it: --unmine stops the push half; healing was always local.
Secrets are scanned before anything is shared — and the same scan runs on your side.
check it: every snippet a mining batch would carry passes a secret scanner (a versioned, open method: fixed key formats — API keys, tokens, private-key blocks — plus high-entropy detection; a snippet with any finding is dropped, not sent). The same scan runs on your machine: cargo refine --secret-scan lists findings with the value never shown, and cargo refine --secret-scan --blind FILE prints the file with secrets replaced by placeholders — safe to paste into a ticket or a chat. Honest limits: an unknown format is caught only if it looks random (the entropy rule), and this is a secrets scan, not a PII scan — for code you did not write, the whole span is the sensitive thing, so the policy (own-repo only, deny-by-default) is the control that matters.
No hidden results.
check it: the leaderboard and fixstats show what the network fixed, publicly.
Your profiler’s numbers are shown verbatim — and the profile never leaves your machine.
check it: with --hotpath-json, each fix in the review carries the profiler’s own row beside it — compare it against your JSON; they match or the tool is wrong. The report is read from your disk locally, like everything else logged out.
If I just run cargo refine, what leaves my machine?
Nothing. Logged out, the dry run and --fix run locally and upload nothing — no telemetry, no error reports, no usage counts. Two commands download the public corpus: cargo refine update and cargo refine sync. A developer service-URL override makes every run download it too. That download sends no code and no account; like any download, the server sees your IP address — and the worker keeps no request-level logs (no observability or logpush is configured; the host provider's own transport logs are the only record, and they are not ours to read).
Does Refine see my profiling report?
No more than it sees your code — and the report never leaves your machine. --hotpath-json reads the profiler’s JSON from your disk, locally, logged out or in. Mining does not send profiles either: a mined row carries the code span a fix replaced, not the measurements that pointed at it.
I logged in but I don't mine. What is sent?
After a billed run, a signed burn report with four fields: your account’s public key, a signature, your running KAT total and a token count. No code, no crate name, no paths. It is the billing record, so --unmine does not stop it.
When I mine, is my whole codebase sent?
No — never whole files. Mining sends one row per fix: the exact code span the fix replaced and its replacement, the rule name, a short numeric fingerprint of the change, counters and a run id. File paths, crate names, repo URLs, git remotes and usernames are not fields.
Be clear about what a span is: your code, verbatim. One field can be up to 64 KiB, so if a fix rewrote a long function, the whole function travels.
What if a snippet contains a secret?
Every span runs through a secret scanner before the batch is signed: cloud and API keys, private-key blocks, connection strings, bearer tokens, env secrets, and long hex or base64 runs. By default any finding drops the whole row — it is never sent. A scanner catches known secret shapes; it cannot tell that your business logic is confidential.
Is it encrypted?
In transit, yes — HTTPS. The batch is also signed with your account key (Ed25519), which proves it is yours and unaltered as received. Signing does not hide anything: the batch is not end-to-end encrypted, because the network has to read each row to re-run clippy on it. And the signature says nothing about what happens after upload — the operator holds the plain bytes, and a published corpus pair carries no signature, so its integrity rests on the operator's pipeline, not your key. Treat anything you mine as readable by the operator.
Who can see my snippets?
The operator, from the moment a batch arrives. And everyone, once a row is proven: when a real clippy re-run confirms the fix, its before/after pair is published into the shared corpus — a public download anyone can fetch without logging in. That is what “the corpus leases back to every machine” means. The leaderboard and fixstats show counts and rule names, never code text.
Under what licence are published pairs shared?
MIT. When you mine, you license each span you upload — the code before and after the fix — under the MIT licence, and the shared corpus publishes proven pairs under it: anyone may use, copy, modify and redistribute them, keeping the licence notice. Nothing else in your repository is licensed by mining. If your code cannot be released under MIT, don’t mine (the terms have the exact wording).
So could mining leak proprietary code?
The spans your fixes touched, yes — that is what mining shares. If your code is confidential, don’t mine: logged out you get every fix and nothing is uploaded. Before you join, cargo refine sync --export batch.ndjson writes the exact batch to a file and sends nothing, and the miner tab links a real sample.
What identifies me?
An Ed25519 public key — no email, no name, no GitHub account needed. By default the first login adopts ~/.ssh/id_ed25519; if that same public key is on your GitHub profile, the two can be linked. To keep them apart, point the first login at a dedicated key: RIIR_AUTH_ACCOUNT_KEY=/path/to/key cargo refine login.
The account id is derived from the public key alone, so anyone holding a candidate public key can compute the id and look for it in public rows — the GitHub .keys example above is exactly that. A key that exists nowhere public makes the id unlinkable.
A machine label is opt-in: current builds send none unless you set one (RIIR_REFINE_MACHINE_LABEL=rig-a cargo refine --mine), and it is stored, never shown on a public page. Older builds sent your hostname; it stays private the same way — update and re-run --mine to replace the stored copy.
Does my code go to an AI model?
Not from your machine: the cargo refine you install never calls an AI service. Not from ours either: the server calls no AI model, and the operator’s LLM drafting tool reads only the operator’s own local records, never the miner queue. Two honest limits: treat an unproven row as readable by the operator until it proves or is swept (rows that can never prove are deleted — see the privacy page), and a proven pair as public — it is in the open corpus, so anyone can feed it to any tool.
Can I stop, or take it back?
--unmine stops future uploads; batches already queued under .refine/outbox/ are yours to delete. Rows already sent stay on the server — there is no self-serve delete today (write to security@gist.rs; the privacy page has the honest version) — with one by-design exception: a pushed row that never proves is deleted once it provably can never prove (its epoch is more than four epochs behind the settled frontier), so dead spans do not sit in the queue forever; a re-push lands fresh. A pair already published in the corpus cannot be recalled from machines that downloaded it.
Try
Install once, pick your role
One binary covers coding and mining. The table says what each role can run today.
How to read this
Rows are roles (what you do with Refine); columns are tiers (the machine and account posture you run it at). A tier earns only what settles on the network today — this table never promises a future reward class. Every row on the leaderboard is the pro tier (miner); lite is anonymous by design and stays off the board.
Source of truth: the install-tier spec is kept in one place; this table mirrors it, and when they disagree the spec wins.
| role ↓ · tier → | liteany desktop · never billed · no account | proany desktop · login + miner | maxCPU box ~2–4 vCPU | ultraGPU rig / container VPS |
|---|---|---|---|---|
| coderfix your own code | yes — anonymous dry-run + fix, never billed | yes — logged in, every run billed (TUNA grant first) | — | — |
| minercontribute batches, earn KAT | — anonymous earns nothing | yes — the earn tier today | — | — |
| fixerverify & fix the network's queue | — | — | designed · the operator lane is live today | — |
| trainerhost the daily training window | — | — | — | ours only at launch |
One install covers lite + pro (coder and miner below). Max and ultra are node lanes, not downloads — they open to third parties when their reward classes settle, and the leaderboard stays honest about that.
Most people want coder (fix your own code) or miner (share redacted fix records and earn KAT). Fixer and trainer run on the operator’s machines today.
Fix your own code — the lite tier when logged out: never billed, anonymous, earns nothing. The miner tab's join step upgrades the same install to pro.
Step by step: what goes in and what comes out
1 · Install
One prebuilt binary (brew, scoop, or the install script) lands in ~/.cargo/bin — no repo clone, no build. Logged out it stays anonymous and is never billed.
2 · Dry run first
The bare `cargo refine` is a review: it lists the fixes it would make across your crate and writes nothing. No listing is published as a fixture — your code never leaves the machine, so this walk shows real bytes only where a step crosses to the fleet.
3 · The compile gate
`--fix` writes an edit only if your crate still compiles after it; a breaking fix is reverted automatically. Divergence classes the gate cannot judge (comment-guarded matches, array-literal defaults) stay manual and are listed, not applied.
4a · What you get
Healed code across the shipped domains — clippy lints, compile errors, Rust perf, Dockerfiles, release profiles — plus the local self-evolve loop: memory always records, learning runs when the oracle is present.
4b · What a logged-in run costs
The meter counts code-word tokens and bills one KAT-equivalent per million; where the deployment funds trial credit, TUNA pays first. The signed burn report is pushed after the run, is watermark-deduped (replays are no-ops), and never carries your code.
brew tap gist-rs/tap && brew trust gist-rs/tap && brew install cargo-refineor
curl -fsSL https://raw.githubusercontent.com/gist-rs/cargo-refine/main/install.sh | shAbout this command
Prebuilt formula via Homebrew — nothing compiles; updates with brew upgrade cargo-refine. The middle step is the one-time tap trust — Homebrew 6+ refuses to load formulas from an untrusted tap. Apple Silicon (M-series) and Intel binaries both ship.
curl -fsSL https://raw.githubusercontent.com/gist-rs/cargo-refine/main/install.sh | shAbout this command
Static musl builds (x86_64 + aarch64) — runs on any distro, Alpine included. The installer verifies the SHA256SUMS download automatically.
iwr -useb https://raw.githubusercontent.com/gist-rs/cargo-refine/main/install.ps1 | iexAbout this command
PowerShell, not cmd. Or Scoop: scoop bucket add gist-rs https://github.com/gist-rs/scoop-bucket then scoop install cargo-refine.
x86_64 only for now (no Windows-on-ARM build). The binary is not code-signed — SmartScreen may ask on first run. Installs to %USERPROFILE%\.cargo\bin.
cargo refine — dry run: lists the fixes it would make and writes nothing.cargo refine --fix — writes the fixes that still compile. Logged in, it is billed like every run — your free TUNA trial credit pays first (refine, rethink, everything on the network).RIIR_REFINE_JOIN_ENV=devnet or --yes.What it costs. Every run that reads your code — the dry run included — is metered on your machine at 1 KAT-equivalent per million code-word tokens (a code-word token is one whitespace-separated word of code). Logged out (the lite tier), nothing is reported or billed at run time: free, anonymous, earns nothing. The runs still accumulate in the crate’s local .refine/ meter — logging in later in the same crate reports that accumulated total (deleting .refine/ starts fresh). Logged in, each run’s metered total is reported and billed to your account — free trial credit (TUNA) first where the network funds it, then KAT; an emptied account that has never contributed is refused until you contribute (--mine) or top up (and what the credit itself is — and is not: token & staking risk).
Why login?
--mine logs you in automatically — zero config, local key ops only. Logging in creates (or claims) your account and its free trial grant — 100 TUNA, 30 days from claim — once per account. The explicit command is the repair path: re-run cargo refine login to repair, or import an existing key on a new machine with cargo refine login --import-key.
Is it on crates.io?
No — Refine ships as checksum-verified prebuilt binaries only, landing in ~/.cargo/bin. It runs as cargo refine inside any Rust crate: a Rust toolchain is needed to use it, not to install it.
Contribute batches, earn KAT — the pro tier: the only tier that earns mining KAT today, and every row on the leaderboard is a miner. Install first (the coder tab's step 1 — same binary), then:
--mine syncs them, and each epoch settle pays miners from the mining pool.Step by step: what goes in and what comes out
1 · Join once
`cargo refine --mine` opts in, auto-logs-in, and runs the first sync — one command, reversible (`--unmine` stops the push half; healing was always local). Consent tiers: Unset never pushes; running sync IS the consent.
2 · The redacted batch
Every heal run auto-syncs the redacted batch: rule verdicts plus the short snippets each fix touched — secret-scanned, never whole files, never your paths, signed with your account key. This is the network's published sample batch, so you can inspect exactly what leaves the machine before opting in.
IN · one --mine batch (published sample)
{ "payload_version": 3, "redact_version": 3, "origin": "own-repo", "created_unix": 1791028699, "rows_included": 4, "rows_blocked": 0, "batch_commitment": "9c0e4935070db7b4b2ce346758824b3efbcc9d9a603bb4143d36f70080b63d58", "account_pubkey_hex": "f57d1724269522a6ce74493d99997cafa6888820fd8f6f33899273f4299460f8", "signature_hex": "08043514c985b9d28aae54630a66639b713de74a0831b2b2d5c1d327b494c120ab02e0dbba7c9b1381ed4a6d4cc13366087b48b113f44bf6e87b183d118a7a0b" } { "shape_id": "7819c50b7076", "lint_key": "filter_next", "domain": "clippy", "shape": "values.iter().filter(|v| *v % 2 == 0).next()", "fix": "values.iter().find(|v| *v % 2 == 0)", "direction": [-0.9384366, 0.010083847, -0.044518255, -0.35203317, 0.107131176, 0.60174465, -0.8606558, 0.07532138], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "c3a6997f234a", "lint_key": "needless_range_loop", "domain": "clippy", "shape": "for i in 0..values.len() {\n total += values[i];\n }", "fix": "for value in values {\n total += *value;\n }", "direction": [-0.31596875, 0.74847627, -0.25766408, -0.7536681, -0.8198199, -0.5253514, 0.24328057, 0.40595883], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "2bd8a283534f", "lint_key": "needless_return", "domain": "clippy", "shape": "return total;", "fix": "total", "direction": [0.6863015, -0.76078856, -0.73800665, 0.8010406, 0.87747365, 0.82867664, 0.25373134, -0.0011432369], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } } { "shape_id": "34fc9d1c297e", "lint_key": "vec-with-capacity", "domain": "rust_perf", "shape": "Vec::new()", "fix": "Vec::with_capacity(words.len())", "direction": [0.7280237, -0.24283206, -0.594867, 0.99811685, 0.058567684, 0.06598411, 0.8178545, -0.09290348], "success_count": 0, "fail_count": 0, "consecutive_fails": 0, "tier": 1, "last_run_id": "run-18db031b945c2c08-80989", "last_seen_at": 1791028693, "elo": 1200.0, "span_elo": 1200.0, "gate": { "decision": "allow", "findings": [] } }cargo refine sync --export on a ~30-line demo crate (4 fixes), signed with the export's throwaway key — published at ai.gist.rs/sample-mine-batch.ndjson and ingest-verified by the worker's test
3 · Proof queue
On push, rows enter the proof queue and are credited only at a real clippy re-run on the queue's own fixture — a verdict is measured, never trusted from the client. Test network today.
4a · KAT at the settle
The epoch settle pays the pool to miners (mining = processing, minted = paid), within seven days of an accepted push. Contributed accounts are never re-gated while depleted. Test network today.
4b · The corpus grows — and leases back
Every verified row grows the fleet's pattern corpus, and the corpus leases back to every machine's retrieval — the flywheel closing. This is the newest row of the recorded corpus history: rules per domain, today.
OUT · the fleet corpus per domain
{ "clippy_lints": 100, "dist": 6, "docker": 31, "kernel_opt": 746, "rust_perf": 168, "sec": 16, "shader_perf": 8, "ts": "2026-10-03" }the fleet corpus per domain, 2026-10-03 — the newest row of the recorded corpus history
cargo refine --mine — run once to join: opts in, logs you in, syncs. After that, every run auto-syncs your redacted batch.First join picks the network — devnet, the live test network, test credit (KAT/TUNA carry no cash value), is the default. Mainnet is not open yet — every gist.rs product runs on this one network first. Agents/CI: RIIR_REFINE_JOIN_ENV=devnet or --yes takes the default; scripted setups that want no prompt at all can cargo refine config set --url devnet.
Why mine?
Every fix run records HOW Refine behaved — which rules fired, which were declined, what merged. Those verdicts, with the code snippets each fix touched (secret-scanned; never whole files, never your paths), are the corpus the network learns from. Miners who contribute them are paid from the mining pool at each epoch settle. Every KAT the network burns is split 70% mining reward pool · 20% treasury (operator) · 10% destroyed by default — the live split is on the KAT page. The fixing already runs on your machine — mining turns that work into network credit.
How do mine / unmine work?
cargo refine — the dry run, private, no account: reviews the current directory (or the paths you name), prints what it would fix, writes and sends nothing. --fix writes — still local, still nothing uploaded.
cargo refine --mine — contribute & earn: opts in, logs you in, syncs. Your code leaves only through sync, and only as a gated batch — rule verdicts, counters and the code spans your fixes touched (secret-scanned; a span with any finding is dropped), never whole files, never your paths — signed with your account key, not encrypted, and public once proven (the data path). Miners are paid from 70% of every KAT the network burns (by default), at each epoch settle. Your burn reports automatically after each run — account accounting, not a consent gate — and offline runs stack locally and report with the next run.
See a batch before you join. Here is a real one, from a small demo crate after cargo refine --fix made 4 fixes: one header line (counts, a checksum of the rows, a signature), then one line per fix — the rule, the snippet before and after, and counters. To check your own repo, cargo refine sync --export batch.ndjson writes the exact batch to a file and sends nothing, with no login (cargo-refine v0.2.1 and later).
Run neither flag and nothing has been uploaded yet — but the unset state is not a refusal: running sync is itself the consent. cargo refine account shows your balance, burn and grant at any tier.
cargo refine --unmine — opt out, stay local: sync stops pushing — no batch built, none signed, none sent. The lease pull half still runs (a read is not a contribution). Fixing is untouched; trajectories keep recording locally. Anything queued under .refine/outbox/ is yours to delete — --unmine neither submits nor deletes your files; --mine turns it back on.
Verify & fix the network's queue — the max tier: a CPU box (~2–4 vCPU, 4–8 GB, no GPU). No download — this is a node lane, not an install.
Step by step: what goes in and what comes out
1 · The unproven queue
Pushed rows wait for proof — nothing credits until a verifier re-runs the gate and the oracle. Test network today.
2a · The operator's drain lane (live today)
Our nodes draft fixes for queued rows over a hosted-LLM lane — free-legs first, USD-capped, redaction-gated. It is a node lane, not a download: nothing for you to install yet.
2b · Replay on your rig (designed) ○ illustrative · planned
The third-party lane would lease queued fixes to your own CPU box, re-run the gate and the oracle locally, and — on K=2 agreement with a second verifier — share a bounded cut of the row's reward. The cut is pinned at zero until ratified; nothing is promised until it settles.
3 · The gates
Every candidate, whichever lane drafted it, passes the same two gates: your crate still compiles, and real clippy is silent on the result. A replay verdict is measured, never guessed — that is why the replay client needs an oracle build.
4 · Pays on the board
Accepted work settles through the miner rows on the public board — the operator lane's earn path today, in public.
The fixer lane runs TODAY as the operator's fixer (our nodes, working on our own repos' failing spans — its accepted work settles through the miner rows you see on the board). Third-party replay verification is designed but its reward class does not settle yet — nothing is promised here until it does.
The operator’s fixer may call hosted LLM APIs to draft fixes, over the operator’s own local records — it does not read the miner queue. Your local cargo refine never calls an AI service.
What replay will be: lease queued fixes, re-run the compile gate + clippy oracle on your rig, agree with a second verifier → both share a bounded cut of the row's reward. Watch this tab.
Host the daily training window — the ultra tier: a GPU rig or container VPS. No download — this is a node lane, not an install.
Step by step: what goes in and what comes out
1 · Stake 1K KAT
The operator bond for hosting a window — designed for third parties; the stake machinery matures first. Local models stay optional and unarmed (measured quality + latency fail; a reopen bar is on record).
2 · The daily window
One container, cron-start, sleep-after — billing is the run window only. The LLM lane is API-first with free legs and a USD cap. It runs today on our replicas only, and the page says so.
3 · Endorsements (a designed class)
Trainer endorsements plus an epoch pool share — the reward class settles when third-party hosts open; until then nothing is promised. v1 windows are fleet-funded from the USD treasury.
Stake 1K KAT, host the daily trainer window (API-first; local models stay optional and unarmed). Ours only at launch — the staking and hosting machinery matures before third-party installs open, and we say so rather than market it.
When it opens: one container, cron-start, sleep-after — billing is the run window only.
Pricing
Free on your machine. Metered when you log in.
The meter always runs locally. Nothing is billed until you log in — and mining earns KAT back.
Logged out free · no account
The dry run and the compile-gated fix, on your machine: never billed, anonymous, earns nothing.
Logged in metered
Each run’s metered total bills your account — free trial credit (TUNA) first where the network funds it, then KAT. Mining (--mine) earns KAT at each epoch settle.
Devnet service credit: KAT carries no cash value and no redemption right.
A logged-in run is billed 1 KAT per million code-word tokens it reads (a code-word token is one whitespace-separated word of code; logged out, nothing is billed), and every
KAT burn funds the next epoch's mining pool. New accounts draw the free trial credit (TUNA) first where the deployment funds it — refine, rethink, everything on the network bills it before KAT. TUNA counters are public. A typical run on a crate the size of the sample above meters 317 code-word tokens ≈ 0.0003 KAT-equivalent — the meter runs locally, and logged out nothing is reported or billed. After the trial, the refuel doors are exactly the client's two: contribute (cargo refine --mine) or top up at the network's payment page.
What is TUNA?
TUNA is the network's free trial credit. The signup grant is TUNA now (not KAT): it pays exactly like KAT — same meter — across the whole network (refine for fixing, rethink for decisions, everything that burns), is drawn before your KAT, and the blue squares in the pulse card below track it (yellow = KAT, green = a day that burned both).
The strings: one grant per account, 30 days from claim, spent on the network's services only, non-transferable, no cash value. Trial burns do not fund the mining pool — KAT burns do. When TUNA runs out (or expires), the network bills KAT as before.
Check your position with cargo refine --info; the network's
two-door counters — spent on fixes vs swept at expiry — are the
public /tuna/stats. Trial credit is funded per
environment: a deployment whose reservoir is not funded answers
unconfigured and fixing bills KAT directly.
Step by step: what goes in and what comes out
1 · The run is metered
The meter counts code-word tokens on your machine and bills a fixed µ rate per million. Logged out, nothing is billed anywhere — anonymous is outside the economy by design. Offline, the burn is a local commit; the next run pushes the cumulative total.
2a · TUNA pays first
Where the deployment funds trial credit, the server draws TUNA first — one grant per account, thirty days, heals only. Trial burns fund nothing and expired credit is inert; the public TUNA counters show the reservoir. Test network today.
2b · KAT pays
After the trial (or where it is not funded), KAT pays — metered totals, signed, watermark-deduped so replays are no-ops. No debt exists: the server clamps warn-and-pay and never goes negative. Test network today.
3 · Every burn funds the pool
Each KAT burn is split by the network's published parameters — mostly into the next epoch's mining pool. The live split renders from parameters on the leaderboard and the explorer; the figure names where the money lands, never a typed percentage.
4 · The settle pays
The once-per-epoch settle fixes each miner's share of the pool and mints it (mining = processing, minted = paid), with mint receipts in public. Test network today.
5 · The lease-back
The fleet corpus every machine leases back — the newest row of the recorded corpus history: rules per domain, today. The wheel closes where it started: your next run retrieves more.
OUT · the fleet corpus per domain
{ "clippy_lints": 100, "dist": 6, "docker": 31, "kernel_opt": 746, "rust_perf": 168, "sec": 16, "shader_perf": 8, "ts": "2026-10-03" }the fleet corpus per domain, 2026-10-03 — the newest row of the recorded corpus history
Roadmap
What is live, and what comes next.
Every piece is marked live, on the test network, or designed. Fixer and trainer are node lanes that open to third parties only when their reward classes settle.
| Piece | Runs on | Status |
|---|---|---|
| Dry run + compile-gated fixes — clippy · perf · docker · dist + compile errors (security, GPU-kernel and shader rules are in preview) | your machine | live |
| The burn meter — TUNA trial credit first where the network funds it, then KAT | your machine + the network | metering live · billing on the test network |
| Mining — redacted batches, proof queue, epoch settle | the network | test network |
| The corpus lease-back — the fleet corpus refreshes retrieval | the network | test network |
| One account across the network — Rethink’s hosted trained decisions bill the same tanks when its lane opens; its measured cells are public today | the network | account live · hosted lane planned |
| Third-party replay verification + trainer hosting | your rig | designed — settles nothing yet |
Each environment shows its own numbers above — you are viewing the test network's ledger.
Agents
For agents.
One file teaches your coding agent to drive cargo refine properly — the dry run before the fix, the compile-gated write, verification at the real feature set, the divergence classes that stay manual, and the contribution loop. Curl-installable, plain instructions, exact commands.
Claude Code
mkdir -p .claude/skills/cargo-refine && curl -fsSL https://ai.gist.rs/skills/cargo-refine/SKILL.md -o .claude/skills/cargo-refine/SKILL.mdZed / any agent
mkdir -p .agents/skills/cargo-refine && curl -fsSL https://ai.gist.rs/skills/cargo-refine/SKILL.md -o .agents/skills/cargo-refine/SKILL.mdWhich agents does it work with?
Claude Code reads .claude/skills/ natively; Zed reads .agents/skills/. And any agent that accepts a markdown instruction file works — the skill is plain instructions plus exact commands your agent already knows how to run.
What does it change?
Without it, an agent fixing lint warnings hand-rolls edits and re-runs clippy hoping. With it, it dry-runs first, applies compile-gated fixes, verifies cfg-gated code at its real feature set, leaves the documented divergence classes manual, respects bench files, and reads the balance + contribution loop correctly — measured fixes instead of churn.