Tuning tman for Ruff
Fast enough that the caps are only there to catch a pathological case.
Recommended starting caps
| cap | start at | what it answers |
|---|---|---|
stall | 5m | hang backstop — no output and no CPU/IO activity for this long |
max-time | 5m | wall-clock budget — the only cap that bounds a run that is working but will never finish |
max-mem | unset — opt in only if it has hurt you | RSS ceiling across the process tree |
max-parallel | 4 | slots per name-and-directory bucket |
These are starting points derived from how Ruff behaves, not measurements of your machine. Every one of them should be replaced by a number you took from your own runs — the last section on this page is how.
alias "lint" {
command "ruff"
args "check" "."
max-time "5m"
max-parallel 4
}Ruff lints a large repository in under a second. Supervising it is not about controlling resource use — there is none to control. It is about two other things.
A cap that fires is a signal
A five-minute max-time on a command that normally takes 800 milliseconds will never fire on healthy work. If it does fire, something is genuinely wrong — a filesystem that has stopped answering, a symlink loop, a network mount — and you find out through a clear exit 124 rather than through an agent that appears to have gone quiet.
Consistency is worth more than the cap
The other reason is uniformity: if every command in the project goes through an alias, then tman list shows the whole picture, tman status --json gives you durations for everything, and there is no category of command that quietly runs unsupervised because it seemed too small to bother with. The same reasoning applies to Biome and to formatters.
ruff format --checkdeserves its own alias rather than being folded intolint. A single alias that does both gives you one exit code for two questions, and the answer an agent needs — reformat, or fix a rule — is different in each case.
Turn the starting point into a real number
Everything above is derived from how this tool behaves, not from your machine. The numbers that matter come from your own runs, and getting them takes one command:
tman status --json | jq '.runs[] | {name, exit, duration_ms}'Set max-time from the slowest successful run you are willing to wait for, with real headroom — a cap that fires on healthy work teaches everyone to raise the cap, and after a few rounds of that it bounds nothing. Set stall from the longest stretch the command legitimately produces no output and no CPU, then double it.
Exit 124, 125, and 126 are findings, not flakes. 124 is a wall-clock timeout, 125 a stall, 126 a resource cull. Widening the cap that fired is the right response only after you know why it fired — the first two times a suite trips
max-mem, the interesting question is what is holding the memory.
Frequently asked
Is it worth supervising a linter as fast as Ruff?
Yes, for two reasons that are not about resource control. A cap that never fires on healthy work turns a genuinely wedged filesystem into a clear exit 124 instead of a silent pause. And if every command goes through an alias, `tman list` and `tman status --json` show the whole project rather than the parts that seemed big enough to bother with.