# Stage 12: Governed Background Jobs Date: 2026-07-29 ## Result - Registered market refresh, automatic screening, and iFinD event enrichment as versioned jobs with schedules, date policy, dependencies, locks, timeouts, retry limits, and output versions. - Added the `job_runs` migration and persistent run ledger. - Centralized worker and scheduler thread creation in `InProcessJobRunner`. - Added process-level lock keys and persistent idempotency keys. - Persisted successful, failed, and retried attempts with elapsed time and normalized error type. - Exposed recent job runs in administrator system status. - Limited retained completed history while preserving running jobs. - Kept existing feature services and the detailed market `sync_runs` audit unchanged. ## Compatibility The runner remains in-process, matching the current single-container deployment. Jobs call the same application methods as HTTP requests and do not depend on request-local account state. The persistent contract permits a later worker process without changing job identities or business calculations. ## Timeout Boundary Timeouts are declared and elapsed time is recorded. Python threads cannot be terminated safely, so hard cancellation remains cooperative until jobs move to a durable worker process. Locks and idempotency prevent concurrent duplicate execution in the current single-process deployment.