Most scaffolders hand you a stub. You run the generate command, you get a file with the right shape and a // TODO: implement where the actual work goes, and the rest is on you. That’s fine, it’s upfront, and it’s most of what the rtb scaffolder does too: it’s the Rust port of the go-tool-base one, it works from a single manifest, and it regenerates without clobbering the code you’ve written. If you want the whole tour, those three cover it.
This is about the one bit they don’t, which is what happens when you ask the scaffolder to write the implementation, not just the stub.
rtb generate command --prompt "add a command that lists the user's pinned repos" doesn’t drop a TODO. It drafts the actual command, with AI doing the drafting. Which sounds great in a demo and is a menace in practice, because AI-drafted code that doesn’t compile is strictly worse than a stub. A stub at least admits it’s empty. A plausible-looking command that references a function that doesn’t exist, or borrows something it can’t, or compiles but fails its own test, costs you more time to discover and unpick than writing it yourself would have. The generation isn’t the hard part. Trusting the output is.
Which is why the real work didn’t go into the generating at all. It went into ai/verifier.rs, a repair loop wrapped around the one grader in the Rust ecosystem that cannot be sweet-talked: cargo.
It runs in stages, and each stage is a gate. cargo check: does it compile? If not, the compiler’s error goes straight back to the AI as the next instruction, and it tries again. Then cargo clippy: is it idiomatic, does it trip any lints? Same deal, the lint output is the prompt for the next pass. Then cargo test: does it actually do the thing? A failing test is just another error to feed back. The loop only stops when all three are green, or when it hits --max-repair-iterations and gives up and tells you, rather than handing you something broken with a confident smile.
That cap is there on purpose, by the way. The loop is bounded on purpose, because AI repair loops have a lovely failure mode where they churn forever, each pass convinced it’s nearly there, burning tokens and time on something that was never going to converge. So there’s a cap, and when the cap is reached the scaffolder stops, tells you it couldn’t get there, and leaves you the last attempt plus the errors. That’s a far better outcome than the alternative, which is a tool that either loops to infinity or ships code that doesn’t build.
The bit I’m most attached to, though, is --agentless. It short-circuits the whole AI path. No drafting, no repair loop, no model in the chain at all, just the deterministic templating you’d get from any other scaffolder. And I built that in deliberately, because the moment an AI step becomes load-bearing in a tool other people depend on, you’ve added a requirement that there’s a model available, a network, an API key, and a budget. Sometimes you want none of that. CI that has to be reproducible. An offline machine. A change where you simply don’t want a model anywhere near the diff. --agentless keeps the AI an accelerator rather than a dependency, and a tool that can’t run without a model is a tool with a single point of failure you didn’t choose.
Generating the code is the cheap bit, and verifying it is the actual product. Anyone can wire a model up to write a Rust function. What makes it a tool and not a party trick is that nothing it writes gets anywhere near your project until cargo has had its say. The AI writes the first draft. Cargo decides whether you ever see it.
