Observation
Background image requests could be accepted faster than they completed, while cancellation and blocking file work were represented through general failure handling. The result was an unclear runtime boundary: queued work could grow, a cancelled task looked too much like an ordinary error, and local image reads or result writes could occupy the event loop.
Treatment
The plugin now applies a configurable limit to background tasks before creating a new task. When the active count reaches the limit, the request is rejected and a background.rejected audit event records the decision. Cancellation catches asyncio.CancelledError, writes the cancelled state and callback result, then re-raises the cancellation. Local image reads, input parsing, step-image saves, and result saves use a shared asyncio.to_thread() helper for blocking file operations.
Verification
Focused tests fill the available background slots and confirm that the next request is rejected before task creation. Cancellation tests check both the stored state and callback payload. File-operation tests replace the thread helper and confirm that local reads and workflow saves pass through it. These checks cover the configured background-task boundary rather than claiming one global limit for every executor.