For implementation and refactor work, call the pass complete only when the approved in-scope work is fully reflected in the attached artifacts.

Before you say the pass is complete:
- finish the approved in-scope code changes
- remove dead local bodies made obsolete by those in-scope changes, unless the task explicitly defers that cleanup
- remove imports made unused directly by those in-scope changes, unless the task explicitly defers that cleanup
- keep unrelated code unchanged
- run the required smoke checks
- prefer Python standard-library `unittest` for promoted KBOS tests
- do not introduce `pytest` or other new test dependencies unless the assigned message explicitly authorizes the dependency change
- scratchpad-only exploratory tests may use other tools if available, but any test intended for promotion must be runnable with standard project test commands
- when adding or changing promoted Python tests, provide proof using `python -m unittest ...` unless the thread contract explicitly specifies another test runner
- include at least one smoke check through the real caller shape or equivalent live call pattern when signatures, helper boundaries, or dependency-injection boundaries changed
- for tiny display-only changes that do not start or modify a long-running runner, server, watcher, monitor, subprocess, HTTP endpoint, or status-file writer, prefer direct helper/unit smoke over live subprocess smoke.
- for tiny display-only UI changes, require one narrow render smoke against the actual UI path and one lightweight DOM/assertion check.
- skip repeated server/API/status-file checks unless the change touches data flow, status writes, HTTP endpoints, runtime config, or render-boundary logic.
- use live smoke only when the changed behavior depends on a live process boundary.
- for any live smoke that starts a long-running runner, server, watcher, or monitor subprocess, own that subprocess and clean it up before reporting smoke complete
- use smoke-only config where practical, including a non-default port, `open_browser_on_start=false`, and smoke-only output/log paths under the actor scratchpad
- wrap live-smoke assertions in cleanup logic so the subprocess is terminated even when assertions fail
- if graceful termination fails, kill the subprocess and verify it is gone before reporting smoke complete
- do not report live smoke as complete while a smoke-started runner, server, watcher, or monitor process is still running
- report the exact smoke commands and exact results

If any approved in-scope item remains open, say exactly what remains open and do not call the pass complete.
