Quantum Nebula Depletion Service¶
Status: 📐 Design-only — Fully unbuilt and honestly marked 📐 Design-only: no quantum_depletion_service, no Sector.depletion_state/depletion_replenish_at schema, no nebula_replenished event … (impl audit 2026-06-16)
📐 Design-only. No service code is committed yet; this page is the prescriptive runtime spec. Canonical decision in ADR-0053 WR6. Player-facing nebula-depletion mechanics live in ../FEATURES/galaxy/quantum-resources.md.
The runtime that walks Sector rows where quantum nebulae have been harvested, tracks their replenishment timers, and transitions them back toward HEALTHY state. Depletion timers per-color are spec'd in quantum-resources.md (Crimson 14 days; all other colors 5 days). This service implements the timer.
Cadence and scan target¶
Cadence: every 60 seconds (UTC).
Scan target: Sector rows where:
SELECT * FROM sectors
WHERE depletion_state IS NOT NULL
AND depletion_state != 'HEALTHY'
AND depletion_replenish_at <= NOW()
FOR UPDATE SKIP LOCKED;
The SKIP LOCKED clause makes multiple service instances safe — concurrent scans don't block each other or double-process rows.
Action¶
For each scanned row, transition the depletion state one step healthier:
| Current state | Next state | Action |
|---|---|---|
DEPLETED |
RECOVERING |
Set depletion_replenish_at = now() + per_color_timer |
RECOVERING |
HEALTHY |
Clear depletion_replenish_at; emit nebula_replenished realtime event |
HEALTHY |
(no-op) | This state shouldn't be in the scan; if encountered, log warning |
The per-color timer (when transitioning from DEPLETED → RECOVERING) is:
| Nebula color | Timer |
|---|---|
| Crimson | 14 days |
| Azure | 5 days |
| Emerald | 5 days |
| Violet | 5 days |
| Amber | 5 days |
| Obsidian | 5 days |
A nebula sector cycles HEALTHY → DEPLETED (on harvest) → RECOVERING (after timer 1) → HEALTHY (after timer 2). Total round-trip: 28 days for Crimson, 10 days for the others.
Realtime emission¶
When a sector transitions to HEALTHY, the service emits:
{
"event_type": "nebula_replenished",
"sector_id": "uuid",
"region_id": "uuid",
"nebula_color": "crimson",
"replenished_at": "iso8601"
}
Subscribers: any player in the sector, any player with the sector marked in their ARIA exploration map, and the region's owner (for governance dashboard awareness).
Idempotency¶
- Running the service twice in quick succession with no eligible rows is a no-op.
- Running with overlapping scans (multiple instances) uses
SKIP LOCKEDto avoid double-processing. - A row whose timer hasn't elapsed yet is filtered out at the SQL level — never picked up.
Failure modes¶
| Mode | Detection | Handling |
|---|---|---|
| Service down for > 1 minute | Heartbeat absent | On restart, the next tick processes any backlog. Replenishment timers extend by however long the service was down. Acceptable — the granularity is days; minutes of skew per outage is invisible. |
| DB connection failure mid-scan | Transaction rollback | Row stays in pre-transition state; next tick retries. |
| Sector deleted mid-tick (region terminated, etc.) | Row no longer exists at update time | Skipped silently. The terminating region's cleanup orchestrator handles cascade-deletion of the sector and its replenishment state goes with it. |
depletion_replenish_at somehow null on a non-HEALTHY row |
Defensive check | Log warning, treat row as if depletion_replenish_at = now() − 1 so the next tick can transition it. |
Source map¶
| Concern | Path (target) |
|---|---|
| Service entry point | services/gameserver/src/services/quantum_depletion_service.py:run_tick |
| Cron / scheduler | services/gameserver/src/scheduling/cron_jobs.py:quantum_depletion_tick (60-sec cadence) |
| Realtime event emission | Existing realtime_bus.emit for nebula_replenished |
| Sector model fields | Sector.depletion_state, Sector.depletion_replenish_at (per DATA_MODELS/galaxy.md) |
Related¶
../ADR/0053-batch6-runtime-services.md— canonical decision (WR6).../FEATURES/galaxy/quantum-resources.md— player-facing nebula depletion + per-color timer specs.../DATA_MODELS/galaxy.md—Sectorschema with depletion fields../realtime-bus.md— realtime event delivery.