Adds a full per-chapter evaluation logging system that captures every
score, critique, and quality decision made during writing, then renders
a self-contained HTML report shareable with critics or prompt engineers.
New file — story/eval_logger.py:
- append_eval_entry(folder, entry): writes per-chapter eval data to
eval_log.json in the book folder (called from write_chapter() at
every return point).
- generate_html_report(folder, bp): reads eval_log.json and produces a
self-contained HTML file (no external deps) with:
• Summary cards (avg score, auto-accepted, rewrites, below-threshold)
• Score timeline bar chart (one bar per chapter, colour-coded)
• Score distribution histogram
• Chapter breakdown table with expand-on-click critique details
(attempt number, score, decision badge, full critique text)
• Critique pattern frequency table (keyword mining across all critiques)
• Auto-generated prompt tuning observations (systemic issues, POV
character weak spots, pacing type analysis, climax vs. early
chapter comparison)
story/writer.py:
- Imports time and eval_logger.
- Initialises _eval_entry dict (chapter metadata + polish flags + thresholds)
after all threshold variables are set.
- Records each evaluation attempt's score, critique (truncated to 700 chars),
and decision (auto_accepted / full_rewrite / refinement / accepted /
below_threshold / eval_error / refinement_failed) before every return.
web/routes/run.py:
- Imports story_eval_logger.
- New route GET /project/<run_id>/eval_report/<book_folder>: loads
eval_log.json, calls generate_html_report(), returns the HTML as a
downloadable attachment named eval_report_<title>.html.
Returns a user-friendly "not yet available" page if no log exists.
templates/run_details.html:
- Adds "Eval Report" (btn-outline-info) button next to "Check Consistency"
in each book's artifact section.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Added tags VARCHAR(300) column to Run model
- Added startup ALTER TABLE migration in app.py
- New POST /run/<id>/set_tags route saves comma-separated tags
- Tag badges + collapsible edit form in run_details.html header area
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New POST /run/<id>/delete route removes run from DB and deletes run directory
- Only allows deletion of non-active runs (blocks running/queued)
- Delete Run button shown in run_details.html header for non-active runs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New GET /run/<id>/download_bible route serves project bible.json as attachment
- Download Bible button added to run_details.html header toolbar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Backend (web/routes/run.py): Extended /run/<id>/status JSON response with
server_timestamp, db_log_count, and latest_log_timestamp so clients can
detect whether the DB is being written to independently of the log text.
- Frontend (templates/run_details.html):
• Added Live Status Panel above the System Log card, showing:
- Polling state badge (Initializing / Requesting / Waiting Ns / Error / Idle)
- Last Successful Update timestamp (HH:MM:SS, updated every successful poll)
- DB diagnostics (log count + latest log timestamp from server response)
- Last Error message displayed inline when a poll fails
- Force Refresh button to immediately trigger a new poll
• Refactored JS polling loop: countdown timer with clearCountdown/
startWaitCountdown helpers, forceRefresh() clears pending timers before
re-polling, explicit pollTimer/countdownInterval tracking.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- web/tasks.py: db_log_callback bare `except: break` replaced with
explicit `except Exception as _e: print(...)` so insertion failures
are visible in Docker logs. Also fixed datetime.utcnow() → .isoformat()
for clean string storage in SQLite.
Same fix applied to db_progress_callback.
- web/routes/run.py (run_status): added db.session.expire_all() to
force fresh reads; raw sqlite3 bypass query when ORM returns no rows;
file fallback wrapped in try/except with stdout error reporting;
secondary check for web_console.log inside the run directory;
utf-8 encoding on all file opens.
- ai_blueprint.md: bumped to v2.11, documented root causes and fixes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>