v3.11.3 — wiki entry summaries were generated as JSON (#285) #292
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/lore-summary-prose"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Supersedes v3.11.2, which was tagged but never deployed to production. The dev deploy caught this against a real LLM.
No migrations.
BOT_CONTRACT_VERSIONstays 1.The bug
An approved wiki entry came out with a summary of
{"proposals":[]}.generate_structured_textdefaults tojson_mode=Truewith_LORE_PROPOSAL_SYSTEM_PROMPT. The summary task called it bare, so it asked the model for:…in the user prompt, while the system prompt simultaneously instructed it to emit lore proposals as JSON. The model followed the system prompt, and the result was stored verbatim as
entry.summary.Fixed by passing an explicit prose system prompt and
json_mode=False, matching how the journal and lore-merge tasks already call the same transport.Why this is release-blocking rather than a minor fix
The bug predates v3.11.2. But it was only ever reachable through the manual "regenerate summary" button, which is rarely used.
v3.11.2 (#285) made that generator run on every proposal approval. So a latent bug became a data-corrupting one: it would have written JSON into the summary of every entry a GM approves, at exactly the moment the feature started being useful.
Why the test suite missed it
Every test mocks at the
generate_structured_textseam. They assert that the task is called and that its result is stored — never that the request asks for the right output format. No amount of the existing 880 tests would have caught this; it took a real model on a real deploy.The new test closes that specific gap: it captures the transport kwargs and asserts both
json_mode=Falseand a prose system prompt, plus that a stored summary never begins with a brace.Production data
Checked, read-only: 46 lore entries, none with a summary at all. The generator had no automatic trigger before v3.11.2 and the manual button had evidently never been used, so there is nothing to repair.
On the version number
v3.11.2's tag and release are left in place rather than rewritten. Anything that already pulled that tag should get a version number that differs from the fixed code, not the same number with different contents.
Verification
ruff check+ruff format --check: clean, 194 filesscripts/check_version_sync.py: OK — app 3.11.3, bot contract v1🤖 Generated with Claude Code
Caught on the v3.11.2 dev deploy, against a real LLM: an approved wiki entry came out with a summary of `{"proposals":[]}`. `generate_structured_text` defaults to `json_mode=True` with `_LORE_PROPOSAL_SYSTEM_PROMPT`. This task called it bare, so it asked the model for "a 2-3 sentence summary… plain prose only — no headings or bullet points" in the user prompt while the system prompt simultaneously instructed it to emit lore proposals as JSON. The model followed the system prompt, and the result was stored verbatim as entry.summary. The bug predates this work, but it was only ever reachable through the manual regenerate-summary button. #285 made the task run on every proposal approval, which would have written JSON into the summary of every entry a GM approves — so a latent bug became a data-corrupting one. Now passes an explicit prose system prompt and json_mode=False, matching how the journal (`_JOURNAL_SYSTEM_PROMPT`) and lore-merge (`_LORE_MERGE_SYSTEM_PROMPT`) tasks already call the same transport. Worth noting why the suite missed it: every test mocks at the generate_structured_text seam, so they assert that the task is called and that its result is stored, never that the request asks for the right output format. The new test closes that specific gap — it captures the kwargs and asserts both json_mode=False and a prose system prompt, plus that a stored summary never begins with a brace. Prod was checked and is unaffected: 46 lore entries, none with a summary at all, so the manual button had never been used there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>