Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 86 additions & 82 deletions docs/USER_GUIDE.md

Large diffs are not rendered by default.

200 changes: 62 additions & 138 deletions docs/design/SCOPED_SETTINGS_IMPLEMENTATION.md
Original file line number Diff line number Diff line change
@@ -1,145 +1,69 @@
# Flat settings pages and three-level inheritance
# Scoped settings: schema, drafts and Preferences

Requested 27 September 2026. This supersedes the nested navigation introduced by
the canonical Settings consolidation. The user approved up to 500 net additional production lines for this change.
Implementation and Linux verification are recorded in [VERIFICATION.md](../VERIFICATION.md).
The October 1 refinement supersedes the September 27 combined application dialog.
See [verification and accounting](../reviews/2026-10-01-settings-refactor.md).

## Invariant

For an inheritable setting, the effective value is the explicit slide override,
otherwise the explicit talk override, otherwise the application default. The same
resolved values must drive presentation, voice summaries, preview, narration,
speech synthesis and audio validity. Missing overrides are different from zero,
empty text, false and an explicitly selected model default.
Project resolves slide override → talk setting → application default → built-in.
Resolution, schema v5, SETTING_DEFAULTS, language versions and audio fingerprints
are unchanged. MainWindow owns the live project. A scoped dialog owns a draft,
never the live project. Preferences owns computer controls, not talk defaults.

Three fixed-scope Settings dialogs share flat navigation with up to five pages:
## Ownership

1. Voice & language: voice identity/source, language, writing style and delivery.
2. Talk & preparation: audience/conference and timing policies; a read-only talk mode row.
3. Presentation & recording: playback behaviour, recording, output and added audio.
4. AI & speech engine: Codex selection, Qwen options and GPU lifecycle.
5. Application: account, device preferences and general application settings.

Pages combine related settings. Application defaults, talk and slide each have a
fixed-scope window; there is no scope selector. Navigation exposes only applicable
pages. Device and engine lifetime retain application scope. Existing shortcuts
select the concrete page and focus target; native style and palette are retained.

## Settings ownership

| Scope chain | Settings | Editor location |
| Scope | Settings | Editor location |
| --- | --- | --- |
| Application → talk → slide | Voice, writing style, delivery attributes/directions | Corresponding scope's Voice & language dialog |
| Application → talk → slide | Narration language | Application default / main Language combo / slide Language of this slide; talk dialog readout + reset only |
| Application → talk → slide | After-slide action, pause | Application and talk Playback sections; slide inspector After this slide / Timing |
| Application → talk | Mode; recording intent | Application default dialog; main toolbar combo / main checkbox; talk dialog readouts + reset only |
| Application → talk | Language arrangement, Codex model/reasoning, synthesis sampling, Quick/Realtime policies, tolerance, recording source/microphone/policy, encoding, background gain/loop | Corresponding scope's task page |
| Application only | Account, GPU lifetime, device preferences, libraries | Application dialog and focused menu entrances |
| Talk only | Duration | Main Duration spin only |
| Talk only | Title, conference/sources, audience/objective, background track, output destination, gradual delivery | Talk dialog; background track controls share Background audio |
| Talk only | Language versions | Main Language combo |
| Slide only | Narration, notes, inclusion, budget, additional clips | Editor, inspector Timing/inclusion, slide Additional audio dialog |


The selected language version belongs to talk scope; it is not a fourth tier.
Slide overrides belong to that version's slide. Explicit passage language markers
remain content instructions and must satisfy the talk's language-arrangement rule.
Changing language does not translate existing text automatically.

Voice identity is an atomic selection, including its reference recordings. Vocal
attributes inherit individually. Supported controls depend on the effective voice;
the Qwen variant follows that voice rather than an independently conflicting choice.

## Concrete implementation boundaries

1. **Project/settings state — `project.py`, application preferences.** Introduce
one allowlisted settings resolver and explicit override storage. Application
defaults are stored in application config; talk/slide overrides in the talk
JSON. Workers receive a resolved snapshot instead of reading live preferences.
Replace direct effective-setting calculations at consumers rather than keeping
a parallel policy. Migrate existing talk values to explicit overrides, preserving
saved behaviour and existing audio when effective synthesis inputs are unchanged.

2. **Bindings and dialog — `ui.py`, `options.py`, `app.py`.** Replace the tree and
thirteen pages with five combined pages. Reuse the field editors with explicit
scope-aware bindings, inherited-value captions and removal of overrides. Keep
ordinary controls direct; technical parameters remain under Advanced. Preserve
pending edits while changing pages. Each fixed-scope dialog has its own
Save/Cancel transaction. Immediate account,
engine, system-audio and explicit library operations stay clearly identified.
Do not temporarily adopt a fake talk to edit application defaults.

3. **Voice identity — `project.py`, `voices.py`, voice actions in `app.py`.** Preserve
recorded/imported/designed/predefined origin independently of the synthesis
backend and user-assigned name. Accepting a design keeps its origin after its
audio becomes a Base reference. Saved-library selection is not another voice
type. Older ambiguous references are labelled Reference voice without guessing.
Use the resolved identity in both talk and selected-slide summaries. Reuse the
existing reference-copy/hash mechanism for portable talk assets.

4. **Generation and engine ownership — `services.py`, `runtime.py`.** Resolve
language, writing and speech settings per slide. Preserve whole-talk context
during narration generation. Replace the one-configuration-per-batch assumption
with compatible batches through the existing single speech owner, including
Realtime and explicit preload. Avoid holding the existing session guard across
a transition that needs to acquire it again. Speaker changes within a compatible
model should not trigger needless model reloads. Model-type changes may require
loading and must report that work. Do not change the existing text splitting.

5. **Modes, cache and saved projects.** Prepared, Quick and Realtime share effective
settings; remove Quick's hidden Ryan/Professional substitutions. Quick keeps
its simplified start workflow. Audio fingerprints use effective synthesis inputs,
not override provenance, so switching from inherited to explicit identical values
preserves valid audio. Only affected slides become outdated. Keep existing words
and saved files until explicit replacement succeeds. Playback and exports use the
accepted artifacts, not newly resolved settings midway through an operation.

## Defaults and persistence semantics

Inheritance is live: changing an application default affects talks/slides that still
inherit that field. Show the affected scope when saving application defaults; do
not silently regenerate text or audio. An active job retains its starting snapshot.

Provide an explicit Keep these settings for this talk action to turn inherited
values into talk overrides and include required voice assets. This makes a talk
independent of another computer's defaults without another inheritance tier.
Account credentials and machine-specific choices are never copied into a talk.

## Verification

- Resolver precedence, removal of overrides, explicit empty/zero/false values and
supported/unsupported vocal controls; effective-value equality preserves cache.
- Application config versus talk JSON persistence; migration and reopen with changed
application defaults; pinning settings and copying the talk to another directory.
- Predefined, own and designed voices retain their displayed origin through preview,
acceptance, library save/load and project reopen; library audition does not select.
- Three flat fixed-scope dialogs, five possible pages, focused shortcuts, scoped Save/Cancel,
application defaults without a talk and correct selected-slide/version binding.
- Whole-talk and per-slide text/audio generation, mixed-language validation and
Prepared/Quick/Realtime use the same resolved settings; no text approval is added.
- Engine reuse and compatible/incompatible voice transitions, cancellation and
progress; pre-existing valid audio avoids loading a model unnecessarily.
- Linux native Qt/Breeze Xvfb, minimum/default window sizes and 150% scaling; full
regression suite, packaged launcher and library audit. Only Linux is tested.

## Accounting and approval

The prior approved limit was 160 net additional production lines from baseline
117fb8b. Before this pass, the tree used 101, leaving 59. Flattening navigation can reduce UI
code, but the existing model has no persisted application speech/language defaults
or general slide overrides, and generation is bound to talk-level speech config.
Moving widgets cannot supply those missing semantics.

Estimated additional production growth, after removing superseded paths:

| Area | Net lines |
| --- | ---: |
| Settings resolution, serialization and migration | 110–150 |
| Scope-aware editors and transaction changes, offset by navigation consolidation | 130–180 |
| Voice origin, summaries and library/reference persistence | 30–50 |
| Generation, mode and single-engine transition changes | 80–120 |
| **Total** | **350–500** |

Approved allowance: at most **500 net additional production lines from the current
tree** (601 total from 117fb8b). Tests and documentation are counted separately.
This is an estimate and ceiling, not a target. Final measured accounting is recorded with the verification results.
| Application → talk → slide | Voice identity and references | Voice & language in each fixed-scope dialog |
| Application → talk → slide | Language | Talk defaults; main Language combo; Slide sound → Voice & language |
| Application → talk → slide | Writing style, delivery instructions/attributes | Writing & delivery in each fixed-scope dialog |
| Application → talk → slide | After-slide action and pause | Defaults/talk Timing & playback; slide inspector only |
| Application → talk | Mode | Talk defaults Timing & playback; main Mode combo |
| Application → talk | Recording intent | Talk defaults Audio & recording; main checkbox |
| Application → talk | Language arrangement | Defaults/talk Voice & language |
| Application → talk | Quick/Realtime/timing policies | Defaults/talk Timing & playback |
| Application → talk | Codex model/effort; synthesis sampling | Defaults/talk AI model |
| Application → talk | Recording/output settings; background gain/loop | Defaults/talk Audio & recording |
| Talk | Duration | Main Duration spin only |
| Talk | Title/audience/objective/conference/sources; pin inherited settings | Talk settings → Talk |
| Talk | Background file and recording destination | Talk settings → Audio & recording |
| Slide | Inclusion/budget | Slide flow inspector |
| Slide | Audio clips, gain and placement | Slide sound → Audio & recording |
| Computer | Display, system sound, account, engine and lifecycle policy | Preferences, immediate; Close only |
| Shared library | Reusable voices and delivery presets | Relevant component's explicit library actions, immediate |

Talk mode, language and recording rows are read-only with Reset. Every inheritable
row has a constant source caption (set here/from talk/from app/built-in) and Reset;
explicit zero, false, empty, and equal-to-parent values remain overrides.

## Implementation

`settings_schema.py` is the presentation metadata authority for keys, kinds,
choices, scope, page, section and order. Values/scopes originate in Project's
SETTING_DEFAULTS and SETTING_CHOICES. The explicitly listed custom owners handle
voice, sampling, delivery presets and assets. `SettingField` builds and loads the
same editor/source/Reset row in dialogs and the inspector. Widgets are placed once.

`ScopedSettingsDialog` has thin TalkDefaults/Talk/Slide configurations. It composes
VoiceEditor, AudioAssets, CodexModelPicker, ConferencePanel and DeliveryPresets.
The narrow controller API is documented in module docstrings and checked by AST.
PreferencesDialog owns device, account and engine widgets. MainWindow owns actions,
the speech session and persistence; no compatibility widget aliases remain.

Opening copies the project (or defaults) and records its generation. Edits use
`apply_edit`, shared by draft editing and Save replay, and append immutable operations.
Save checks the generation, replays once through Project mutators inside the
existing configuration change boundary, updates audio/UI once, compares stale
slides, and writes once. Defaults write QSettings; talk/slide write the manifest.
Cancel writes nothing, preserves pre-existing main-window modifications, cancels
owned operations and deletes only session-created unreferenced media.

Conference/import workers receive the draft and never save. Late cancelled results
cannot edit a reopened draft. Save is unavailable during project-returning jobs;
Cancel remains available. Shared-library actions do not save the project.
Preferences account/model jobs do not save pending document settings.

Draft edits never call MainWindow.edit_setting, configuration_changed or refresh.
MainWindow no longer reloads drafts after live edits. Local timing is measured on
the draft when its page is shown/edited. Engine status and account availability are
read-only external state; they do not replace draft model selections.
38 changes: 38 additions & 0 deletions docs/design/UX_PLACEMENT_PROPOSAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,44 @@ interaction contract. The [original inventory](UI_INVENTORY.md) is the historica
baseline. Existing visual styling is retained. The implementation was authorized
with a ceiling of 160 net additional production lines.

## Current settings and access contract — October 1

The [scoped settings contract](SCOPED_SETTINGS_IMPLEMENTATION.md) supersedes the
historical settings layout below. The main controls and single-owner rules remain.
Preferences is this computer (immediate, Close). Talk defaults, Talk settings and
Slide sound edit independent drafts (Save/Cancel). No scope selector exists.

| Controls | Current entrance / location | Priority / navigation depth |
| --- | --- | --- |
| Mode, duration, language, record, Start, text/audio/play, slide navigation | Main window | P1 / 0 |
| Predefined voice and sample | Main voice button → Voice & language | P1 / 1 |
| Personal/designed/saved voice | Main voice button → source tab | P2 / 2 |
| Audience, objective, conference | Talk settings → Talk | P2 / 1 |
| Delivery style and presets | Voice button → Writing & delivery | P2 / 2 |
| Vocal attributes | Writing & delivery → More vocal attributes | P3 / 3 |
| Slide include/after | Slide flow inspector | P3 / 0 |
| Slide budget/pause, inheritance reset | Slide flow → Timing | P3 / 1 |
| Slide voice/language | Slide sound… → Voice & language | P3 / 1 |
| Slide directions/attributes | Slide sound… → Writing & delivery [→ More vocal attributes] | P3 / 2–3 |
| Slide clips | Additional audio… → Audio & recording | P3 / 1 |
| Recording source, microphone, destination, background | Presentation settings → Audio & recording | P2 / 1 plus scroll if needed |
| Pause, tolerance, Quick/Realtime policies | Talk settings → Timing & playback | P2–P3 / 2 |
| Fit duration | Talk → Fit duration…; or talk Timing → Save and fit… | P2 / 1–2 |
| Display/system sound | Settings → Preferences… → Display & sound (Ctrl+,) | P2 / 2; shortcut opens directly |
| Account | Settings → Account… | P3 / 2 |
| Speech engine | Status-bar engine button → Preferences/Speech engine | P3–P4 / 1 |
| Inheritable application defaults | Settings → Talk defaults… → relevant page | P3 / 2–3 |
| Codex model/effort and speech sampling | Talk settings → AI model | P4 / 2 plus scroll if needed |

Count navigation separately from entering values, executing actions and Save.
Pages use the same order at each scope, omitting empty pages. P1 main controls
remain directly visible at 940×680. Fixed-scope titles, source captions and Reset
identify ownership; Cancel does not save or undo unrelated changes. See the
[October 1 evidence](../reviews/2026-10-01-settings-refactor.md) for sizes, screenshots,
keyboard/pointer tests, test counts and measured edit/Save latency.

## Historical placement records

## Current settings contract

The subsequent [flat scoped-settings contract](SCOPED_SETTINGS_IMPLEMENTATION.md)
Expand Down
38 changes: 38 additions & 0 deletions docs/design/UX_PLACEMENT_VERIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,44 @@ Implemented 27 September 2026 against the accepted
[inventory](UI_INVENTORY.md) remains the pre-refactor coverage baseline; the
[user guide](../USER_GUIDE.md) describes the current interaction routes.

## Current settings and access contract — October 1

The [scoped settings contract](SCOPED_SETTINGS_IMPLEMENTATION.md) supersedes the
historical settings layout below. The main controls and single-owner rules remain.
Preferences is this computer (immediate, Close). Talk defaults, Talk settings and
Slide sound edit independent drafts (Save/Cancel). No scope selector exists.

| Controls | Current entrance / location | Priority / navigation depth |
| --- | --- | --- |
| Mode, duration, language, record, Start, text/audio/play, slide navigation | Main window | P1 / 0 |
| Predefined voice and sample | Main voice button → Voice & language | P1 / 1 |
| Personal/designed/saved voice | Main voice button → source tab | P2 / 2 |
| Audience, objective, conference | Talk settings → Talk | P2 / 1 |
| Delivery style and presets | Voice button → Writing & delivery | P2 / 2 |
| Vocal attributes | Writing & delivery → More vocal attributes | P3 / 3 |
| Slide include/after | Slide flow inspector | P3 / 0 |
| Slide budget/pause, inheritance reset | Slide flow → Timing | P3 / 1 |
| Slide voice/language | Slide sound… → Voice & language | P3 / 1 |
| Slide directions/attributes | Slide sound… → Writing & delivery [→ More vocal attributes] | P3 / 2–3 |
| Slide clips | Additional audio… → Audio & recording | P3 / 1 |
| Recording source, microphone, destination, background | Presentation settings → Audio & recording | P2 / 1 plus scroll if needed |
| Pause, tolerance, Quick/Realtime policies | Talk settings → Timing & playback | P2–P3 / 2 |
| Fit duration | Talk → Fit duration…; or talk Timing → Save and fit… | P2 / 1–2 |
| Display/system sound | Settings → Preferences… → Display & sound (Ctrl+,) | P2 / 2; shortcut opens directly |
| Account | Settings → Account… | P3 / 2 |
| Speech engine | Status-bar engine button → Preferences/Speech engine | P3–P4 / 1 |
| Inheritable application defaults | Settings → Talk defaults… → relevant page | P3 / 2–3 |
| Codex model/effort and speech sampling | Talk settings → AI model | P4 / 2 plus scroll if needed |

Count navigation separately from entering values, executing actions and Save.
Pages use the same order at each scope, omitting empty pages. P1 main controls
remain directly visible at 940×680. Fixed-scope titles, source captions and Reset
identify ownership; Cancel does not save or undo unrelated changes. See the
[October 1 evidence](../reviews/2026-10-01-settings-refactor.md) for sizes, screenshots,
keyboard/pointer tests, test counts and measured edit/Save latency.

## Historical placement records

## Subsequent settings refinement

The settings-specific locations below describe the preceding canonical-dialog
Expand Down
Loading
Loading