# How to Implement Temporal Logic Verification (LTL) on CSI Event Streams in RuView

> Implement LTL temporal logic verification on CSI event streams using RuView's WebAssembly module. Detect rule violations in real time for enhanced system safety.

- Repository: [rUv/RuView](https://github.com/ruvnet/RuView)
- Tags: how-to-guide
- Published: 2026-03-08

---

**RuView processes Channel State Information (CSI) frames through a WebAssembly edge module that evaluates Linear Temporal Logic (LTL) safety rules at 20 Hz, emitting violation events when sensor data violates globally- or eventually-operators defined in [`tmp_temporal_logic_guard.rs`](https://github.com/ruvnet/RuView/blob/main/tmp_temporal_logic_guard.rs).**

RuView’s Wi-Fi-DensePose stack transforms raw CSI into structured event streams suitable for real-time safety monitoring. The repository implements **temporal logic verification on CSI event streams** through a deterministic state-machine interpreter that evaluates eight LTL invariants on every processed frame snapshot.

## LTL Guard Architecture in the RuView Pipeline

The temporal logic guard operates as a stateful middleware between signal processing and visualization layers. According to the RuView source code, the data flows through the `wifi-densepose-signal` crate before reaching the verification stage.

```

CSI capture → wifi-densepose-signal → wifi-densepose-wasm-edge
                               │
                               └─► TemporalLogicGuard (per‑frame)

```

The `wifi-densepose-signal` crate extracts subcarrier amplitudes and builds a temporal CSI matrix. It forwards a condensed `FrameInput` snapshot to the WASM edge layer, where `TemporalLogicGuard::on_frame(&FrameInput)` executes **once per frame** at approximately 20 Hz.

## Understanding G-Rules and F-Rules in RuView

The guard encodes two distinct classes of LTL formulas with different violation semantics:

- **G-rules (globally)**: These specify conditions that must never hold on any single frame. Violations trigger immediately upon detection through direct boolean checks (e.g., `presence == 0 && fall_alert`).
- **F-rules (eventually)**: These define deadlines where a trigger condition must be followed by a required state within a specific timeframe. The implementation uses state machines transitioning from `Pending` → deadline → `Violated` or `Satisfied`.

The source header in [`tmp_temporal_logic_guard.rs`](https://github.com/ruvnet/RuView/blob/main/tmp_temporal_logic_guard.rs) documents the eight safety rules:

```rust
//! Encodes 8 safety rules as state machines monitoring CSI‑derived events.
//! G‑rules (globally) are violated on any single frame; F‑rules (eventually)
//! have deadlines. Emits violations with counterexample frame indices.

```

Key timing constants defined in the implementation include:
- `FAST_BREATH_DEADLINE = 100` (5 seconds at 20 Hz)
- `SEIZURE_EXCLUSION = 1200` (60 seconds)
- `MOTION_STOP_DEADLINE = 6000` (300 seconds)

## FrameInput Structure and CSI Event Schema

The `FrameInput` struct aggregates the minimal sensor features required for LTL evaluation. This structure bridges the CSI processing layer and the temporal logic engine:

```rust
pub struct FrameInput {
    pub presence: i32,
    pub n_persons: i32,
    pub motion_energy: f32,
    pub coherence: f32,
    pub breathing_bpm: f32,
    pub heartrate_bpm: f32,
    pub fall_alert: bool,
    pub intrusion_alert: bool,
    pub person_id_active: bool,
    pub vital_signs_active: bool,
    pub seizure_detected: bool,
    pub normal_gait: bool,
}

```

Higher-level CSI processing results populate these fields from motion detection and vital-sign extraction algorithms before passing the snapshot to the guard.

## Event Emission and Real-Time Monitoring

`TemporalLogicGuard::on_frame` returns a slice of `(event_id, payload)` tuples. The guard caps emitted vectors at **12 entries per frame**, ensuring bounded memory footprint for WASM execution.

Critical event identifiers include:

| ID | Constant | Meaning |
|----|----------|---------|
| 795 | `EVENT_LTL_VIOLATION` | Rule violated; payload contains rule index (0-7) |
| 796 | `EVENT_LTL_SATISFACTION` | Periodic heartbeat; payload = count of satisfied rules |
| 797 | `EVENT_COUNTEREXAMPLE` | Frame index causing violation (debugging) |

After a violation, the affected rule remains in `Violated` state until the offending condition clears (e.g., `fall_alert` becomes `false`). Every `report_interval` (default 200 frames ≈ 10 seconds), the guard emits satisfaction events, allowing downstream health monitoring without per-frame polling.

## Implementing LTL Verification in Rust

### Instantiation and Frame Processing

Instantiate the guard once and reuse it across frames, as demonstrated in [`tests/vendor_modules_test.rs`](https://github.com/ruvnet/RuView/blob/main/tests/vendor_modules_test.rs):

```rust
use wifi_densepose_wasm_edge::tmp_temporal_logic_guard::{
    TemporalLogicGuard, FrameInput, RuleState,
};

fn main() {
    // Create the guard once.
    let mut guard = TemporalLogicGuard::new();

    // Build a normal frame.
    let mut frame = FrameInput::default();
    frame.presence = 1;
    frame.n_persons = 1;
    frame.motion_energy = 0.05;
    frame.coherence = 0.9;
    frame.breathing_bpm = 12.0;
    frame.heartrate_bpm = 70.0;

    // Feed the frame.
    let events = guard.on_frame(&frame);

    // Inspect emitted events.
    for (id, payload) in events {
        match *id {
            wifi_densepose_wasm_edge::tmp_temporal_logic_guard::EVENT_LTL_VIOLATION => {
                println!("LTL violation of rule {}", payload);
            }
            wifi_densepose_wasm_edge::tmp_temporal_logic_guard::EVENT_LTL_SATISFACTION => {
                println!("All {} rules satisfied", payload);
            }
            _ => {}
        }
    }

    // Trigger G-rule 0: fall alert with no presence.
    frame.presence = 0;
    frame.fall_alert = true;
    guard.on_frame(&frame);
    assert_eq!(guard.rule_state(0), RuleState::Violated);
}

```

### Handling Violations and Satisfactions

The `on_frame` method evaluates all eight rules against the current `FrameInput`. For G-rules, any boolean condition evaluating to true immediately generates an `EVENT_LTL_VIOLATION` with the corresponding rule index. For F-rules, the guard maintains internal counters tracking deadlines since trigger conditions activated.

## Web Assembly Integration for Browser Dashboards

The WASM edge module exposes the guard through `wifi_densepose_wasm_edge::tmp_temporal_logic_guard`, enabling JavaScript consumption for web-based dashboards:

```javascript
import init, { TemporalLogicGuard, FrameInput } from './wifi_densepose_wasm_edge.js';

async function runLTL() {
  await init();
  const guard = TemporalLogicGuard.new();

  function makeFrame(data) {
    const f = FrameInput.default();
    f.presence = data.presence;
    f.n_persons = data.n_persons;
    f.motion_energy = data.motion_energy;
    f.coherence = data.coherence;
    f.breathing_bpm = data.breathing_bpm;
    f.heartrate_bpm = data.heartrate_bpm;
    f.fall_alert = data.fall_alert;
    f.intrusion_alert = data.intrusion_alert;
    f.person_id_active = data.person_id_active;
    f.vital_signs_active = data.vital_signs_active;
    f.seizure_detected = data.seizure_detected;
    f.normal_gait = data.normal_gait;
    return f;
  }

  const csiStream = getCsiStream();
  for await (const snapshot of csiStream) {
    const frame = makeFrame(snapshot);
    const events = guard.on_frame(frame);

    for (let i = 0; i < events.length; i++) {
      const [id, payload] = events[i];
      if (id === 795) {
        console.warn(`LTL rule ${payload} violated`);
      } else if (id === 796) {
        console.log(`Health check: ${payload} rules satisfied`);
      }
    }
  }
}
runLTL();

```

## Extending the Rule Set with Custom Safety Policies

To add a new F-rule requiring `presence > 0` within 10 seconds of an `intrusion_alert`:

```rust
// Add deadline constant (20 Hz × 10 seconds).
const INTRUSION_DEADLINE: u32 = 200;

// In TemporalLogicGuard::new(), increment NUM_RULES and initialize state.

// In on_frame(), after G-rule processing:
if self.check_deadline_rule(8, input.intrusion_alert, INTRUSION_DEADLINE) {
    // Violation emitted automatically with EVENT_LTL_VIOLATION and rule index 8.
}

```

Re-run `cargo test --workspace` to verify the extended logic. The guard will emit `EVENT_LTL_VIOLATION` with payload `8` and populate `EVENT_COUNTEREXAMPLE` with the violating frame index.

## Summary

- **RuView implements LTL verification** through [`tmp_temporal_logic_guard.rs`](https://github.com/ruvnet/RuView/blob/main/tmp_temporal_logic_guard.rs) in the WASM edge crate, processing CSI-derived `FrameInput` structures at 20 Hz.
- **Two rule types** govern behavior: G-rules (immediate violation) and F-rules (deadline-based eventual conditions) with configurable timeouts like `FAST_BREATH_DEADLINE` and `SEIZURE_EXCLUSION`.
- **Event-driven architecture** emits IDs `795` (violation), `796` (satisfaction), and `797` (counterexample) with bounded 12-entry buffers per frame.
- **Dual deployment** supports both native Rust integration and WebAssembly browser execution via the same `TemporalLogicGuard` API.
- **Extensible design** allows adding custom safety policies by defining new deadline constants and invoking `check_deadline_rule` with incremented rule indices.

## Frequently Asked Questions

### What is the processing frequency of the LTL guard in RuView?

The guard evaluates `on_frame` **once per frame at approximately 20 Hz**, corresponding to the CSI capture rate. This timing determines the real-world interpretation of deadline constants: `FAST_BREATH_DEADLINE = 100` equals 5 seconds, while `MOTION_STOP_DEADLINE = 6000` equals 300 seconds.

### How does RuView distinguish between immediate and deadline-based LTL violations?

**G-rules** trigger instantly when boolean conditions evaluate true on any single frame, while **F-rules** use internal state machines that track time since a trigger event. When the deadline expires without the required condition being met, the guard transitions from `Pending` to `Violated` and emits `EVENT_LTL_VIOLATION`.

### Can the LTL guard run outside of WebAssembly in pure Rust?

Yes. The `TemporalLogicGuard` struct lives in [`wifi-densepose-wasm-edge/src/tmp_temporal_logic_guard.rs`](https://github.com/ruvnet/RuView/blob/main/wifi-densepose-wasm-edge/src/tmp_temporal_logic_guard.rs) but compiles as standard Rust. Unit tests in [`tests/vendor_modules_test.rs`](https://github.com/ruvnet/RuView/blob/main/tests/vendor_modules_test.rs) demonstrate pure Rust usage without WASM bindings, though the module is optimized for edge deployment where it can be called from JavaScript via the generated WASM interface.

### Where are the safety rule deadlines configured in the source code?

Deadlines are defined as `const` values at the top of [`tmp_temporal_logic_guard.rs`](https://github.com/ruvnet/RuView/blob/main/tmp_temporal_logic_guard.rs). For example, `const FAST_BREATH_DEADLINE: u32 = 100` and `const SEIZURE_EXCLUSION: u32 = 1200`. These frame-count values assume the 20 Hz processing rate documented in the pipeline architecture.