1. editor.py — Fix rewrite_chapter_content to use model_writer (was model_logic).
Chapter rewrites now use the creative writing model, not the cheaper analysis model.
2. editor.py — evaluate_chapter_quality now uses keep_head=True so the evaluator
sees the chapter opening (engagement hook, sensory anchoring) as well as the
ending; long chapters no longer scored on tail only.
3. editor.py — Consistency analysis sampling upgraded to head+middle+tail (was
head+tail), giving the LLM a complete view of each chapter's events.
4. writer.py — max_attempts is now adaptive: climax/resolution chapters
(position >= 0.75) receive 3 refinement attempts; others keep 2.
5. writer.py — Polish-skip threshold tightened from 0.012 to 0.008 (1 filter
word per 125 words vs. 1 per 83 words), so more borderline drafts are cleaned.
6. style_persona.py — Persona validation sample increased from 200 to 400 words
for more reliable voice quality assessment.
Version bumped: 3.0 → 3.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step 1 (Bible-Tracking Merge):
- Added merge_tracking_to_bible() to story/bible_tracker.py — merges character
tracking state and lore back into bible dict after each chapter, making
blueprint_initial.json the single persistent source of truth.
- Integrated in cli/engine.py after each chapter's update_tracking + update_lore_index
calls so the persisted bible is always up-to-date.
Step 2 (Character-Specific Voice Profiles):
- story/writer.py: write_chapter now checks bp['characters'] for a voice_profile on
the POV character before falling back to the prebuilt_persona cache.
- story/style_persona.py: refine_persona() accepts pov_character=None; when a POV
character with a voice_profile is supplied it refines that profile's bio instead of
the global author_details bio.
- cli/engine.py: refine_persona call now passes ch.get('pov_character') so per-chapter
persona refinement targets the correct voice.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
core/utils.py:
- estimate_tokens: improved heuristic 4 chars/token → 3.5 chars/token (more accurate)
- truncate_to_tokens: added keep_head=True mode for head+tail truncation (better
context retention for story summaries that need both opening and recent content)
- load_json: explicit exception handling (json.JSONDecodeError, OSError) with log
instead of silent returns; added utf-8 encoding with error replacement
- log_image_attempt: replaced bare except with (json.JSONDecodeError, OSError);
added utf-8 encoding to output write
- log_usage: replaced bare except with AttributeError for token count extraction
story/bible_tracker.py:
- merge_selected_changes: wrapped all int() key casts (char idx, book num, beat idx)
in try/except with meaningful log warning instead of crashing on malformed keys
- harvest_metadata: replaced bare except:pass with except Exception as e + log message
cli/engine.py:
- Persona validation: added warning when all 3 attempts fail and substandard persona
is accepted — flags elevated voice-drift risk for the run
- Lore index updates: throttled from every chapter to every 3 chapters; lore is
stable after the first few chapters (~10% token saving per book)
- Mid-gen consistency check: now samples first 2 + last 8 chapters instead of passing
full manuscript — caps token cost regardless of book length
story/writer.py:
- Two-pass polish: added local filter-word density check (no API call); skips the
Pro polish if density < 1 per 83 words — saves ~8K tokens on already-clean drafts
- Polish prompt: added prev_context_block for continuity — polished chapter now
maintains seamless flow from the previous chapter's ending
marketing/fonts.py:
- Separated requests.exceptions.Timeout with specific log message vs generic failure
- Added explicit log message when Roboto fallback also fails (returns None)
marketing/blurb.py:
- Added word count trim: blurbs > 220 words trimmed to last sentence within 220 words
- Changed bare except to except Exception as e with log message
- Added utf-8 encoding to file writes; logs final word count
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix: chapter quality evaluation now uses model_logic (free Pro) instead of model_writer (Flash).
The model that wrote the chapter was also scoring it, causing circular, lenient grading.
- Increase max_attempts in write_chapter from 2 to 3 for more refinement passes per chapter.
- Update auto model selection prompt (ai/setup.py) to prioritize quality over budget framing:
free/preview/exp models preferred by capability (Pro > Flash, 2.5 > 2.0 > 1.5), not just cost.
Writer role now allowed to use best free Flash/Pro preview — not restricted to basic Flash only.
- Bump version to 3.0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Each chapter card now has a footer with Prev/Next chapter anchor links
- First chapter shows only Next; last chapter shows 'End of Book'
- Back to Top link on every chapter footer
- Added get_chapter_neighbours() helper in story/bible_tracker.py for
programmatic chapter sequence navigation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- story/planner.py: enrich() and plan_structure() now extract series_metadata
and inject a SERIES_CONTEXT block (Book X of Y in series Z, with position-aware
guidance) into prompts when is_series is true.
- story/writer.py: write_chapter() builds and injects the same SERIES_CONTEXT
into the chapter draft prompt; passes series_context to evaluate_chapter_quality().
- story/editor.py: evaluate_chapter_quality() accepts optional series_context
parameter and injects it into METADATA so arc pacing is evaluated relative to
the book's position in the series.
- ai_blueprint.md: Section 11 marked complete (v2.7), summary updated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- story/style_persona.py: Expanded default ai_isms list with 20+ modern AI phrases
(delved, mined, neon-lit, bustling, a wave of, etched in, etc.) and added
filter_words (wondered, seemed, appeared, watched, observed, sensed)
- story/editor.py: Stricter evaluate_chapter_quality rubric — added
DEEP_POV_ENFORCEMENT block with automatic fail conditions for filter word
density and summary mode; strengthened criterion 5 scoring thresholds
- story/writer.py: Added get_genre_instructions() helper with genre-specific
mandates for Thriller, Romance, Fantasy, Sci-Fi, Horror, Historical, and
General Fiction; added DEEP_POV_MANDATE block banning summary mode and
filter words; expanded AVOID AI-ISMS banned phrase list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implement Section 3 of the AI Context Optimization Blueprint: before each
chapter draft, model_logic expands sparse scene_beats into a structured
Director's Treatment covering staging, sensory anchors, emotional shifts,
and subtext per beat. This treatment is injected into the writer prompt,
giving the model a detailed scene blueprint to dramatize rather than infer,
reducing rewrite attempts and improving first-draft quality scores.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- writer.py: Dynamic character injection — only POV + beat-named characters
are sent to the writer prompt, eliminating token waste and hallucinations
from characters unrelated to the current scene.
- writer.py: Smart tail truncation — prev_content trimmed to last 1,000 tokens
(the actual chapter ending) instead of a blind 2,000-token head slice,
preserving the exact hand-off point for continuity.
- writer.py: Scene state injected into char_visuals — current_location,
time_of_day, and held_items now surfaced per relevant character in prompt.
- bible_tracker.py: update_tracking expanded to record current_location,
time_of_day, and held_items per character after each chapter.
- core/config.py: VERSION bumped 1.4.0 → 1.5.0.
- README.md: Story Generation section and tracking_characters.json schema
updated to document new context optimization features.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>