Skip to content

Authored-choice response continuity

The roof encounter's production check returned a Chinese acceptance with no native decision. A read-only local reproduction using the signed-in QA account's configured model/settings captured the raw provider output: English included classicDecision:1; the next Chinese reply omitted the field. Stored assistant history is intentionally speech-only. The parser incorrectly interpreted omission as a deliberate clarification, so a promise could appear without its action.

Every authored binary/classic choice now gets a final response contract after conversation and account prompts. It names the required field and only the currently legal values. Gift-box replay and already opened slots remain restricted. One explicit null can still answer a question; after the existing server-owned exchange receipt, only a legal decision is allowed. Omitted decisions are rejected before speech or memory is accepted. There is no inference of actions from prose, extra model call, or automatic spending retry. Ordinary chat and numeric puzzle rules are unchanged.

Verification:

  • Regression tests first reproduced the omitted-field failure for source choices, classic bargains and the roof offer, plus the missing final contract after account preferences.
  • All 365 game-NPC tests pass; full pnpm build and pnpm typecheck pass.
  • The same live provider reproduction now includes decision 1 in both EN and ZH with conversation history. It used a read-only database transaction and local QA usage receipts; it did not change account settings or saves. This is not a claim that every provider will always produce valid JSON.
  • The failed production QA notebook was removed by exact signed-in owner and disposable campaign ID after checking that no save referenced it. Player saves were unchanged.

Game worktree evidence: output/roof-favor/provider-before.json, provider-after.json, live-ai.json and cleanup.json. The later public endpoint/release check is still required before publishing the roof package.