Skip to content

fix: restore capture runtime contract#39

Closed
abrichr wants to merge 1 commit into
mainfrom
agent/fix-capture-recorder-runtime
Closed

fix: restore capture runtime contract#39
abrichr wants to merge 1 commit into
mainfrom
agent/fix-capture-recorder-runtime

Conversation

@abrichr

@abrichr abrichr commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

  • declare Matplotlib as a default runtime dependency while keeping plotting imports lazy and headless-safe
  • make recorder startup termination-aware, detect workers that exit before readiness, and bound pre-ready teardown
  • wake wait_for_ready() when startup stops or raises instead of making callers wait for the full timeout
  • replace the GPL oa-atomacos macOS accessibility wrapper with direct MIT-licensed PyObjC/ApplicationServices APIs
  • add source, runtime, macOS accessibility, and built wheel/sdist contract tests

Root cause

openadapt_capture.Recorder imported the performance plotting module eagerly, but Matplotlib was declared only for development. A normal runtime installation therefore caught the missing dependency in the package-level headless fallback and silently exposed Recorder = None.

Separately, the readiness loop did not observe terminate_processing, so a worker that never set its ready event could leave Desktop teardown waiting forever. The macOS default dependency also pulled GPL-licensed oa-atomacos into the frozen installer even though the needed AX operations are available directly through permissively licensed PyObjC.

User impact

A normal installation now exposes the recorder, failed or cancelled startup tears down promptly, and native macOS window/accessibility observation no longer depends on oa-atomacos.

This PR is necessary but not sufficient for the next frozen Desktop release: the follow-up native-input PR must remove the remaining LGPL pynput runtime dependency before Capture or Desktop is published.

Validation

  • ruff check openadapt_capture scripts/verify_distribution.py tests
  • pytest -q tests --ignore=tests/test_browser_bridge.py --timeout=120 — 197 passed, 7 skipped
  • focused runtime/startup/macOS/window tests — 73 passed, 1 skipped
  • built wheel and sdist both pass scripts/verify_distribution.py
  • fresh Python 3.12 wheel install:
    • Recorder is available
    • Matplotlib is installed
    • oa_atomacos is absent
    • package metadata contains the direct PyObjC/ApplicationServices dependency

The local browser-bridge suite was not used as a verdict because this sandbox forbids binding its loopback test ports; that suite remains intentionally excluded by the repository's CI workflow.

@abrichr

abrichr commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

Superseded by #40, which preserves this dependency-boundary change and adds the reviewed native observer/runtime and release-artifact gates on one exact green head. Closing this duplicate without merge so only the consolidated fix lands.

@abrichr abrichr closed this Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant