The table of contents is a level, and I built one wrong
This is the finding that embarrassed me most, and it is a writing problem rather than a code one.
A table of contents is UI. A chapter title is a signpost, and a signpost’s job is to tell you what is worth walking toward without telling you what you will find when you get there. Ten of mine, across four stories, were doing the second thing. You would open the chapter already knowing where it landed, because the title had said so, and then read several thousand words of something that could no longer surprise you. I retitled all ten.
Anyone who has built levels will recognise it. A door with a sign that names the room is fine. A door with a sign that names what happens to the person who walks through it is a spoiler with a UI treatment. I would never ship a level select screen that told you how the boss fight ends, or a loading tip that gave away the encounter. I shipped the prose equivalent and did not see it.
A choice after the fact
The choices had the same problem wearing a different coat, and this one is closer to a mechanic than to copy. The page would describe her doing the thing, in prose, committed. Then the choice would ask whether she does it. So you would read that she had already crossed the room, and then be asked to decide whether she crosses the room.
In a level, that is asking a player to choose a route into a space the camera has already panned through. The decision has to sit where the outcome is still open, before the prose commits to one version of it, or it stops being a choice and becomes a quiz about the paragraph you just read. I have written about the broader idea as the level design of an interactive novel. This is the uglier version: the theory holds right up until your own signpost is lying to the player standing in front of it.
What the checks cannot see
None of this showed up in anything automated, and I have a lot of checks. They can tell me a route is unreachable. They can tell me a pronoun is ambiguous. They have no opinion on whether a title gives away the chapter it sits on top of, because that is not a property of a string. It is a relationship between two pieces of text, and nothing in my pipeline was ever asked to read them together.
What catches it is a person reading the whole thing cold, in the order a reader would meet it, table of contents first and chapter after, and noticing whether the second thing still has anywhere to go once the first has spoken. I can write a tool that checks whether a flag reaches the reader. I do not know how to write one that checks whether a sentence already told her the ending, because that needs the whole shape of the story held at once.
The fix itself was cheap. Nothing about the structure underneath changed, only the surface that announces it, which is the kind of bug that costs an afternoon to fix and months to notice.