Limits Before Tools


Phase 10 gave kodr a single-shot coding loop: one prompt, one proposal, done. The obvious next move is tools - let the model list files, read them, write them, run commands, fetch a URL, and loop on the results. That is also the move where a harness quietly becomes dangerous, so kodr phase 11 does it limits-first.

The tools

Five primitives, owned by a ToolRunner:

  • list_files
  • read_file
  • write_file
  • run_command
  • fetch_url

The nice part is how little of this is new. write_file runs through the safe-write gate - same path jail, same backups. run_command reuses the verification allowlist - no shell, just the handful of approved checks. fetch_url is the one genuinely new risk, so it blocks local and private network targets out of the gate (no SSRF into localhost or 169.254.x.x, thanks).

So the tools are mostly thin wrappers over modules I already locked down across the last few phases. That was the plan all along.

The bit that’s actually new: budgets

A tool you can call once is a function. A tool you can call in a loop is a liability. The ToolRunner owns two things specifically for the loop that does not exist yet:

  • Budgets. Every tool call counts against a limit. Run out and the run stops. A model cannot read-file its way into infinity.
  • Duplicate-call detection. If the model makes the same call with the same arguments again, that is almost always a stuck loop, not progress. So it gets caught and stops.

The tests are mostly about the unhappy paths: each tool works, sure, but also budget exhaustion stops the run and a repeated call trips the duplicate detector.

Why this order

Tools amplify model mistakes. A wrong answer is cheap; a wrong answer with a write_file and 40 iterations of budget is expensive. Budgets, duplicate detection, path jails, command allowlists, and network blocks all have to exist before you put tools inside an iterative loop - otherwise the first thing your shiny new agent loop does is faithfully execute a small disaster.

So phase 11 builds the tools and their cage, and stops there. The loop that uses them comes next.

Links: