Skip to content

_hub_events

_hub_events

Best-effort JSON event emitter for the terok-clearance hub.

Shield CLI calls (up/down) notify the hub so desktop/TUI consumers can reflect the state change — in particular, the hub closes pending block notifications for a container whose shield just dropped. Stays stdlib-only so the reader script resource (which bypasses the package) can mirror the same wire format without importing this module.

Every emit targets the per-container ingester socket under $XDG_RUNTIME_DIR/terok/events/<short_id>.sock, where <short_id> is the 12-char prefix of the container id — the same addressing the NFLOG reader uses, and deliberately distinct from the varlink subscriber socket at terok/clearance/<id>.sock that operator UIs glob. Callers therefore supply container_id (the full podman container UUID) on every call: the destination socket is per-container, so the id is what selects it.

Fails silent when the hub isn't listening: flipping shield state must never be held up by a desktop-side daemon being absent.

HubEventEmitter

One-shot writer of JSON-line events to the hub's unix ingester.

Each emit_* call opens a fresh connection to the per-container socket, sends a single line, and closes. The hub stays up across many CLI invocations while each CLI invocation is short-lived — pooling would save nothing and would complicate the fail-silent semantics.

shield_up(container, container_id, *, dossier=None)

Emit a shield_up event for container (optional dossier).

container_id — full podman container UUID; routes the event to the supervisor's per-container hub socket.

dossier mirrors the orchestrator-supplied identity bundle the per-container reader already attaches to connection_blocked events; passing it through here keeps the clearance UI's rendering of every event for the same container consistent (project/task · name rather than the bare container slug). Empty / omitted dossier omits the key entirely.

Source code in src/terok_shield/_hub_events.py
def shield_up(
    self,
    container: str,
    container_id: str,
    *,
    dossier: dict[str, str] | None = None,
) -> None:
    """Emit a ``shield_up`` event for *container* (optional *dossier*).

    *container_id* — full podman container UUID; routes the event
    to the supervisor's per-container hub socket.

    *dossier* mirrors the orchestrator-supplied identity bundle the
    per-container reader already attaches to ``connection_blocked``
    events; passing it through here keeps the clearance UI's
    rendering of every event for the same container consistent
    (``project/task · name`` rather than the bare container slug).
    Empty / omitted dossier omits the key entirely.
    """
    self._send(container_id, {"type": "shield_up", "container": container}, dossier)

shield_down(container, container_id, *, allow_all=False, dossier=None)

Emit a shield_down (or shield_disengaged) event for container.

container_id — see shield_up.

dossier — see shield_up.

Source code in src/terok_shield/_hub_events.py
def shield_down(
    self,
    container: str,
    container_id: str,
    *,
    allow_all: bool = False,
    dossier: dict[str, str] | None = None,
) -> None:
    """Emit a ``shield_down`` (or ``shield_disengaged``) event for *container*.

    *container_id* — see
    [`shield_up`][terok_shield._hub_events.HubEventEmitter.shield_up].

    *dossier* — see
    [`shield_up`][terok_shield._hub_events.HubEventEmitter.shield_up].
    """
    event_type = "shield_disengaged" if allow_all else "shield_down"
    self._send(container_id, {"type": event_type, "container": container}, dossier)