Introduce a reusable browser-test harness under tests/operator_gui/:
- conftest.py: shared fixtures (operator_server, browser with graceful skip,
operator_page with screenshot-on-failure artifacts)
- pages/: OperatorWorkbench Page Object encapsulating selectors and actions
- refactor test_browser_smoke.py onto the fixtures + POM (drops duplicated
server/browser plumbing)
- test_decision_flow.py: approve/hold/reject E2E against the real server,
covering the reject-requires-memo guard and decision persistence
Pin playwright in requirements-dev.txt (Chromium bundled offline for the
air-gapped target) and ignore the artifacts/ screenshot dir.