Skip to content

Commands

mchristegh edited this page Jul 14, 2026 · 2 revisions

Everything you can ask a recorder to do, in one place.

How commands are addressed

Recorder How commands arrive
Inline recorder Only via a control node targeting it. Its input carries traffic, and a traffic wire must never be ambiguous about what's a command.
Tap Via a control node (canonical), or directly on the tap's own input as a convenience — that input has no other purpose.

Commands are a string in msg.payload, case-insensitive, whitespace-tolerant: dump, PAUSE , and Resume all work. Command messages are consumed, never recorded as traffic.

The vocabulary

Command Companion property Does Returns / emits
dump msg.context (optional) — attached as incident context Emits the recording as a manual incident. Does not clear the tape. An empty recording is a legal zero-record incident. Incident on the recorder's incidents output (and copied to events).
clear Empties the recording and resets the wrap/truncation/dropped counters. Sequence numbers are preserved — monotonic forever. cleared event with the count.
pause Stops the tape. Arriving messages are counted (droppedWhilePaused), never silently lost. Traffic keeps flowing on inline passthrough. Idempotent. paused event; a redundant pause gets a commandIgnored ack.
resume Restarts the tape. Idempotent. resumed event.
mark msg.annotation (object or string) Lays an annotation onto the tape in sequence position — "about to test X". Works even while paused (it's metadata about the recording, not traffic) and counts toward capacity. Reports render marks as full-width rules. marked event with the seq.
query Emits a status snapshot: state, capacity, counters, config echo — plus, on taps, active mutes with suppressed counts and scope counters. Snapshot on the recorder's query output.
mute msg.target{"node":"<id>"}, {"type":"mqtt in"}, or {"flow":"<tab id>"} Tap only. Silences one channel while the tape rolls: suppressed messages counted, a mark laid on the tape, and the source's errors still auto-dump. Ephemeral — resets on deploy/restart. muted event; muteIgnored if the target is verifiably outside scope; sent to an inline recorder → commandIgnored.
unmute msg.target Reverses a mute; lays a mark carrying the suppressed count. unmuted event with suppressedCount.

Triggers and the cooldown

Incidents carry a trigger: manual (dump command), error (tap auto-dump), or watermark (a configured condition matched a passing message).

The cooldown (per-recorder config) rate-limits automatic triggers only — an error loop or a flapping watermark can't flood your outputs. Two rules worth internalizing:

  • Manual dumps always fire. A human asking for the tape gets the tape; the cooldown exists to stop machines, not people. Manual dumps also don't reset the cooldown clock.
  • Suppression is visible. Every auto-dump the cooldown swallows emits an incidentSuppressed event with the trigger and time remaining.

Receipts

Commands issued through a control node each produce an ack on its output — { ok, command, targetId, result, reason } with inReplyTo correlation — so a command sender can confirm the action without polling. Commands sent directly to a tap's input rely on the resulting events (cleared, paused, marked, …) on the events output, which serve the same nothing-invisible purpose.

Clone this wiki locally