# 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.
