Sidecars
Scope note (2026-06-16). The
steelmoth_runtime.sidecarspackage is a misnamed shared-infra package, not a dispatch subsystem. The Moth Dispatch Team / Kratos execution engine that originally gave this package its name has been removed from Steelmoth — dashboard surface (PR #354), runtime engine (#363), compose service (#367). It was never used in production: the Kratos executor never ran (0 rows ever insteelmoth.sidecar_runs). What remains undersidecars/is the live infrastructure described below. SeeCHANGELOG.mdand ADRs/RFCs 0036/0046/0038/0028/0029/0037 (all superseded).
What the package is now
Section titled “What the package is now”steelmoth_runtime.sidecars is a hexagonal package (domain / application /
adapters / infrastructure) that today holds live shared infrastructure that
is not dispatch-specific despite the directory name:
- Notification outbox.
steelmoth.notification_outboxis the live notification queue.postgres_notification_outbox.pyis its repository; thesteelmoth-notifiercontainer runsnotification_worker.run_foreverto drain it withPreferenceRoutingNotificationDelivery(routing_notification_delivery.py) for routing. The outbox is fed by live features — reminders and browser-task delivery — not dispatch. (RFC 0028 introduced both a Kratos run-queue half and this outbox half; only the run-queue half was removed.) - Workspace repository.
postgres_workspace_repository.py(port:application/ports/workspace_repository.py) backs the per-owner dashboard Workspace Inbox/Outbox surfaces (ADR 0068 / ADR 0071), implemented byPostgresWorkspaceRepository. - Weather.
weather_open_meteo.pyis the Open-Meteo weather adapter used by the weather tool. - User settings.
postgres_user_settings_profile.py(port:application/ports/user_settings_profile.py, plus an in-memory variant) backs per-owner user-settings storage. - Shared Postgres wiring.
postgres_repositories.pyexposesruntime_database_url()and the shared connection helpers the adapters reuse.
The addon registries under addons/ (registry.json and the
browser_pool_orchestrator / moth_adapters addon trees) are the first source
paths to inspect when addon identity, launch metadata, or addon availability
changes. (The dispatch-team worker registry addons/sidecars.json was removed
with the dispatch subsystem.)
Removed: the Kratos dispatch-team execution engine
Section titled “Removed: the Kratos dispatch-team execution engine”The dispatch-team execution path — the Kratos run-queue, the worker process, the
dispatch policy gate, the /v1/team/sidecars API, the dashboard /team pages,
and the planner dispatch_team tool — has been removed across PRs
#354 / #363 / #367 (2026-06-16). It never ran in production (sidecar_runs had 0
rows ever). Do not describe it as a current capability. A few dispatch-domain
value types (domain/identifiers.py’s WorkerId / SidecarRunId,
domain/execution.py) survive as inert, misnamed leftovers and should not be
read as evidence the executor exists.
Runtime-adjacent compose services (live)
Section titled “Runtime-adjacent compose services (live)”compose.shared.yml defines two long-lived runtime-adjacent services that
inherit the run-agent-vault-proxy-session.py wrapper:
steelmoth-notifier(profilenotifier) processes thesteelmoth.notification_outboxqueue vianotification_worker.run_foreverwithPreferenceRoutingNotificationDeliveryfor routing.steelmoth-reminder-daemon(profilereminder-daemon) tickssteelmoth_runtime.reminder_daemon.main_loopevery 60s (configurable viaMOTH_HYBRID_REMINDER_DAEMON_TICK_S). Each tick scansworld.remindersand enqueues per-channel delivery intents intosteelmoth.notification_outbox(plus syntheticsteelmoth.sidecar_runsprovenance rows; the table survives as the FK parent ofnotification_outbox). One-shot reminders are marked sent when at least one enabled channel enqueue succeeds. PRD 0032 / RFC 0067 / ADR 0087. The service remains profile-gated in compose, but the canonical startup paths (scripts/start-stack.shandscripts/compose-up.sh) include thereminder-daemonprofile so it comes up with the private runtime stack. The loop emits guardrail alerts for stale cycles (reminder_daemon.stale_cycle_alert, default threshold 120s viaMOTH_HYBRID_REMINDER_DAEMON_STALE_ALERT_S) and persistent due-backlog accumulation (reminder_daemon.backlog_alert, thresholds viaMOTH_HYBRID_REMINDER_DAEMON_BACKLOG_ALERT_DUE+MOTH_HYBRID_REMINDER_DAEMON_BACKLOG_ALERT_CYCLES).
Delivery is completed by steelmoth-notifier: notification_worker consumes
pending outbox rows and uses PreferenceRoutingNotificationDelivery. Reminder
fan-out rows preserve explicit channels (email, inbox_only, dashboard,
webhook); preference auto-routing applies only to legacy default rows.
Topology rationale (ADR 0084 carried into ADR 0087): the reminder daemon
runs in its own container — not as an in-process asyncio task in
steelmoth-api — so DB outages or otherwise-misbehaving reminder enqueue
work cannot stall the api container’s Telegram polling loop.
Maintenance Notes
Section titled “Maintenance Notes”- Update this page when the notification-outbox / workspace / weather / user-settings shape under the package changes, or when addon registry metadata changes.
- Do not reintroduce dispatch-team / Kratos prose describing it as live; the executor is removed (PRs #354 / #363 / #367).
- Do not expose raw provider secrets to package adapters; use the credential and broker boundaries documented in domain terms and ADRs.
Known Unknowns
Section titled “Known Unknowns”- This page does not describe every addon implementation.
- The package directory name (
sidecars/) is a historical misnomer; a future rename to reflect its shared-infra role is not yet scheduled.

