Skip to content

double-billing

If a rulebook gives two ways to say "this costs wood," the model will eventually say both, and pay twice.

The mechanism

The adjudicator's delta vocabulary has two ops that can carry a cost:

  • {"op": "spend", "resource": "wood", "amount": 2} — pay from stock
  • {"op": "repair", ..., "materials": {"wood": 2}} — a repair's price

During the first real-model playtest (qwen2.5:14b, 2026-07-08 — see the playtest ledger), the model proposed both for the same braced door: a spend of the wood and the same wood as the repair's materials. Deltas are validated in order against a live working copy, so the spend drained the stock and the repair then bounced with "you don't have 2 wood" — the player burned wood and got no repair, on a proposal that looked internally sensible.

The fix, and what it predicts

A prompt rule in hunker/adjudicator.py (SYSTEM): "Each cost appears EXACTLY ONCE. A repair's materials are its whole price." Plus deduping of repeated bounce reasons in the log (dict.fromkeys), because the same mistake tends to arrive several times in one proposal.

Prediction: any structured-output vocabulary where one real-world cost has two encodings will elicit double-encoding from weaker models. Either collapse the encodings (one op per cost) or state the exclusivity rule explicitly in the prompt. We kept two ops because repair needs its materials bound to it for validation — so the rule went in the prompt.

Open question (parked in the try-anything PR): whether partial application (legal deltas apply, illegal bounce) is fairer than all-or-nothing when the illegal half was the model's bookkeeping error rather than the player's overreach.