You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
⚠️ Blocked on PR #587 — everything this issue touches lands in that PR and is not on main yet. Automated agents/routines: do not implement this issue while PR #587 is open. Before starting any work, run gh pr view 587 -R schmug/PhishSOC --json state -q .state and proceed only if it prints MERGED; otherwise stop silently (no comment, no branch). Remove the blocked/impl-blocked labels only after #587 merges.
Task
Scale the sidecar poll loop past the stateless-cron fan-out's ceiling by moving per-mailbox polling behind Durable Object alarms (the "SidecarDO" evolution named in the design spec). Today one Worker invocation polls every sidecar mailbox sequentially each minute; at ~dozens of busy mailboxes the tick approaches wall-clock/subrequest budgets (~26 Gmail round-trips per busy mailbox).
Motivation
The spec chose stateless cron fan-out for v1 with this exact seam reserved: pollWorkspaceMailbox(env, ctx, mailboxId, cfg) is a pure per-mailbox step designed to be re-homed without rework.
Pointers
workers/providers/workspace.ts — pollWorkspaceMailbox (the re-homeable step) and pollSidecarMailboxes (becomes an alarm-healer instead of a poller)
workers/durableObject/ — decide: alarm on the existing MailboxDO vs a new SidecarDO class; the design spec (docs/superpowers/specs/2026-07-06-sidecar-workspace-design.md, "Approach" section) discussed the trade-offs — a new DO class keeps provider/network concerns out of the storage DO
wrangler.jsonc — new DO class needs a migration tag + binding (NOTE: Workers Builds deploys prod on merge; a new binding must be provisioned correctly or the deploy step fails — see repo memory)
Cutover must be incremental: cron fan-out remains the default; alarm mode per mailbox or via env flag until proven
All poll-loop invariants preserved (cursor freeze, dedupe, cap-on-processed, backoff, audit/label rules) — the existing workspace-poll.test.ts suite must keep passing against the extracted step
Acceptance criteria
N sidecar mailboxes poll concurrently with per-mailbox isolation (one slow tenant doesn't delay others)
Alarm death is self-healing (cron heals missing alarms within one hourly cycle)
Existing poll-step tests pass unchanged; no regression in the cron-only mode
Out of scope
Provider changes; push transport (#589) — though alarms + push compose, land them separately.
Task
Scale the sidecar poll loop past the stateless-cron fan-out's ceiling by moving per-mailbox polling behind Durable Object alarms (the "SidecarDO" evolution named in the design spec). Today one Worker invocation polls every sidecar mailbox sequentially each minute; at ~dozens of busy mailboxes the tick approaches wall-clock/subrequest budgets (~26 Gmail round-trips per busy mailbox).
Motivation
The spec chose stateless cron fan-out for v1 with this exact seam reserved:
pollWorkspaceMailbox(env, ctx, mailboxId, cfg)is a pure per-mailbox step designed to be re-homed without rework.Pointers
workers/providers/workspace.ts—pollWorkspaceMailbox(the re-homeable step) andpollSidecarMailboxes(becomes an alarm-healer instead of a poller)workers/durableObject/— decide: alarm on the existingMailboxDOvs a newSidecarDOclass; the design spec (docs/superpowers/specs/2026-07-06-sidecar-workspace-design.md, "Approach" section) discussed the trade-offs — a new DO class keeps provider/network concerns out of the storage DOwrangler.jsonc— new DO class needs a migration tag + binding (NOTE: Workers Builds deploys prod on merge; a new binding must be provisioned correctly or the deploy step fails — see repo memory).superpowershistory: the poll-lease issue (fix(sidecar): poll lease — overlapping cron ticks can double-process a mailbox #591) becomes moot inside a DO alarm (alarms serialize per object) — coordinate/close accordinglyConstraints
workspace-poll.test.tssuite must keep passing against the extracted stepAcceptance criteria
Out of scope
Provider changes; push transport (#589) — though alarms + push compose, land them separately.
Cross-references
PR #587 (architecture decision + seam), #31, #591 (lease — superseded inside alarms), #589