> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nelieo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# NSP Runtime Probes: How Live State Extraction Works

> How NSP's four runtime probes attach to live processes, extract semantic state as structured JSON, and transition from cold probe to fast-poll.

A **probe** is the component that physically connects to a running OS process and reads its internal state — no screenshots, no UI automation, and no source code required. NSP ships four probes, each engineered for a different runtime environment. When a new process starts on the host machine, NSP's `axon-daemon` detects it, classifies its runtime, selects the matching probe, attaches to the live process, and begins emitting structured `SubstrateState` JSON within seconds.

***

## What a Probe Does

Every probe performs the same three jobs, regardless of the underlying runtime:

1. **Connect** — Establishes a channel into the live process (CDP WebSocket, JVMTI agent socket, MMF bridge, or `ptrace`/`ReadProcessMemory` handle).
2. **Extract** — Reads the application's in-memory data model and converts raw runtime objects into dot-notation key-value pairs.
3. **Normalize** — Applies semantic labels (field names, object types, action signatures) and writes the result as a `SubstrateState` object with a `confidence` score.

***

## The Four Probe Types

<CardGroup cols={2}>
  <Card title="V8 / JavaScript" icon="js" href="/probes/v8">
    Connects via the Chrome DevTools Protocol (CDP). Uses the ASO fast-path (\~5–50ms) or heap snapshot fallback (\~47s). Covers Gmail, Slack, VS Code, Notion, Discord, and any Electron app. Accuracy **>99%**.
  </Card>

  <Card title="JVM / Java" icon="java" href="/probes/jvm">
    Attaches a native JVMTI agent via the JVM Attach API and uses JNI reflection to read fields and invoke methods. Covers SAP ERP, IntelliJ IDEA, Jenkins, and Elasticsearch. Accuracy **>97%**.
  </Card>

  <Card title="CLR / .NET" icon="microsoft" href="/probes/clr">
    Injects a managed C# bootstrapper via the Windows CLR Hosting API and communicates over a Memory-Mapped File bridge. Covers Mission Planner, WinForms, WPF, and Microsoft Office. Accuracy **>97%**.
  </Card>

  <Card title="Native / C++" icon="c" href="/probes/native">
    Reads process memory via `ptrace` (Linux) or `ReadProcessMemory` (Windows) and applies Visual-Memory Grounding for semantic labeling. Covers Bloomberg Terminal, Photoshop, and AutoCAD. Accuracy **\~75%**.
  </Card>
</CardGroup>

***

## Probe Comparison

| Runtime             | Attach Method                                        | Supported Apps                                                                                                           | Accuracy |
| ------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -------- |
| **V8 / JavaScript** | CDP WebSocket + ASO injection                        | Gmail, Slack, VS Code, Notion, GitHub Desktop, Salesforce, WhatsApp Desktop, Discord, Shopify, HubSpot, any Electron app | >99%     |
| **JVM / Java**      | JVMTI agent + JNI reflection                         | SAP ERP, Eclipse, IntelliJ IDEA, Jenkins, Elasticsearch, ArduPilot GCS                                                   | >97%     |
| **CLR / .NET**      | CLR Hosting API + MMF bridge                         | Mission Planner, WinForms, WPF, Visual Studio, Microsoft Office (.NET 4.x / 6+)                                          | >97%     |
| **Native / C++**    | ptrace / ReadProcessMemory + Visual-Memory Grounding | Bloomberg Terminal, Photoshop, AutoCAD, Chrome internals                                                                 | \~75%    |

***

## App Lifecycle

Every tracked application follows the same deterministic lifecycle from first detection to steady-state fast polling.

<Steps>
  <Step title="Process detection">
    `axon-daemon` continuously scans all running OS processes and registers any new PID, executable name, and command-line arguments.
  </Step>

  <Step title="Runtime classification">
    The daemon inspects the process to determine whether it is running a V8 engine, a JVM, a CLR, or native code, and selects the appropriate probe.
  </Step>

  <Step title="App identity assignment">
    The classified process is matched against the app signature database. A matching entry assigns a stable `app_id` (e.g. `gmail-chrome-12847`) and human-readable `app_name` that survive process restarts.
  </Step>

  <Step title="Probe attachment">
    The appropriate probe connects to the target runtime. This is the cold probe phase — the first full state extraction and schema discovery. Duration is 3–90 seconds depending on runtime and app size.
  </Step>

  <Step title="First SubstrateState cached">
    Once `confidence` reaches 0.80 or above, the first `SubstrateState` is written to the in-memory cache and made available via the REST API.
  </Step>

  <Step title="Fast poll loop begins">
    The probe enters its optimized fast-path poll loop. By default, state refreshes every 2 seconds at \~50ms per cycle. Any state change triggers a WebSocket event broadcast to all subscribers.
  </Step>
</Steps>

<Note>
  When the tracked application exits, the probe detaches automatically, the state is removed from cache, and the `probe_status` transitions to `detached`. No manual cleanup is required.
</Note>

***

## Probe Status Values

The `probe_status` field in `AppSummary` reflects the current lifecycle phase:

| Status       | Description                                                  |
| ------------ | ------------------------------------------------------------ |
| `detecting`  | Process seen but runtime not yet classified                  |
| `attaching`  | Probe establishing connection to the target runtime          |
| `cold_probe` | First full state extraction and schema discovery in progress |
| `active`     | Fast poll loop running normally                              |
| `error`      | Probe encountered an error and will retry                    |
| `detached`   | Process exited — probe cleaned up, state removed             |

***

## Confidence Score by Runtime

Each probe produces a `confidence` score (0.0–1.0) reflecting how completely its semantic labeling covers the application's state. Confidence determines which action tiers are unlocked.

| Runtime            | Cold Probe | After Schema Cache |
| ------------------ | ---------- | ------------------ |
| V8 (ASO path)      | 0.95–0.99  | 0.97–0.99          |
| V8 (Heap snapshot) | 0.75–0.90  | 0.90–0.97          |
| JVM                | 0.93–0.97  | 0.95–0.98          |
| CLR                | 0.93–0.97  | 0.95–0.98          |
| Native             | 0.40–0.75  | 0.60–0.80          |

| Confidence Range | Action Gating                               |
| ---------------- | ------------------------------------------- |
| `0.00 – 0.39`    | No actions allowed — probe initializing     |
| `0.40 – 0.79`    | Read-only actions only                      |
| `0.80 – 0.94`    | `reversible_write` actions allowed          |
| `0.95 – 1.00`    | All actions, including `irreversible_write` |

***

## Forcing a Fresh State Read

By default, state is served from the 2-second rolling cache. To bypass the cache and trigger an immediate probe cycle:

<Tabs>
  <Tab title="HTTP">
    ```bash theme={null}
    GET /substrate/v1/state/12847?fresh=true
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    await session.refresh(fresh_probe=True)
    ```
  </Tab>
</Tabs>

<Warning>
  Do not call `fresh=true` in a tight loop. For continuous updates, use WebSocket streaming — the daemon pushes state-change events on every poll cycle automatically.
</Warning>
