* fix(threads): stop and join the prompt cleanup thread, the image worker and the observer (#302, #370)
- PromptTracker: the cleanup thread waits on a stop event instead of
time.sleep; new shutdown(timeout=2) joins it and returns whether it ended.
- ImageGenerationHandler.shutdown(timeout=5) now joins the worker and
returns a bool; new close() is final: schedule() refuses and a sealed
run's history re-check is dropped, so no worker restarts afterwards.
- ImageMonitor.stop_monitoring(timeout=5) closes the handler first, then
stops and joins the watchdog observer within one deadline.
- Every test that builds a real tracker, handler or monitor ends with its
final stop and an assertion, before its folder and databases go.
- #370: the wrapper/session history test drains before dispose(); the
held-write bound test uses 30 s ceilings instead of tight wall clocks.
* test(history): drain the writer before asserting a bounded close it does not test (#370)
* fix(threads): a later stop waits again for a worker or observer an earlier stop left running (#302)
Review findings on #372:
- ImageGenerationHandler keeps the workers a stop signalled that had not
ended; every later shutdown/close joins them again, so a second call no
longer returns True while the first worker still runs.
- ImageMonitor.stop_monitoring keeps an observer or handler it left
running and stops and joins it again on the next call.
- A closed handler takes no awaiting history path, and a re-check that
raced close() is not kept due.
- Tests: second stops of a busy worker and a live observer, the closed
handler's re-check paths, the handle test asserts the worker ended and
stops before it asserts, and a no-new-thread check instead of set
equality.
* test(browser): the System reset restores every settings value, safety_backup included
The frontend coverage shard of #372 failed in workspace-system-tagging:
the review read "No safety backup (the policy is off)". The backups spec
saves safety_backup=false, and /__test__/system/reset restored config.json
but not PromptManagerConfig.SAFETY_BACKUP (nor INFINITE_SCROLL), so a
later spec on the same worker server saw the policy off. The reset now
captures and restores every non-tagging value POST /settings can change.