<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Writing on cameronqj</title>
    <link>https://cameronqj.com/writing/</link>
    <description>Recent content in Writing on cameronqj</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <copyright>Cameron Jones</copyright>
    <lastBuildDate>Fri, 24 Jul 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://cameronqj.com/writing/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>You can&#39;t govern what you can&#39;t verify</title>
      <link>https://cameronqj.com/writing/you-cant-govern-what-you-cant-verify/</link>
      <pubDate>Fri, 24 Jul 2026 00:00:00 +0000</pubDate>
      <guid>https://cameronqj.com/writing/you-cant-govern-what-you-cant-verify/</guid>
      <description>What building an agent harness taught me about controlling systems I don&amp;#39;t fully trust.</description>
      <content:encoded><![CDATA[<p>I set out to answer a simple question: does wrapping a model in an orchestration loop improve its answers? The idea was to put the scientific method around the model: generate an answer, test it, inspect the failure, and revise.</p>
<p>I never got a clean answer. I learned something more useful instead: I couldn&rsquo;t govern even this small system until I could independently verify its behavior.</p>
<p>Several apparent model failures were something else: a token ceiling, a serving default, an uneven comparison, or a bug in my control flow. The score told me that a model had failed. It rarely told me which part of the system had failed or why.</p>
<p>That became the more interesting result.</p>
<h2 id="the-score-was-right-but-the-explanation-was-wrong">The score was right, but the explanation was wrong</h2>
<p>Early runs showed a model returning nothing usable. My harness recorded a capability failure.</p>
<p>The raw response told a different story. The model had spent its completion budget on hidden reasoning tokens, hit the ceiling, and stopped with <code>finish_reason: length</code> before producing an answer.</p>
<p>After I raised the limit, 8 of 27 successful calls used more than the old 1,200-token ceiling, almost entirely on hidden reasoning. The model had not necessarily failed at the task. I had cut it off before it could answer.</p>
<p>The pass/fail result alone could not reveal that. I needed two separate things: verification to tell me whether a valid answer existed, and telemetry to explain why it did not.</p>
<h2 id="the-model-wasnt-the-whole-system">The model wasn&rsquo;t the whole system</h2>
<p>My most convincing &ldquo;the stronger model is better&rdquo; result compared a frontier model running inside a mature coding agent with an open model accessed through a raw API.</p>
<p>The token accounting made the problem obvious:</p>
<ul>
<li>Frontier side: 67,991 input tokens</li>
<li>Open-model side: 1,320 input tokens</li>
</ul>
<p>One side had an agentic loop, tools, retries, internal turns, and a tuned system prompt. The other received one completion request.</p>
<p>The result was real in the narrow sense that one system completed the task and the other did not. But I had not isolated model capability. I had compared two systems with very different amounts of machinery around them.</p>
<p>Most of that machinery was missing from the result table.</p>
<p>Any useful account of an agent&rsquo;s behavior has to include the scaffold: which tools it used, how many attempts it received, what information it saw, what the framework changed between turns, and how the final answer was extracted. Looking only at the model leaves much of the actual system unobserved.</p>
<h2 id="my-enforcement-code-was-wrong-too">My enforcement code was wrong too</h2>
<p>The orchestrator was supposed to inspect failing answers and repair them. When I reviewed the control flow, I found that it was rewriting answers before checking whether they were already correct.</p>
<p>The loop was quietly degrading passing results.</p>
<p>Left unfixed, the experiment would have produced a plausible conclusion: orchestration does not help and may make answers worse. The conclusion would also have been wrong. I would have been measuring an ordering bug in the code responsible for running the experiment.</p>
<p>That changed how I thought about the harness. The code enforcing the rules could not be above scrutiny. It needed its own invariants and tests.</p>
<p>Verification had to happen before revision. A passing answer had to remain untouched unless the system could produce evidence that it no longer passed. Every transition needed to be visible.</p>
<h2 id="the-checker-was-part-of-the-attack-surface">The checker was part of the attack surface</h2>
<p>My checks also admitted shortcuts. A candidate could satisfy the letter of a test by hardcoding a value, exiting early, or bypassing the behavior I intended to measure.</p>
<p>A passing check was therefore not enough. I needed adversarial probes for the obvious shortcuts and a way to mark ambiguous results as invalid rather than quietly counting them as successes.</p>
<p>I&rsquo;m careful with the word &ldquo;gaming&rdquo; here. A model does not need to understand that it is cheating. If the shortest path to a reward exploits a weakness in the evaluator, the effect is the same: the score says one thing while the execution says another.</p>
<p>The verifier is part of the system under test.</p>
<h2 id="what-made-a-result-believable">What made a result believable</h2>
<p>I eventually settled on a few structural rules.</p>
<p>Authority lives in code. The model cannot grant itself more attempts, a larger budget, or additional tools through its output. Those limits hold whether the model understands them or not.</p>
<p>Where an answer can be checked through execution, I run the check in an isolated environment. An LLM judge may be useful for qualitative work, but it should not replace a deterministic test that already exists. Model judges can share blind spots with the outputs they grade.</p>
<p>Ambiguous outcomes fail closed. Hardcoded answers, premature exits, incomplete traces, and unverifiable success claims are not passes.</p>
<p>The orchestration receives the same scrutiny as the model. I record enough about control flow, tool use, budgets, and endpoint behavior to identify which layer produced a failure without logging raw prompts by default.</p>
<p>Runs retain their lineage. Inputs, configuration, decisions, and derived artifacts have enough parentage to reconstruct a result instead of accepting it on faith.</p>
<p>None of these controls depend on the model or its prompt cooperating.</p>
<h2 id="from-an-eval-problem-to-a-control-problem">From an eval problem to a control problem</h2>
<p>These experiments do not prove a general loss-of-control thesis. They made the underlying engineering problem concrete.</p>
<p>In an eval, weak enforcement or bad telemetry produces a misleading number. When an agent can call APIs, modify a repository, spend money, or act under standing credentials, the same class of failure produces an external side effect.</p>
<p>The questions become more consequential, but they are familiar:</p>
<ul>
<li>What was the system allowed to do?</li>
<li>Which component granted that authority?</li>
<li>What did it actually do?</li>
<li>Can the claimed result be checked against external state?</li>
<li>Does the record remain trustworthy if the model, prompt, or orchestration is buggy, compromised, or simply opaque?</li>
</ul>
<p>A stronger system prompt cannot answer those questions. The boundary has to exist outside the model: scoped credentials, budgets enforced in code, action receipts, immutable audit records, and independent verification of effects.</p>
<p>Better models still matter. Better orchestration matters too. Neither removes the need for controls that keep working when the system gives you a convincing but incorrect account of itself.</p>
<p>I started out trying to build a loop that made a model perform better. I came away more interested in the layer around that loop: one that bounds its authority, records what it changes, and checks its claims against the world.</p>
<p>I learned that lesson on functions that fit on a screen. The agents won&rsquo;t stay that small.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
