Work Queue Service Design
Architectural design document for workqueue-service. Covers the
reasoning behind every major design choice so that future changes can be
made safely. For operational usage, see
Work Queue Service.
1. Design Philosophy
Four principles shaped the service’s architecture:
Security boundary. The service sits between untrusted callers (AI agents, CI jobs, automation scripts) and trusted write operations (GitLab pushes, MR creation). All changes are inspectable structured data, not opaque blobs. Path blocklists and action validation run before any GitLab write.
Type-agnostic queue, type-specific behaviour. The processing loop, claiming, heartbeat, and lease management are generic. Type-specific logic (MR creation, CVE remediation) lives in pluggable subpackages that register deciders and executors at import time. Adding a new work item type requires no changes to the generic layer.
Single pending action. Only one action per work item at a time. After each action, the decider re-evaluates with current state. This avoids queuing actions that assume a future state which may not hold.
Phase + dimensions, not a linear state machine. The coarse lifecycle (active/completed/failed/cancelled) is separate from independent readiness signals (CI, approval, Konflux build). Dimensions can regress (force-push resets CI), which a linear state machine cannot express.
2. Architecture
Callers submit work items via REST API. The ProcessingManager drains
pending actions in per-item threads, dispatching to type-specific
executors. Executors create and update GitLab MRs via the Commits API.
flowchart LR
callers["Callers\n(CI, CLI, agents)"] --> API["REST API\n+ Auth"]
API --> DB[("PostgreSQL")]
Processing["ProcessingManager"] --> DB
Processing --> GL["GitLab\nCommits API"]
API -.-> Processing
3. Design Decisions Record
See Work Queue Service Design Decisions for all DDR entries covering data model, auth, processing, event pipeline, and MR lifecycle decisions.
4. Future Work
Event-driven dimension updates
The dimension mechanism is implemented with all MR dimensions following
the uniform needs_* model (DDR-48). MR state events drive phase
transitions (merge -> completed, close -> cancelled). Future
dimensions: Konflux PipelineRun events updating
needs_konflux_build/needs_konflux_release. Each follows the same
EventResult.dimensions pattern.
Non-managed MR tracking
Design how the service handles MRs it did not create (MRs without the
managed-by::workqueue label). Requires subscribing to note events
so the service can discover dashboard notes posted by the Lambda and
adopt them as needs_dashboard dimensions. Prerequisite for retiring
the Lambda.
Status rendering
An executor that edits the dashboard note (using the note_id from
the needs_dashboard dimension detail) with aggregated dimension
status (CI, Konflux).
CVE work item type
Add cve/ subpackage with CveWorkItem, CVE-specific decider
(analyze → label → create advisory MR → check VEX → close), and
CVE-specific executors. No changes to the generic layer.
Content validation and size limits
Add content-level inspection to the pre-commit checks: maximum file size, binary detection, and content pattern matching. Currently only path blocklists and action validation are enforced.
Reconciliation sweep
Note: The reconcile_mr executor (DDR-46) now provides per-item
reconciliation. A full sweep (querying GitLab for all active items in
bulk) remains a future optimization for catching items that fall
through individual reconciliation.
Service rename
The service was renamed from hummingbird-mr-service to
workqueue-service to reflect its generalized purpose. A further rename
to hummingbird-work-queue or similar is deferred until a second work
item type is implemented.