disables BullMQ/Redis consumers when queue.type === "local"
makes admin health report cache OK on Local without opening Redis
gates Commands/GC/Cron/SystemOverride Redis usage for Local
adds a focused QueueService local-tier regression spec
Provider/quick-start changes from #676 are intentionally excluded for the 0.0.50 onboarding/provider-first epic.
Verification
pnpm build
pnpm --filter @mosaicstack/gateway typecheck
pnpm --filter @mosaicstack/gateway lint
pnpm --filter @mosaicstack/gateway test
pnpm format:check
pre-push hook: full pnpm typecheck, pnpm lint, pnpm format:check
Notes
No self-merge. Source PR requires review-of-record.
## Summary
Fixes the 0.0.49 B1 blocker where Local-tier gateway boot attempts to open Redis/BullMQ/ioredis connections and never becomes healthy.
This is the gateway-only split from #676:
- disables BullMQ/Redis consumers when `queue.type === "local"`
- makes admin health report cache OK on Local without opening Redis
- gates Commands/GC/Cron/SystemOverride Redis usage for Local
- adds a focused QueueService local-tier regression spec
Provider/quick-start changes from #676 are intentionally excluded for the 0.0.50 onboarding/provider-first epic.
## Verification
- `pnpm build`
- `pnpm --filter @mosaicstack/gateway typecheck`
- `pnpm --filter @mosaicstack/gateway lint`
- `pnpm --filter @mosaicstack/gateway test`
- `pnpm format:check`
- pre-push hook: full `pnpm typecheck`, `pnpm lint`, `pnpm format:check`
## Notes
No self-merge. Source PR requires review-of-record.
REVIEW-OF-RECORD — APPROVE (#689, head 8cb9b13cad). I reviewed the gateway-only Local-tier Redis gate and found no blockers.
Local-tier gating: the Redis/BullMQ entry points in scope are gated on queue.type === "local" or the resulting null/disabled service state. Admin health returns cache OK without createQueue() on Local; CommandsModule and GCModule provide null Redis handles instead of opening ioredis; CommandExecutor skips provider-login poll cache writes when Redis is absent; SessionGC cold-start/full/session GC skip Valkey operations on Local; CronService exits before scheduling/registering BullMQ jobs when QueueService is disabled; SystemOverrideService uses an in-memory local fallback instead of creating a Redis queue handle; QueueService disables BullMQ queue/worker/job operations and returns local no-op/error results. The remaining Redis calls are behind non-null handle/enabled guards, so I do not see a Local-tier Redis call escape in the changed consumers.
Non-local behavior: for non-local tiers or absent config in legacy construction paths, the existing Redis/BullMQ paths remain enabled (createQueue(), BullMQ queues/workers, Redis health ping, Redis-backed system overrides), so Standalone/Federated behavior is preserved apart from nullable plumbing and shutdown cleanup.
Split cleanliness: the diff is gateway-only plus a focused QueueService regression spec. No provider-setup, quick-start, wizard, installer, or provider-first/OAuth changes are included.
Reviewer verification on head 8cb9b13c: focused QueueService local-tier spec pass; full gateway test suite pass (524 passed, 16 skipped); gateway typecheck pass; gateway lint pass; repo format:check pass; repo build pass (23/23). PR CI reported green on pipeline 1638. APPROVE.
REVIEW-OF-RECORD — APPROVE (#689, head 8cb9b13cad6c75e3cff9fb765618c31dfd232098). I reviewed the gateway-only Local-tier Redis gate and found no blockers.
Local-tier gating: the Redis/BullMQ entry points in scope are gated on `queue.type === "local"` or the resulting null/disabled service state. Admin health returns cache OK without `createQueue()` on Local; CommandsModule and GCModule provide null Redis handles instead of opening ioredis; CommandExecutor skips provider-login poll cache writes when Redis is absent; SessionGC cold-start/full/session GC skip Valkey operations on Local; CronService exits before scheduling/registering BullMQ jobs when QueueService is disabled; SystemOverrideService uses an in-memory local fallback instead of creating a Redis queue handle; QueueService disables BullMQ queue/worker/job operations and returns local no-op/error results. The remaining Redis calls are behind non-null handle/enabled guards, so I do not see a Local-tier Redis call escape in the changed consumers.
Non-local behavior: for non-local tiers or absent config in legacy construction paths, the existing Redis/BullMQ paths remain enabled (`createQueue()`, BullMQ queues/workers, Redis health ping, Redis-backed system overrides), so Standalone/Federated behavior is preserved apart from nullable plumbing and shutdown cleanup.
Split cleanliness: the diff is gateway-only plus a focused QueueService regression spec. No provider-setup, quick-start, wizard, installer, or provider-first/OAuth changes are included.
Reviewer verification on head 8cb9b13c: focused QueueService local-tier spec pass; full gateway test suite pass (524 passed, 16 skipped); gateway typecheck pass; gateway lint pass; repo format:check pass; repo build pass (23/23). PR CI reported green on pipeline 1638. APPROVE.
Independent review (reviewer ≠ author). Blocker B1 (greenfield wizard: gateway ECONNREFUSED loop / "did not become healthy" on Storage tier=Local).
Scope: gateway-only Redis gating for queue.type === "local". 8 consumers + 1 new spec. Confirmed this does NOT carry #676's provider-setup/quick-start bundle — that UX redesign stays in the 0.0.50 onboarding epic. Clean split as requested.
Correctness: factories return null on local tier; @Optional() @Inject everywhere a Redis handle is consumed; guards (if (this.redis) / ?.) on every use; onApplicationShutdown null-safe; admin-health reports {status:"ok", latencyMs:0} for local (no per-request ioredis connect). Distributed/Redis tiers unchanged (else-branch = createQueue()).
CI: PR-event pipeline 1638 fully green (ci-postgres, typecheck, lint, format, test all success).
Approving for squash-merge to next.
REVIEW-OF-RECORD — APPROVE
Independent review (reviewer ≠ author). Blocker **B1** (greenfield wizard: gateway ECONNREFUSED loop / "did not become healthy" on Storage tier=Local).
**Scope:** gateway-only Redis gating for `queue.type === "local"`. 8 consumers + 1 new spec. Confirmed this does NOT carry #676's provider-setup/quick-start bundle — that UX redesign stays in the 0.0.50 onboarding epic. Clean split as requested.
**Correctness:** factories return `null` on local tier; `@Optional() @Inject` everywhere a Redis handle is consumed; guards (`if (this.redis)` / `?.`) on every use; `onApplicationShutdown` null-safe; admin-health reports `{status:"ok", latencyMs:0}` for local (no per-request ioredis connect). Distributed/Redis tiers unchanged (else-branch = `createQueue()`).
**CI:** PR-event pipeline 1638 fully green (ci-postgres, typecheck, lint, format, test all success).
Approving for squash-merge to `next`.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Fixes the 0.0.49 B1 blocker where Local-tier gateway boot attempts to open Redis/BullMQ/ioredis connections and never becomes healthy.
This is the gateway-only split from #676:
queue.type === "local"Provider/quick-start changes from #676 are intentionally excluded for the 0.0.50 onboarding/provider-first epic.
Verification
pnpm buildpnpm --filter @mosaicstack/gateway typecheckpnpm --filter @mosaicstack/gateway lintpnpm --filter @mosaicstack/gateway testpnpm format:checkpnpm typecheck,pnpm lint,pnpm format:checkNotes
No self-merge. Source PR requires review-of-record.
REVIEW-OF-RECORD — APPROVE (#689, head
8cb9b13cad). I reviewed the gateway-only Local-tier Redis gate and found no blockers.Local-tier gating: the Redis/BullMQ entry points in scope are gated on
queue.type === "local"or the resulting null/disabled service state. Admin health returns cache OK withoutcreateQueue()on Local; CommandsModule and GCModule provide null Redis handles instead of opening ioredis; CommandExecutor skips provider-login poll cache writes when Redis is absent; SessionGC cold-start/full/session GC skip Valkey operations on Local; CronService exits before scheduling/registering BullMQ jobs when QueueService is disabled; SystemOverrideService uses an in-memory local fallback instead of creating a Redis queue handle; QueueService disables BullMQ queue/worker/job operations and returns local no-op/error results. The remaining Redis calls are behind non-null handle/enabled guards, so I do not see a Local-tier Redis call escape in the changed consumers.Non-local behavior: for non-local tiers or absent config in legacy construction paths, the existing Redis/BullMQ paths remain enabled (
createQueue(), BullMQ queues/workers, Redis health ping, Redis-backed system overrides), so Standalone/Federated behavior is preserved apart from nullable plumbing and shutdown cleanup.Split cleanliness: the diff is gateway-only plus a focused QueueService regression spec. No provider-setup, quick-start, wizard, installer, or provider-first/OAuth changes are included.
Reviewer verification on head
8cb9b13c: focused QueueService local-tier spec pass; full gateway test suite pass (524 passed, 16 skipped); gateway typecheck pass; gateway lint pass; repo format:check pass; repo build pass (23/23). PR CI reported green on pipeline 1638. APPROVE.REVIEW-OF-RECORD — APPROVE
Independent review (reviewer ≠ author). Blocker B1 (greenfield wizard: gateway ECONNREFUSED loop / "did not become healthy" on Storage tier=Local).
Scope: gateway-only Redis gating for
queue.type === "local". 8 consumers + 1 new spec. Confirmed this does NOT carry #676's provider-setup/quick-start bundle — that UX redesign stays in the 0.0.50 onboarding epic. Clean split as requested.Correctness: factories return
nullon local tier;@Optional() @Injecteverywhere a Redis handle is consumed; guards (if (this.redis)/?.) on every use;onApplicationShutdownnull-safe; admin-health reports{status:"ok", latencyMs:0}for local (no per-request ioredis connect). Distributed/Redis tiers unchanged (else-branch =createQueue()).CI: PR-event pipeline 1638 fully green (ci-postgres, typecheck, lint, format, test all success).
Approving for squash-merge to
next.