75292ed474
A concurrent-session denial resolves after the CDP handshake, so the browser exits with a live connection already established. The launch-failure path never sees it and the user gets a bare TargetClosedError on their first call (#477). The binary records the license exit code (76-79) to a per-launch file whose path the wrapper passes via CLOAKBROWSER_LICENSE_STATUS_FILE. The wrapper reads it when a guarded call throws and re-raises the correct CloakBrowserLicenseError. Discrimination is on the file, not the error type, so a genuine crash is never mislabelled. Fail-safe (no key or unwritable dir -> feature off) and backward-compatible (old binaries never write the file). Guarded surfaces: new_page/new_context, a persistent context's already-open pages (goto + the wait family), and Puppeteer user-created contexts. Orphaned denial files are swept at mint time; an observed code is cached in-process so a concurrent second call can't miss it; the .NET reader parses as tolerantly as Python/JS. Implemented across Python, JavaScript (Playwright + Puppeteer), and .NET, with unit tests. Reproduced end-to-end with a real over-cap denial.