ADR-0065 — Queue v1: Strangler-Fig over Greenfield
Date: 2026-05-09 UTC
Status: Accepted
Deciders: software-architect + operator
Context: docs/architecture/queue/design.md §Greenfield vs Strangler-Fig
Context
Queue is a new dedicated identity/customer/RBAC service (operator decision 2026-05-09 UTC). Two implementation strategies were viable for v1 (due 2026-05-23 UTC):
Option A — Greenfield: New raxx-queue Heroku app + new Postgres DB. Clean separation from day 1. All identity data migrated in a big-bang cutover.
Option B — Strangler-Fig: Queue code lives in queue/ (monorepo, same Heroku dyno as Raptor). Backed by Raptor's existing Postgres DB via queue_ namespaced tables. Queue exposes the full API contract (/api/v1/). Data extraction to a standalone DB is Phase 3 (post-v1). Data extraction to a standalone Heroku app is Phase 4 (post-v1).
Decision
Strangler-Fig (Option B) for v1.
Consequences
Positive: - Ships within the 14-day v1 timeline. Infrastructure provisioning (new Heroku app + DB) alone would consume 5-7 dev-days, leaving insufficient runway. - In-flight PRs #1503, #1505, #1506, #1507, #1508 are directly portable — the code diffs become Queue's internal implementations. No work is lost. - Queue is architecturally real from day 1: it has a defined API surface, service-to-service auth, namespaced tables, and a typed module structure. The "virtual service" period is brief. - Phase 3 and Phase 4 are fully planned and can execute post-v1 without disrupting customers.
Negative:
- Queue and Raptor share a DB during Phase 1-2. A Raptor DB outage also takes Queue down (same as today's situation).
- Queue is not independently deployable in v1. A Raptor dyno restart restarts Queue.
- The queue_ table prefix creates temporary visual noise that disappears in Phase 3.
Alternatives Considered
Greenfield: Rejected due to timeline risk. With 14 days to v1 launch and 5-7 dev-days needed for new infrastructure, the margin for setbacks is zero. The operator's explicit instruction is that v1 must ship by 2026-05-23 UTC.
Embedded-in-Raptor (no Queue module): Rejected because it leaves no path to extraction and defeats the purpose of the architectural decision. Queue must be a recognizable module boundary even if it shares a dyno today.