Future improvement — Chapter Character Beats (potential v1.9)
Status: backlog. Not committed to ship. Discussed 2026-05-05 after the v1.5–v1.8 planning push. Recommendation at the time: don't ship next — pause, run a v1.8 improve-all-behind on a real season, and confirm whether multi-character flatness is actually the limiting issue before adding another planning layer. If it is, this is the next thing to build. If the limiting issue turns out to be something else (sentence rhythm, dialogue density, emotional pacing), build that instead.
The gap
After v1.8 we have five chapter-level planning layers + nine critics:
| Layer | What it provides |
|---|---|
| Bible (canon) | each character's overall season-level arc + rolling current_state (updated via deltas) |
| Knowledge layer (v1.5) | per-chapter what the reader learns |
| Spine (v1.6) | per-chapter scene shape (opening_image / central_turn / closing_image) |
| Stakes (v1.7) | per-chapter wants / obstacle / cost — for the central character only |
| Framework | act-level structure |
The chapter writer sees each major character's overall arc + rolling current_state via the bible block. What they don't explicitly receive is a per-chapter beat for each major character — "in chapter 4 specifically, here's what shifts for Evelyn, what Marcus does and why, where Pell ends up emotionally."
The failure mode this would address: multi-character chapters where side characters feel flat or static because the writer wasn't told what's pressing on them this chapter and defaults to making them backdrops. AI is bad at multi-character density.
Why it's smaller than the gaps already filled:
- Bible deltas already update each character's
current_stateafter each chapter — so cross-chapter continuity is enforced continuity_auditorchecks against the bible's per-character statesubtext_doctorflags character-state inconsistencystakescovers the chapter's central character
The remaining gap is specifically about the other major characters in scenes where multiple appear.
Proposed shape
Same pattern as v1.5/v1.6/v1.7:
Migration 143
alter table story_episodes
add column if not exists chapter_character_beats jsonb;
alter table story_episodes
add column if not exists chapter_character_beats_generated_at timestamptz;
JSONB shape
[
{
"character_key": "evelyn_harper", // matches bible.characters[].key
"entry_state": "still angry from the meeting; replaying what Marcus said",
"shift": "finds the second key in the drawer and lies about it to Marcus",
"exit_state": "the lie is pressing; she's calculating whether he believed it"
},
{
"character_key": "marcus_vance",
"entry_state": "pretending not to know about the audit; reading her",
"shift": "asks about the drawer too directly; sees her flinch",
"exit_state": "now suspects she found something but won't ask again"
}
]
One entry per major character that appears or is referenced in the chapter. Skip introduced_only characters and walk-ons.
Service: apps/backend/src/services/chapter-character-beats.ts
computeChapterCharacterBeatsForSeason(seasonId)— single GPT-4o-mini pass over bible + chapter plan + knowledge layer + spine + stakes (so beats compose with what's already planned). Returns one entry per (chapter × major character).hasChapterCharacterBeats(seasonId)— for lazy-compute gatingbuildChapterCharacterBeatsBlock(beats)— renders the prompt block
Prompt injection
In season-novel-chapter.ts, inject AFTER stakes:
bible → reader window → scene compass → pressure → CHARACTER BEATS → framework directive
The block frames the beats as marching orders for the non-central characters specifically — the central character is already covered by chapter_stakes. Possibly only inject the beats for characters who aren't the chapter's central one, to avoid redundancy.
Critic update
Extend delivery_auditor (v1.8) or add a sibling multi_character_density critic that checks: "for each character listed in chapter_character_beats, did the prose deliver their entry/shift/exit?" Same pattern as the existing prose-vs-plan audit.
UI
Mirror the v1.5/v1.6/v1.7 admin buttons:
🎭 Regen character beatsbutton inEpisodesAdminModaltoolbarPOST /api/story-seasons/:id/regenerate-chapter-character-beats(super-admin)
Platform version bump
v1.9 — adds chapter_character_beats to the planning chain + (optionally) multi_character_density critic to the default set.
Cost
~$0.005/season for the GPT pass (one call, all chapters). Independent of per-chapter prose generation cost.
Tradeoffs
For:
- Closes a real failure mode (multi-character flatness)
- Natural completion of the planning hierarchy (bible.arc → chapter_character_beats → bible delta)
- Composes with existing critics
Against:
- We're at 5 planning layers already; system prompt is getting heavy
- Diminishing returns set in
- The bible's
current_statealready provides per-character snapshots; this layer is partly redundant - Could over-constrain the writer for characters who organically take a different shape mid-chapter
Decision criterion: After running v1.8 in production for at least one season, if the dominant failure mode in critique findings + reader feedback is "side characters feel flat" or "multi-character scenes lack texture," ship this. If it's something else, ship that.
Pre-work needed
Before implementing:
- Run a v1.8 improve-all-behind on a real season (e.g., the Turing Logs current season)
- Listen + read the result
- Tally findings from delivery_auditor + first_reader + subtext_doctor — what's the dominant pattern?
- If multi-character flatness shows up consistently, proceed with this plan.