Hmbown/CodeWhale · error · RuntimeError

Codewhale terminal receipt did not confirm auto tools

Error message

Codewhale terminal receipt did not confirm auto tools

What it means

exec is launched with --auto, letting tools run without per-call approval; the terminal receipt must confirm approval_posture='auto_tools'. The assertion guarantees the measured rollout was not silently downgraded to an approval-gated mode, which would stall headless runs and change tool behavior.

Source

Thrown at integrations/verifiers-codewhale/codewhale_harness/harness.py:232

        ]
        if self.config.max_turns is not None:
            argv.extend(["--max-turns", str(self.config.max_turns)])
        if self.config.disabled_tools:
            argv.extend(["--disallowed-tools", ",".join(self.config.disabled_tools)])
        if system:
            argv.extend(["--append-system-prompt", system])
        argv.extend(["--", str(prompt or "")])

        result = await runtime.run_program(argv, env)
        if result.exit_code == 0:
            receipt = _parse_stream_receipt(result.stdout)
            terminal = receipt["terminal"]
            if terminal.get("provider") != "openai":
                raise RuntimeError("Codewhale terminal receipt did not use provider openai")
            if terminal.get("model") != ctx.model:
                raise RuntimeError("Codewhale terminal receipt model did not match rollout")
            if terminal.get("approval_posture") != "auto_tools":
                raise RuntimeError("Codewhale terminal receipt did not confirm auto tools")
            if terminal.get("sandbox_posture") != sandbox:
                raise RuntimeError("Codewhale terminal receipt sandbox did not match launch")
            if receipt["events"].get("error", 0) != 0:
                raise RuntimeError("Codewhale successful run contained an error event")
            if terminal.get("status") != "completed":
                raise RuntimeError("Codewhale terminal receipt did not report completion")
            if terminal.get("termination_reason") != "resolved":
                raise RuntimeError("Codewhale terminal receipt was not resolved")
            trace.info["codewhale"] = receipt
        return result


def _has_version(output: str, version: str) -> bool:
    return (
        re.search(
            rf"(?<![0-9A-Za-z.+-]){re.escape(version)}(?![0-9A-Za-z.+-])",
            output,
        )

View on GitHub (pinned to 8880682c63)

Solutions

  1. Remove approval-forcing settings from the config inside the isolated home
  2. Emit approval_posture='auto_tools' in facade terminal metadata
  3. Run the release matching the pinned version so receipt field names match

Example fix

# before (facade)
meta = {'approval_posture': None}
# after
meta = {'approval_posture': 'auto_tools'}
Defensive patterns

Strategy: try-catch

Try / catch

try:
    result = await harness.launch(ctx, trace, runtime, endpoint, secret, mcp_urls)
except RuntimeError as e:
    if 'did not confirm auto tools' in str(e):
        audit_facade_receipt('approval_posture')  # inspect raw stream-json stdout
    raise

Prevention

When it happens

Trigger: A binary or home config forcing conservative approval despite --auto; facades omitting approval_posture; receipt vocabulary drift in binaries that do not match the pinned release.

Common situations: Default configs requiring confirmations; facades written against older receipt schemas; version skew between the binary and the 0.9.1 pin.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/2289aab9b9350313. Report an issue: GitHub.