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.