ADR-006: Task Persistence
Status: PROPOSED.
Context
CURRENT: hxEASM has durable scans and scan_jobs, but scan_jobs do not track Worker identity, lease ownership, attempts, idempotency keys, or result-batch acceptance.
Source references:
ScanJobmodel:backend/internal/scans/model.goscan_jobstable:backend/migrations/001_initial_schema.sql- job creation:
backend/internal/scans/repository.go
Decision
Use a hybrid model:
- keep
scan_jobsas the user-visible plugin job; - add
worker_tasksas the execution and lease envelope; - link scanner tasks to
scan_jobswithscan_job_id; - reserve
worker_tasks.task_typefor future non-scanner tasks such as AI.
Alternatives
Extend scan_jobs
Pros:
- fewer tables;
- simple for scanner-only tasks.
Cons:
- mixes user-visible job state with distributed lease state;
- difficult to model attempts and batch idempotency;
- poor fit for future AI tasks;
- risks large invasive changes to existing scan APIs.
Create only worker_tasks
Pros:
- clean distributed execution model.
Cons:
- duplicates existing scan job concept;
- risks breaking existing UI/API expectations around
scan_jobs.
Hybrid
Pros:
- preserves current scan/job API behavior;
- isolates distributed execution concerns;
- supports future task types.
Cons:
- requires careful synchronization between task state and scan job state.
Consequences
scan_jobsremains authoritative for UI-visible plugin status.worker_tasksis authoritative for acquisition, leasing, attempts, and delivery.- Gateway must update both consistently.
Unresolved
- Whether the first implementation stores task payload inline as JSONB or by reference to a payload table.
- Exact state mapping from
worker_tasks.statetoscan_jobs.status.