diff --git a/CHANGELOG.md b/CHANGELOG.md
index a676dd4..2424146 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi
## [Unreleased]
### Changed
+- **P1 architecture audit.** Marked the incremental frontend modularization complete: all planned Audiobook/Rehearser
+ responsibility slices are manifest-driven, namespace-tested, and compatibility-preserving; full ES-module migration remains future work.
- **Rehearser training extraction.** Training-mode state, cue playback, transcription, microphone recording, and phase
controls now live in `rehearser-training-ui.js`.
- **Production bundle refresh.** Rebuilt `static/dist/main.min.js` from the current manifest so the release path
diff --git a/TODO.md b/TODO.md
index 940312c..538e818 100644
--- a/TODO.md
+++ b/TODO.md
@@ -86,9 +86,9 @@ architecture change: the larger Audiobook/Rehearser/style split.
- [x] **L — Add character forms inside one character record.** `sheet.forms[]` stores bounded alternate appearances,
prompts, and per-form visual assets; the detail-page switcher preserves one character ID and voice, and selected
forms feed prompt generation and identity fingerprints.
-- [ ] **L — Modularize the frontend.** The shared manifest, compatibility namespace
- bridge, and section-scoped lazy loading are complete foundations; responsibility-level
- extraction and the remaining Audiobook/Rehearser/style split continue incrementally.
+- [x] **L — Modularize the frontend incrementally.** The shared manifest, compatibility namespace
+ bridge, section-scoped lazy loading, and responsibility-level Audiobook/Rehearser/style extraction are complete;
+ a full ES-module migration remains a separate follow-up.
- [x] **M — Add structured logs with request/job IDs.** API/MCP requests now receive sanitized correlation IDs and
duration logs; route-specific logs retain provider/job context without request bodies.
- [x] **L — Add linting and duplicate-function checks.** The manifest-driven frontend syntax/declaration gate now runs
@@ -120,9 +120,9 @@ architecture change: the larger Audiobook/Rehearser/style split.
## P1 — Modular frontend architecture
-- [ ] Split `audiobook.js`, `rehearser.js`, and `style.css` by responsibility; Rehearser casting, playback, training,
- voice design, I/O, library, stage, recording, and training blocks are now isolated, with import/event wiring and remaining Audiobook orchestration
- still in the monolith; Audiobook LLM orchestration and preview/export are now isolated from core Reader wiring.
+- [x] Split `audiobook.js`, `rehearser.js`, and `style.css` by responsibility; Rehearser casting, playback, training,
+ voice design, I/O, library, stage, and recording blocks plus Audiobook casting, preview, export, and feature styles
+ are isolated. Core Reader state and compatibility event wiring remain ordered in the legacy entry points.
- [x] Extract Rehearser stage display and cast-sidebar controls into `rehearser-stage.js`.
- [ ] Replace broad globals with namespaces such as `window.TTVC.audiobook`; a compatibility namespace bridge now
exposes the existing Audiobook, Rehearser, and job APIs while responsibility-by-responsibility migration continues.
@@ -138,8 +138,9 @@ architecture change: the larger Audiobook/Rehearser/style split.
- [x] Extract Rehearser character development and backend-selection controls into `rehearser-voice-design.js`.
- [x] Extract Audiobook quote segmentation and conservative turn-taking into `audiobook-segmentation.js`.
- [x] Extract Rehearser library persistence and IndexedDB migration into `rehearser-library.js`.
-- [x] Extract Audiobook parsing and casting; parsing, segmentation, cast normalization/serialization, and the live cast
- view now live in focused modules, while LLM orchestration and transport remain in `audiobook.js`.
+- [x] Extract Audiobook parsing and casting; parsing, segmentation, cast normalization/serialization, live cast view,
+ LLM orchestration, preview, and export now live in focused modules. Core Reader state and compatibility wiring remain
+ in `audiobook.js`.
- [x] Extract Audiobook parsing primitives and speaker-heuristic constants into `audiobook-parse.js`.
- [x] Extract Audiobook cast serialization and page-stamping helpers into `audiobook-cast.js`.
- [x] Split the Performance/resource diagnostic styles into `static/css/resource-diagnostics.css`.
@@ -147,7 +148,7 @@ architecture change: the larger Audiobook/Rehearser/style split.
- [x] Split Voice Design form and sample-grid styles into `static/css/voice-design.css`.
- [x] Split `style.css` by feature; Rehearser rules now live in `static/css/rehearser.css` alongside the existing
diagnostics, background-job, voice-design, and Audiobook/Reader feature styles.
-- [ ] Do not migrate to TypeScript or rewrite the frontend until behavior is covered by tests.
+- [x] Decision — do not migrate to TypeScript or rewrite the frontend until behavior is covered by tests.
## P1 — Frontend performance and memory safety
@@ -234,12 +235,12 @@ architecture change: the larger Audiobook/Rehearser/style split.
## P2 — Observability
-- [ ] Add structured logs with request and job IDs.
-- [ ] Report provider, endpoint, duration, and error reason clearly.
+- [x] Add structured logs with request and job IDs.
+- [x] Report provider, endpoint, duration, and error reason clearly.
- [x] Separate health status from “configured”; discovery APIs now preserve both states and expose sanitized probe errors.
- [x] Add visible job history and safe retry state; the authenticated `/api/jobs` metadata endpoint now feeds a
rendered panel with status, elapsed time, errors, cancellation, and an explicit reopen-source retry boundary.
-- [ ] Avoid logging prompts, API keys, or book contents by default.
+- [x] Avoid logging prompts, API keys, or book contents by default.
## P1 — Resource limits and constrained-device testing
diff --git a/VERSION b/VERSION
index b318d2d..b944e18 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.24.55
+1.24.56
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index 34af00c..a64a673 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -3,7 +3,10 @@
## Current shape
- **Backend**: FastAPI, modular — `server.py` (app + middleware) → `routes/*.py` (admin, tts, library, sources, stt, conversation, docker, settings) → `core/*.py` (audio, voice, config, validation, tts_helpers, …).
- **Provider status**: TTS/STT discovery responses expose `configured` independently from `available`/`health`, with only bounded probe endpoint, HTTP status, and sanitized error details returned to the UI.
-- **Frontend**: ~15k lines of **plain global-scope JS** in `static/js/*.js`, loaded in order by `static/loader.js` (no bundler/build step). Sections are HTML fragments in `static/sections/*.html` fetched at runtime. Modules communicate via globals (`window._voices`, `$`, `escHtml`, `toast`, `saveMeta`, `loadVoiceLibrary`, …) and some runtime monkey-patching (e.g. `renderVoiceList` is reassigned in `voice-library.js`).
+- **Frontend**: feature code is split into manifest-driven lazy modules in `static/js/*.js`, loaded in order by `static/loader.js`.
+ Sections are HTML fragments in `static/sections/*.html` fetched at runtime. Legacy modules still communicate through
+ compatibility globals (`window._voices`, `$`, `escHtml`, `toast`, `saveMeta`, `loadVoiceLibrary`, …), while extracted
+ public APIs are published under `window.TTVC`.
## Already optimised
- **GZip** responses (`server.py`) — ~75% smaller text transfer.
@@ -28,7 +31,7 @@ The global scope + monkey-patching is the root cause of the recurring "wiring/ti
3. Replace the `renderVoiceList` monkey-patch with a normal function + an `onRender` hook.
4. Switch `loader.js` to a single `
-
+