Repository navigation
Show Preferences save failures and preserve explicit theme retry #158
Description
Owner: estate-e1438c9d058f/source_worker; root owns independent expectations/source acceptance, and machine_worker owns the separately gated Windows Qt receiving course.
Operator problem
On current main bcf185fb6502f016869a6fb1507c76b06cab317d (actual tree 10d524f14e6010838dab08b432b272421d6f6f17), PreferencesDialog._save() performs seven sequential settings writes and optional theme application without handling ordinary exceptions. A rejected write can escape the Qt slot with no visible Preferences explanation. This is presently a source-derived finding; no original dialog course or candidate has run.
The current SettingsStore.set also changes cached data before writing. After a failed first or later write, a retry that compares the entered theme only against that changed cache can omit the callback even when the visible theme has not changed. The backend repair #125 remains separately owned and is not adopted by this work.
Narrow behavior
Keep the seven setting calls, order and conversions unchanged. Catch a save-stage exception with a literal-text warning, retain all controls and the open dialog, and allow an explicit OK retry or Cancel. Say saving did not finish and some changes may already be saved; do not claim rollback or atomic publication.
Capture the theme-comparison baseline at the first save attempt's existing store-read point, preserving healthy first-click behavior if settings changed after opening. Retain that baseline across errors. A later successful retry applies the changed theme even if the failed setter already changed cache; reverting the control to the retained baseline avoids an unnecessary callback when no callback previously failed.
If all seven writes complete but the optional theme callback raises, show a distinct literal message that preferences were saved but theme application did not finish. Retain a pending-application indication so a user-requested retry invokes the callback despite potentially partial visual effects. Clear pending state only after successful completion and then accept. No automatic retry, store rollback, settings repair or callback-side-effect rollback is added. Cancel closes without undoing already saved changes.
The complete pre-candidate contract is 8,330 bytes, SHA-256 db003c4371c25641ae132491b00cfff3e24490819e763fd0096d1172874b48d2; its original source admission binds 24 exact bodies. Root freezes independent expectations before implementation exposure.
Four-path fence
desktop/capture_desktop/screen_settings.py: save/error/retry handling and necessary imports/local state only.- New
tests/ui/test_preferences_save_errors.py. - New
docs/operator/PREFERENCES_SAVE_ERRORS.md. - Append-only
docs/design/research/PROGRESS.md, preserving its complete current 91,590-byte body and later owner additions.
Preserve SettingsStore #125, registry #126, DesktopPersistence, app/theme implementations, existing tests, schemas, daemon and hardware. The unresolved 99cea3e384ec preset-export ownership remains held; preset library/save/load/export are outside this claim. The separate no-edit confirmation finding is recorded in #118 comment6193997965. No current public Preferences/screen_settings claimant was found; all 15 current open PR changed-file lists were received, including both #94 pages. The source/new test/new guide do not overlap them. Shared PROGRESS contributions remain append-only.
Receiving and publication
Use isolated fictional SettingsStore paths supplied before dialog construction, actual Qt controls, and controlled publication/theme failures. Never construct DesktopPersistence against live app state. Preserve separate cache, disk-prefix and callback observations for first/later failures, explicit retry/revert, healthy controls, literal error text and Cancel. Current read-only metadata identifies the documented user-owned Windows Python3.12.2 with PySide6 packages6.6.3.1; this is not an application run or installed repair.
Current AGENTS, licensing, contribution and autonomous-execution instructions apply. New Python code carries GPL-3.0-only. Focused maintained tests and a small original/candidate native course require exact source/receiver review; no broad unchanged suite is proposed.
Fresh main and all 15 PR heads remain unchanged. All three complete workflow bodies have no issue/comment trigger. The existing Actions/#133 hold stays in force: no PR, main/tag change, workflow edit/dispatch or installed adoption. A separately guarded non-main/non-tag source branch and clearly qualified direct-file delivery may publish the reviewed result without silently promoting it to main. This issue reserves source scope only; candidate and product execution remain absent.
Activity
Jacob-Met commentedon Oct 15, 2026
The Preferences repair is published on the isolated source branch at
954d45e489377ae788ad03f63b8fdf3ddb104875.
The operator guide
explains the retained-form retry behavior. Main and installed CaptureSuite are
unchanged; this issue remains open for adoption under the existing Actions hold.
When a settings write fails, the dialog now explains that saving did not finish
and earlier changes may already be saved. It retains the entered controls for an
explicit OK retry or Cancel. The seven existing writes and their order
remain exact. Retaining the comparison theme from the first save attempt prevents
the backend's changed cache from suppressing a later successful theme retry.
A separate warning handles theme-application failure after all seven writes
complete. It says preferences were saved while applying the theme did not finish.
The callback may already have changed the palette; an explicit retry handles that
pending application. Cancel closes without undoing cache, disk or appearance
effects. This guarantees retry in the retained form, not recovery after reopening
or restarting, and does not add a transaction or backend rollback.
Actual receiving
One Windows course used the documented Python 3.12.2 route with PySide6 6.6.3.1,
explicit fictional settings paths and a persistence adapter that never opened
default application settings or registry. Its five direct children all finished
with status 0: the original two-attempt observation, four focused tests, nine
candidate scenarios with 15 observations, scoped Ruff, and the selected-closure
license check. The independent saved-state comparison accepted 703 checks;
complementary raw/process/custody review accepted 253. Four original Qt widget
renders were separately inspected and accepted.
The original outer receiver and collector both failed during their final output
inventory because pytest created directory links. Those failures remain intact;
there is no invented successful final receipt. A separately reviewed data-only
collector recovered all 51 regular files and recorded the five links without
following them or rerunning product. Both observer logs retain an installed
NumPy/PySide compatibility diagnostic, and the original log retains its expected
induced write-error traceback. No dependency repair or generally clean runtime
is claimed.
Source boundary and evidence
All four complete remote bodies were independently received. The maintained
full-tree check confirms 1,344 leaves with all 1,340 unrelated leaves preserved,
sole parent
bcf185fb6502f016869a6fb1507c76b06cab317d, unchanged main and zeroActions runs for this source head. No pull request, main/tag update, workflow or
settings change was made. The PROGRESS append remains the exact historical
source checkpoint; the actual disposition is recorded here and in the companion.
SettingsStore #125, registry #126 and the unresolved preset-export ownership
remain separate. No app/theme implementation, daemon, hardware, schema or
existing test changed. The source closure supports the focused test; it is not a
complete installed application checkout. The images are
QWidget.grabrenders,not full-desktop or physical-input qualification.
Source and receiving companion is delivered and freshly received. Start with
OPEN_FIRST.mdfor the operator guide and the four original widget renders. The 745,250-byte archive has SHA-2568b41ad6c0b58877e93790e9c41475b680ff0bd43d0379478b030c1f79d129570; the independent fresh-archive review accepted 431 checks. The packet preserves the exact selected source, complete actual observations, raw streams, original failures, recovery and publication proofs.