Skip to main content

Module router

Module router 

Source
Expand description

Notification Router — the side-effecting shell around policy.rs (SPEC_OS_NOTIFICATIONS_SYSTEM_2026_09_24.md §3, §5).

Owns: settings resolution, agent-name lookup + sanitization, body redaction (§9), publishing on the mps broker, a 500 ms tick task for debounce release, and the single pending “activate on next window” slot for a click that arrived while no window was open.

One Router per broker (i.e. per AppState), kept in a small registry keyed by the broker’s identity rather than as an AppState field: it is created lazily by the first WS connection and outlives any one connection. Keying by broker (not a single global) means a second AppState in the same process — tests, or any future multi-state setup — never has its events published onto someone else’s bus.

Structs§

AckOutcome
What a click asks of the launcher (the notify.ack response).
BlockRevealEvent
Where block.reveal reveals a block — also the block:reveal payload.
ClickTarget
Where a toast click lands (rich-content spec §3.3 A). Resolved by srv from its own store for the notification the click acked — never taken from the toast’s launch argument (§3.4).
LedgerEnd
What the router needs from an ended turn’s ledger (agentturn).
NotificationActivateEvent
notification:activate: the user clicked a notification; this window shows its block.
NotificationRetractEvent
notification:retract: take a shown notification down.
PendingActivation
A click that arrived while its pane’s workspace was open in no window.
PublishedLedger 🔒
The fields of a published ledger the router reads, typed by the same enums srv serializes it with.
Router

Enums§

Internal 🔒
srv-internal sources, fed from places that must not block (the broker’s publish path, the jekt delivery path) and drained by the router’s task.
TurnTransition
What the Router does with a controllerstatus turn transition.

Constants§

AGENT_NAME_MAX 🔒
BODY_MAX 🔒
CLOUD_SIGNED_OUT_BODY
The body of the CloudSignedOut notification.
EVENT_BLOCK_REVEAL
block.reveal: the named window’s renderer reveals the block itself (SPEC_REVEAL_BLOCK_ONE_PATH_2026_09_27.md §4.3). Payload: BlockRevealEvent.
EVENT_NOTIFICATION
EVENT_NOTIFICATION_ACTIVATE
EVENT_NOTIFICATION_RETRACT
EVENT_NOTIFICATION_STATE
Tray snapshot (TrayState), published on change with persist=1 so a presenter that (re)subscribes gets the current state immediately.
PENDING_ACTIVATION_MAX_AGE_MS
A click’s target is picked up by a newly opened window only this long after the click (rich-content spec §3.3 D) — never “jumps to an old block much later”.
STOP_GRACE_MS 🔒
How long after a user Stop the turn-ended transition it causes is treated as “the user’s own action”, not “finished”.
SUMMARY_MAX 🔒
Rich-content spec §1.2: the summary line’s cap, before the ….
TURN_MAP_MAX 🔒
Cap on tracked blocks’ turn state (see Internal::TurnStatus handling).

Statics§

ROUTERS 🔒

Functions§

attach_sources 🔒
Both hooks run on hot, lock-holding paths (the broker’s publish; jekt delivery). They only parse and enqueue — never call back into the broker or touch the store inline.
failure_body
AgentFailure.code → the fixed body for its toast; None = don’t notify. Only agent_deleted (a user action) is skipped. killed is NOT a user Stop — those go through the controllers’ kill arm and are never classified (host_spawn.rs) — it means a signal/137, most often the OOM killer: exactly the “stopped while you were away” case (ReAgent P1 on #3654). Detail/stderr never reach a toast.
get
The router for this broker, if a connection has created it yet.
init
Get-or-create the router for this broker. Idempotent.
is_bidi_control 🔒
key 🔒
may_take_pending
Pure: may a window showing workspace_id (None = an older frontend that doesn’t say) take pending at now_ms?
notify_turn_end
Whether a finished turn is notified: never AgentMux’s own hidden turn; a turn something else started only when the user asked for those too.
now_ms
Milliseconds since the Unix epoch, as i64.
parse_ledger_end
The turn is over by its ledger: end: "completed" (an exit is a crash, which agentfailure reports). None for a turn still running or settling.
parse_turn_status
(blockid, turn_active) from a serialized BlockControllerRuntimeStatus. turn_active is skip_serializing_if = "is_false", so a turn that ENDED arrives with the field absent — absent means false (Codex P1 on #3705; treating it as “unknown” dropped every end-of-turn and “finished” never fired).
pick_open_window 🔒
Of window_ids (a workspace’s windows), the one a connected frontend reports open. Two open windows on one workspace: prefer the one the user was last in.
quiet_hours_until
notify:quiethours = "HH:MM-HH:MM" in local time. If now is inside the window, return when it ends (epoch ms); None outside it or on a malformed/empty value. A window whose end is before its start spans midnight (“22:00-08:00”). Equal start and end means “off”.
redact_body
§9.2 body policy: first line, sanitized, truncated, and replaced wholesale when it trips the same credential/destructive keyword list the jekt tier gate uses.
registry 🔒
resolve_click_target
Walk block → tab → workspace → windows. None when the block or its tab is gone. BLOCKING (store reads).
sanitize_name
Strip control + bidi-override characters and cap length — the only user-influenced text that reaches a title (§9.1).
sanitize_summary
Rich-content spec §1.2: the agent’s session summary as a single line — controls and bidi stripped, whitespace collapsed, capped at 90 characters. A summary that trips the jekt keyword list is dropped, not replaced: it is decoration, not something the user needs to be told is hidden.
setting_bool 🔒
setting_str 🔒
settings_from_extra
Resolve the policy’s settings view from settings.json (§8).
spawn_internal 🔒
spawn_ticker 🔒
turn_transition
Pure: prev = last known turn_active for the block (None = never seen, e.g. right after srv start — a replayed/first status is not a transition).
with_question_count
Rich-content spec §2.1: “ (+N more)“ after the (already truncated) first question, so the count survives truncation. No body, no suffix — the title “has a question” stands on its own.

Type Aliases§

Registry 🔒