Good questions. Let me answer each one.
1. Outline vs Beats — what's the difference?
They're different granularity levels from story generation:
-
Outline = high-level chapter plan. Each chapter gets a
title+summary(2-3 sentences). Created once during initial story generation. Example:Ch1: "The Arrival" — Sandy lands in Mumbai and meets her new production team. -
Beats = scene-level breakdown within a chapter. Each beat is a specific story moment with paragraphs mapped to it. Example:
Beat 1: Sandy arrives at the airport,Beat 2: First meeting with the director,Beat 3: Confrontation over creative vision.
During revision, outlines are only revised if the plot itself changes (rare). Beats are always the operating unit for paragraph-level work. In practice, _edit_chapter_outlines fires on maybe 5% of revisions — it's mostly dead weight.
2. Surface notes — when called, can we eliminate the LLM call?
_build_surface_notes() is called at the end of plan_revision_instruction(). For each surface in the plan (title, synopsis, paragraph_content), it makes 1 LLM call to generate a one-sentence UI tooltip like "Revise Ch1 paragraph flow to reflect updated tone."
These notes are shown in the frontend revision summary. But _fallback_surface_note() already generates decent heuristic notes without an LLM call. And plan_beat_actions() already generates per-beat guidance which is far more useful.
Recommendation: drop the LLM path entirely, use only _fallback_surface_note(). Saves 1-2 LLM calls per revision. The beat-level guidance from plan_beat_actions is what actually drives the editor.
3. Evaluator — agreed, make opt-in.
The eval loop adds 1 LLM call minimum, 3 on retries. Making it opt-in saves that cost on every revision.
4. Legacy code to delete:
_phase2_sequential_beat_rewrites()— fully replaced byphase2_execute_actions()_phase1_beat_analysis()— fully replaced byphase1_map_paragraphs()_heuristic_plan()— never called (LLM planner always used)_revise_beats()— dead code (beat revision moved toplan_beat_actions)
5. Why continuity checks are 2-4 LLM calls — and why not batch them.
Here's the key constraint: KEEP beats are processed in sequence, not in parallel, because each one needs to see the LATEST working array.
Consider this scenario:
Beat 1: KEEP → paragraphs [1-5]
Beat 2: EDIT → paragraphs [6-10] (changes character name from "Tom" to "James")
Beat 3: KEEP → paragraphs [11-15] (mentions "Tom" in paragraph 12)
Beat 4: KEEP → paragraphs [16-20] (mentions "Tom" in paragraph 18)
After Beat 2 executes, Beat 3 gets a continuity check with upstream note "Beat 2: renamed Tom to James." The LLM finds paragraph 12 says "Tom" and fixes it to "James." Now Beat 4 also needs a check — and it needs to see the updated working array (where paragraph 12 is already fixed), plus the cumulative continuity notes from both Beat 2 and Beat 3.
You can't batch all KEEP beats in one call because:
- Each KEEP beat's input depends on prior beats' output (the
workingarray mutates) - Continuity notes accumulate — Beat 4 needs notes from both Beat 2 AND Beat 3's check
- A KEEP check might itself change paragraph count (rare, but the offset tracking handles it)
However — there IS an optimization: KEEP beats BEFORE the first changed beat don't need checks (no upstream changes). Currently the code adds a continuity note for every KEEP beat with a description, which triggers an LLM call even if nothing has changed upstream. The first KEEP beat always triggers because it adds its own note, then checks itself against it — which is pointless.
The real fix would be: only trigger continuity checks on KEEP beats that come AFTER a non-KEEP beat. If beats 1-2 are KEEP and beat 3 is EDIT, beats 1-2 should skip entirely, and only beats 4+ get continuity checks. This alone would cut most of the wasted KEEP calls.
Summary of the simplification plan:
- Skip
_llm_plan()— hardcode paragraph_content=true, detect title/synopsis from keywords - Drop surface notes LLM calls — use heuristic fallback only
- Evaluator → opt-in
- Delete 4 legacy functions
- Only trigger KEEP continuity checks AFTER first non-KEEP beat
This takes a typical revision from ~8 LLM calls → ~4-5.
Want me to turn this into a plan doc and implement it?