# Recorded signal decoding `decode_signal_recording` answers what a selected protocol decoder observes in an existing recording. It uses caller-supplied **sigrok-cli 0.7.2** with libsigrokdecode on **Linux**. util-linux `prlimit` is required (default `/usr/bin/prlimit`, overridable with absolute `REA_SIGROK_PRLIMIT_COMMAND`). The limiter sets soft and hard address-space limits before the decoder starts. macOS and Windows are refused because this adapter cannot enforce that limit on those hosts. It does not acquire samples or communicate with hardware. ```sh export REA_SIGROK_COMMAND=/absolute/path/to/sigrok-cli rea decode-signal-recording /artifacts/uart.vcd \ --decoders uart:rx=RX:baudrate=9600 --input_format vcd \ --annotations uart=rx-data --format json ``` The corresponding MCP request is: ```json { "name": "decode_signal_recording", "arguments": { "path": "/artifacts/uart.vcd", "decoders": "uart:rx=RX:baudrate=9600", "input_format": "vcd", "annotations": "uart=rx-data" } } ``` `decoders` uses sigrok's decoder stack and option/channel syntax. Channel names must match the recording; REA does not guess wiring, baud rate or protocol. Omitting `input_format` requests sigrok's autodetection. Omitting `annotations` retains every annotation class. Both omitted selections are recorded as null. See the [upstream manual](https://sigrok.org/wiki/Sigrok-cli) for formats, decoder stacking and annotation selectors. No arbitrary command flags are accepted. Output defaults to 50 literal LF-separated lines. Use `line_offset` and `line_limit` for later pages, or MCP `line_limit: null` / CLI `--all_lines` for all remaining output. `output_window` reports `total_lines`, `returned_lines` and `has_more`; these count display lines, **not annotations or samples**. Line endings, blank lines and text within the selected window stay unchanged. REA does not parse display text into protocol facts, as explained by [upstream's annotation output guidance](https://sigrok.org/wiki/Protocol_decoder_output). Paging does not shorten decoding and producer output must still fit its limit. Use annotation-class selection to reduce producer output. Calls independently check the source digest; do not combine pages from different digests. Each selector is limited to 8,192 UTF-16 code units, and total encoded selector arguments (UTF-8, option prefixes, terminators and 64-bit argv pointers) to 32 KiB before launching. This reserves headroom below Linux execve's minimum argument/environment budget; a large inherited environment may still exhaust it. The returned Evidence includes the input path/digest, exact selections, tool configured and resolved paths/digests, full version banner (including library versions), annotation text with sample-number ranges, and stderr. For example, `1104-1938 uart-1: 52` is producer display text over a sample range, not a timestamp or an independently verified protocol fact. Text is retained verbatim; it is not parsed as a lossless binary payload. Empty output does not establish absence of traffic. Warnings remain visible even when sigrok exits zero, including `tool.version_diagnostics` from the separate version probe. Post-run identity failures name the tool, limiter or private copy involved, rather than blaming the admitted source. Resource-signal failures retain the signal and effective limits without inferring its exact cause. REA decodes a private, read-only copy of the recording, verifies that copy and the selected executable and resource limiter after decoding, and removes the workspace after owned process cleanup. Failed descriptor, process or workspace cleanup retains ownership for retry, and the one-shot CLI awaits a retry without replacing the original failure or completed Evidence. Completed observations remain in the MCP session after cancellation or cleanup failure; bounded post-run integrity checks finish before honoring a late abort. The source file is never passed to sigrok. Caller-supplied tools and their libraries/decoder modules are trusted, and hashes identify bytes rather than publisher authenticity. The input copy is bounded at 32 MiB before reading, each command has a 30-second deadline, and combined stdout/stderr is bounded at 4 MiB during collection. Oversized output fails rather than becoming truncated success. These limits do not form an OS sandbox. Before execution, `prlimit` enforces **1 GiB address space per process**, **64 MiB per file**, **30 CPU seconds** and no core dumps. Stricter inherited soft/hard limits are preserved; Evidence records the effective ceilings. Both limits are set before execution, so decoder allocations and compressed recording expansion cannot exceed the per-process address-space cap. These are not aggregate process-memory or filesystem quotas. The selected limiter is trusted and its path, digest and arguments are retained in Evidence. ## Verification ```sh npm run build:cached REA_SIGROK_COMMAND=/absolute/path/to/sigrok-cli node scripts/verify-signal-recording.mjs ``` The verifier synthesizes a 9600-baud 8N1 UART VCD carrying `REA`, then checks actual CLI/MCP parity, advertised schemas, stored Evidence, source hashes, annotation filtering/autodetection, invalid decoder/input failures and cleanup. An optional positional REA entrypoint verifies an installed package. The real-tool lane requires Linux, sigrok-cli 0.7.2 and libsigrokdecode. A separate kernel-limit regression checks the inherited soft/hard limits and verifies an oversized allocation is refused before it can consume memory. Other formats, decoders and physical acquisition are not established by the UART fixture. The workflow result must be checked before claiming a specific Linux build verified. The earlier macOS tool check does not establish the current bounded integration, which deliberately refuses unsupported hosts. One decode is admitted at a time, including acquisition and cleanup. Excess requests receive a retryable capacity error before acquiring another file or worker. Shutdown closes admission and drains accepted work; failed cleanup remains owned and retryable. ## Discover decoders before choosing settings `inspect_signal_decoders` / `inspect-signal-decoders` queries the **installed** sigrok catalog without opening a recording or scanning devices: ```sh rea inspect-signal-decoders --query uart rea inspect-signal-decoders --decoder uart --query baud rea inspect-signal-decoders --decoder i2c --offset 0 --limit 50 ``` Omit `decoder` to search decoder IDs and names. Supply one exact decoder ID to read its literal help, including required/optional channels, options, annotation classes and documentation. `query` is a case-insensitive literal substring; matching help retains original one-based line numbers. Empty query selects all. `offset` skips matches; `limit` defaults to 50. MCP `limit: null` or CLI `--all` returns all remaining matches; CLI `--all` and `--limit` conflict. The window reports examined, matching and returned records and `has_more`. A filtered empty page is not evidence that the installation has no decoders. Discovery refuses more than 65,535 line separators before constructing record objects (65,536-line representation budget), in addition to the 4 MiB output cap. Exceeding that budget is a resource failure with captured output. Returned text is copied so a retained page does not keep the complete producer output alive. Discovery shares decoding's owned process, admission slot, resource limits, cleanup retries and Evidence delivery. It records the executable and limiter identities, version banner and warnings. Failed version checks and malformed producer output preserve diagnostics. Help is producer text, not an independently validated parameter schema. Each request probes again; it does not cache or claim stable pages across installation changes. Libraries/decoder modules remain trusted and are not fully fingerprinted. Catalog output includes a SHA-256 of its executable, not a digest of the complete installation.