Refine

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 | sh

macOS 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 --fix never 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.

Fix corpus — pattern classes per domain

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.

NovDecJanFebMarAprMayJunJulAugSepOct
MonWedFri
kernel_optrust_perfclippydockerothersecdist
kernel_opt845
rust_perf179
clippy137
docker31
other25
sec16
dist6
Self-evolve

quality measured on a single machine

rules shipped — cumulative, per domain

2026-08-132026-09-082026-10-03

ladder — hardest benchmark generation admitted

ladder steps: 2026-09-12 ▲8

fix rate — gen 1

kernel_optrust_perfclippysecdockerdistotherladder (hardest gen admitted)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).

Network pulsedevnet · test network, test credit
NovDecJanFebMarAprMayJunJulAugSepOct
MonWedFri

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

Network adoptiondevnet · test network, test credit
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.

100%50%0
Mar 5Jun 18Oct 8
mining users / epochearned records / epoch
machinetieraccountlast notesuccess% (pushed/earned/dup/queued)
inc79c…53452026-10-0560% (655/395/260/0)
in8f5a…a4272026-10-05100% (3/3/0/0)
in7161…bd292026-09-164% (7210/287/6923/0)
in518a…81762026-09-17100% (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.

captured on a sample crate — cargo-refine 0.2.1, logged out
$ 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`)
then the fix — every edit compile-gated, kept only if the crate still builds
$ 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.

One pass, three steps — tested with hotpath 0.28

1 — instrument, then run your workload as usual.

cargo add hotpath --features hotpath,hotpath-alloc

Put #[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.json

The 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 --fix

Your 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.

9 steps in path order. 1. Scan: the span pool over your crate — a dry run writes nothing (your machine; live). 2. Retrieve: corpus rules + your past fixes, top-K (your machine; live). 3. Draft + validate: modelless proposers draft; a real-clippy oracle judges (your machine; live). 4. Fix, compile-gated: kept only if your crate still compiles (your machine; live). 5. Record: every verified outcome becomes a trajectory (your machine; live). 6a. If verified outcomes: Learn: skill memory updates from verified outcomes (the learning loop; live). 6b.1. If opt-in: Mining batch: opt-in: redacted records queue to leave (the kat fleet; test network). 6b.2. If syncs: Proof + payout: verified at real clippy; the epoch settle pays KAT (the kat fleet; test network). 7. If the corpus grows: Leased corpus: the fleet corpus refreshes retrieval on every machine (back to your machine; test network). From 6a back to 2: sharper retrieval next run. From 7 back to 2: every machine retrieves more.
The self-evolve flywheel: every local fix is recorded, verified fixes teach Refine, and opt-in mining feeds the fleet — the corpus comes back to every machine. Numbered steps in path order; lanes group who runs each stage. How it works
Step by step: what goes in and what comes out
  1. 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. 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. 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. 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. 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.

  6. 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

  7. 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

  8. 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.

  9. 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

In plain words
dry run
cargo refine with 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.

8 steps in path order. 1. Your fix run: compile-gated, local; records each fix (your machine; live). 2. One row per fix: the span it replaced + the fix; no paths (your machine; live). 3. Secret scan + sign: a finding drops the row; Ed25519 signed (your machine; live). 4a. If export: Export only: sync --export writes a file, sends nothing (your machine; live). 4b. If send: Sent over HTTPS: the signed batch; the server checks the key (the network; test network). 5. If queued: Proof queue: a real clippy re-run confirms the fix (the network; test network). 6. If proven: Public corpus: proven before/after pairs, downloadable (everyone; test network). 7. If pull: Lease back: every machine downloads the corpus (your machine; test network). From 7 back to 1: your next run retrieves more.
Nothing on this path runs unless you opt in. Steps 1–3 and 4a stay on your machine; 4b sends the signed batch; a proven pair (6) is public. Press play to walk it step by step; lanes say who can read the data at that step.
Step by step: what goes in and what comes out
  1. 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. 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. 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.

  4. 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

  5. 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.

  6. 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.

  7. 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.

  8. 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.

Our promises — and how to check them

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.

Your code and the network — questions
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.

node tiers — what you can run
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.

Get started

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.

5 steps in path order. 1. Install: one prebuilt binary lands in ~/.cargo/bin (your machine; live). 2. Dry run: lists the fixes it would make, writes nothing (your machine; live). 3. The compile gate: kept only if your crate still compiles (your machine; live). 4a. Fixed code: clippy · perf · docker · dist + compile errors (your machine; live). 4b. If logged in: The burn meter: 1 KAT-equiv / 1M tokens; TUNA first where funded (the billing plane; live).
The coder loop: install once, dry-run first, then the compile-gated fix — the burn meter draws your TUNA trial credit before KAT.
Step by step: what goes in and what comes out
  1. 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. 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. 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.

  4. 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.

  5. 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.

1install — pick your operating system:
brew tap gist-rs/tap && brew trust gist-rs/tap && brew install cargo-refine

or

curl -fsSL https://raw.githubusercontent.com/gist-rs/cargo-refine/main/install.sh | sh
About 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.

2cargo refine — dry run: lists the fixes it would make and writes nothing.
3cargo 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).
4optional — join the network (the miner tab's step 2): first join picks the network — devnet (the live test network, test credit) is the default; mainnet is not open yet. Agents: 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.

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.

What is KAT?

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.

6 steps in path order. 1. The run is metered: counts code-word tokens; logged out = never billed (your machine; live). 2a. If trial credit left: TUNA pays first: where funded: one grant · 30 days, expires (the ledger; test network). 2b. If after TUNA · logged in: KAT pays: after the trial — metered totals, signed (the ledger; test network). 3. If burns: The mining pool: every KAT burn funds the next epoch's rewards (the ledger; test network). 4. If the epoch closes: The settle pays: rows mint — mining = processing, minted = paid (miners; test network). 5. If the corpus grows: The lease-back: the fleet corpus refreshes every machine (your machine; test network). From 5 back to 1: every machine refines better.
The KAT economy, end to end: the meter runs on your machine, trial credit pays first and funds nothing, every KAT burn funds the pool that pays miners — and the corpus leases back to every machine. The live split renders from parameters on the leaderboard; what the credit is — and is not — is on the token & staking risk page. Numbered steps in path order; lanes group who runs each stage.
Step by step: what goes in and what comes out
  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

What is live, and where it runs
PieceRuns onStatus
Dry run + compile-gated fixes — clippy · perf · docker · dist + compile errors (security, GPU-kernel and shader rules are in preview)your machinelive
The burn meter — TUNA trial credit first where the network funds it, then KATyour machine + the networkmetering live · billing on the test network
Mining — redacted batches, proof queue, epoch settlethe networktest network
The corpus lease-back — the fleet corpus refreshes retrievalthe networktest network
One account across the network — Rethink’s hosted trained decisions bill the same tanks when its lane opens; its measured cells are public todaythe networkaccount live · hosted lane planned
Third-party replay verification + trainer hostingyour rigdesigned — settles nothing yet

Each environment shows its own numbers above — you are viewing the test network's ledger.

Agents

For agents.

Give your coding agent a code fixer that learns.

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.md

Zed / 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.md
Which 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.