Skip to content

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:

  • ScanJob model: backend/internal/scans/model.go
  • scan_jobs table: backend/migrations/001_initial_schema.sql
  • job creation: backend/internal/scans/repository.go

Decision

Use a hybrid model:

  • keep scan_jobs as the user-visible plugin job;
  • add worker_tasks as the execution and lease envelope;
  • link scanner tasks to scan_jobs with scan_job_id;
  • reserve worker_tasks.task_type for 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_jobs remains authoritative for UI-visible plugin status.
  • worker_tasks is 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.state to scan_jobs.status.