0.2.0
Captures are no longer lost in forked workers. Threads do not survive fork(), so a child inherited a dead sender and a queue nothing would drain: under gunicorn --preload, uWSGI or Celery, where install() runs in a master and workers are forked, every capture in every worker was enqueued and silently discarded. The client now re-arms itself in the child.
install() is idempotent. It returns the client already installed in this process instead of building another one. Previously each call added a sender thread, a rules-cache poller, an atexit hook and a 60-second backend poll.
Key paths are reported from every array element, not just the first. This changes the fingerprint of any request or response containing arrays whose elements differ in shape: those endpoints reappear in the review queue as novel and need approving once more. Approvals for every other endpoint are unaffected.
A prepared request sent with Session.send() is now captured. Only Session.request was patched, so a caller that built its own PreparedRequest was silently invisible: no error, no fingerprint.
install() accepts flush_timeout, and stubsmith.is_installed() is a supported way to assert that capture is armed.
Process exit no longer waits on an unreachable ingest host. The at-exit budget is now one second rather than five.
Documented: what gets patched, both egress hosts, both thread names, argument versus environment precedence, and an annotated capture payload. The README previously said masking was applied server-side, which is the opposite of what the SDK does.
Published to PyPI as stubsmith 0.2.0.
Release created retroactively; the version was published from this commit by a manual workflow dispatch on 2026-08-31.