A tool-calling agent runtime with no framework under it, built against a small local model on purpose.
A canned replay of 1 real run over the Meridian corpus, the invented dataset the repo ships so retrieval cannot be bluffed. Nothing here calls a model.
Read it top to bottom. On the left are the inputs and config that feed 1 turn. The centre spine is the loop: count the budget, call the model, parse and repair, check for a tool call, clear permissions, run the tool, confine its paths. The right shows what each turn produces. The amber path is the guardrail layer, path confinement plus the permission gate, which a hostile review broke after the build and which is rewritten here to what defends it now.
A frontier model hides bad tool calls behind constrained decoding. Building against llama3.1:8b is what forces parse, validate, retry to be real rather than aspirational.
python was on the bash allowlist, so python3 -c 'open(...)' wrote outside the root, and bash never called path confinement at all. Both fixed, both with regression tests, all in REVIEW-2026-07-25.md.
The model decides whether to search, reformulates the query, and can search twice for a two-part question. A preprocess step retrieves once, on the original wording, for every question including "thanks".
No LangChain, no LlamaIndex. The loop is 53 lines with its error handling; everything else exists because it breaks in exactly 4 ways.
On 10 tasks llama3.1:8b emitted clean JSON every call while qwen2.5-coder:7b needed repair on 70%.
hit@3 is 0.90 across 20 pairs: 1.00 when the question uses the document's own words, 0.71 when it does not.