Direct answerDefine required obligations before or during task compilation. Keep each obligation in a state such as UNKNOWN, VERIFIED or CONFLICT. Let evidence and deterministic verification update those states. Report DONE only when every required obligation satisfies the task contract. The model should not have a privileged “Done” action that bypasses the gate.

Why agents stop too early

Language models are trained to produce plausible completions. In a tool-using workflow, that creates a subtle risk: the model can mistake a good-looking intermediate state for completion.

Examples include:

  • a search returned one relevant source, but two independent facts were required;
  • a file write succeeded, but the resulting content was wrong;
  • a command exited with code 0, but the service did not become healthy;
  • a browser click executed, but the form never submitted;
  • one source says version A and another says version B;
  • a calculation was performed, but one required input was never verified.

A completion gate makes those conditions explicit instead of relying on the model’s confidence.

Start by defining DONE

Before execution, turn the goal into a small task contract. The exact representation varies, but it should identify what must be true at the end.

For example, “Find the current stable version and write it to result.json” might require:

  1. the stable version fact is verified from acceptable evidence;
  2. the target file exists;
  3. the file contains the verified version in the required schema;
  4. the final file has been independently read back and verified.

The last condition matters. The write receipt alone should not satisfy it.

Use explicit obligation states

A useful minimal state model is:

UNKNOWN — required fact or postcondition is not yet proven.

VERIFIED — accepted evidence satisfies the defined condition.

CONFLICT — accepted evidence disagrees and the system cannot safely choose one value.

The completion rule becomes simple: required UNKNOWN or CONFLICT blocks successful DONE unless the task contract explicitly permits an unknown result.

The model should propose, not certify

A robust Controller can expose actions such as:

  • call a tool;
  • propose a fact;
  • request clarification;
  • report that something cannot currently be verified.

It does not need a model action named Done.

The model can believe the work is complete. The runtime still checks the obligations.

Evidence should drive state transitions

A completion gate is only as good as the evidence feeding it. Tool results should be converted into evidence records with enough identity to know which obligation and value they support.

Where possible, deterministic code should perform the transition. If a JSON response contains the required field, code can extract it. If two accepted values disagree, code can mark a conflict. If a count or sum is required, code can derive it without asking the model to perform bookkeeping.

Mutation tasks need postconditions

The most common weak completion pattern is:

write tool returned success → mark task complete.

A stronger pattern is:

mutate → receive receipt → independently observe → verify postcondition → complete or recover.

This applies beyond files:

  • UI: click → inspect resulting UI state.
  • Process: start service → query health.
  • Configuration: write setting → read effective setting.
  • Database: update → query resulting record.
  • Remote device: send command → observe device state or returned evidence.

Completion gates should fail closed, not freeze forever

Fail-closed does not mean every uncertainty becomes a permanent stop. The gate can reopen an obligation and allow another route.

A useful loop is:

attempt → observe → verify → PASS / FAIL / UNKNOWN → retry, alternate route, clarification or stop.

Retry budgets and duplicate-call detection prevent the system from looping forever while still allowing recovery from real failures.

Conflicts deserve their own state

If two trusted sources disagree, selecting whichever answer appeared last destroys evidence. A CONFLICT state preserves the fact that the system does not yet have a defensible answer.

The next action can then target conflict resolution: prefer a primary source, compare timestamps, seek a third source or ask the user to choose the relevant interpretation.

Completion should be evidence-only

A final response can be written in natural language, but the facts it asserts should come from verified runtime state. The finaliser should refuse to manufacture certainty from unverified model prose.

This is especially important when the model generated an appealing summary before all obligations were complete.

Example: the ARKTOR write sentinel

In one retained ARKTOR Controller V0.2 test, a model wrote the wrong summary payload. The filesystem tool correctly returned a successful write receipt. A legacy integration path incorrectly promoted that receipt to semantic DONE. An independent scorer read the file and rejected it.

The public result remained 8/9, and the missing invariant became explicit: mutation receipt is not semantic proof.

The engineering story is documented in Tool Success Is Not Goal Success.

Practical completion-gate checklist

  • Is DONE defined before the agent starts acting?
  • Does each required condition have an explicit state?
  • Can UNKNOWN remain UNKNOWN without model pressure turning it into a guess?
  • Can conflicting evidence block completion?
  • Are deterministic derivations performed in code?
  • Does every important mutation have an observable postcondition?
  • Can failed postconditions reopen the task for recovery?
  • Are retries bounded?
  • Can the model bypass the gate with a “done” message? It should not.
  • Does the final answer come from verified state rather than free model prose?

The useful principle

A completion gate does not make an agent less autonomous. It makes autonomy accountable to the task definition.

The model can still choose useful next steps. The system simply refuses to confuse “the model stopped” with “the user’s goal is proven complete”.