promptdojo_

building a harness — scaffold, tools, loop, gate — step 8 of 9

write build_harness_run(spec, inputs, tools, fake_model, max_iters) end-to-end with the fake_model:

  • prep: build messages from spec + inputs — include name, trigger, the inputs dict, decisions, and writeback in the user turn.
  • loop up to max_iters:
    • call fake_model(messages)
    • parse text vs tool_use blocks
    • on end_turn: return {text, iters, tool_calls, gate}
    • dispatch only names on spec["allowlist"]. skip the rest. track tool_calls for names you actually ran.
  • on cap: text is "capped", iters is max_iters.
  • gate: "fail" if the allowlist was violated (the model named a tool that is not on spec["allowlist"]) or the run hit max_iters (text == "capped" or iters > spec["eval_gate"]["max_iters"]). otherwise "pass" iff spec["eval_gate"]["must_call"] was dispatched and spec["eval_gate"]["must_include"] is in text.

two cases run. the spec is a shift-board / handoff triage. expected output:

text='ROUTE night.' iters=2 tool_calls=1 gate=pass
text='done.' iters=2 tool_calls=0 gate=fail

full-screen editor opens — close anytime to keep reading.