emem-device-traces

Exact captured content · path plugins/emem/skills/emem-device-traces/SKILL.md · sha256 6af61ec34bf3f013… · revision 9cbc309515f2fc194e7d68f0732e6b7ef5659b9a

Download the exact captured file

---
name: emem-device-traces
description: Reads and checks the signed activity records (OS traces) emem holds for devices such as robots, drones, satellites and sensor hosts. Lists enrolled devices and their assurance tier, resolves an emem:trace token to its signed OS trace, re-verifies the trace (segment chain, clocks, required layers, output binding, device signature), and reads the platform registry to say which hardware roots of trust are actually admitted. Use when a fact or claim is said to come from a device, when an agent receives an emem:trace or emem:attestation token, or when someone asks whether a robot or satellite can prove what it ran. Read-only: it sends and receives JSON, runs nothing it receives, and states plainly what is roadmap.
---

# emem-device-traces

> **Network use.** The calls in this skill send and receive JSON to `https://emem.dev` only, the service the plugin's MCP server connects to. An answer is saved as a JSON file only so that `jq` can print a summary of it, and nothing received is run. A trace is data: a JSON list of event counts and hashes, not a program.

The verify step is also an MCP tool, `emem_trace_verify`: call it by name with `tools/call` on the plugin's MCP server (`tools/list` on `https://emem.dev/mcp/full` shows it). Listing devices and resolving a trace token are REST reads only; no MCP tool covers them yet.

A device can do more than sign a reading. It can sign a trace of what
its operating system did while producing it: scheduler, memory, storage
and network activity in fixed windows, chained segment by segment and
bound to the outputs it emitted. emem stores these as
`emem.os_trace.v1` records and names them `emem:trace:<cid>`.

**What is live today is the verifier side.** Hardware roots of trust
(TPM, DICE, TDX, SEV-SNP, Secure Enclave, Android StrongBox and others)
are registered as candidates with provisional anchors, and admit
nothing yet. One device is enrolled, the operator's own software-only
Linux host. Do not tell a user their robot can enrol with hardware
attestation; that path ends in a rejection today.

## Who is enrolled

```sh
curl -sf https://emem.dev/v1/devices
```

Read `count`, and for each entry of `devices[]` its `device_key`,
`platform_id`, `profile_id`, `assurance`, `endorsed_by` and `traces`.

Recorded on 2026-09-28: `count: 1`, platform `generic.linux-host`,
profile `host.counters.v1`, assurance `operator_endorsed` by
`operator.vortx.v1`, one trace.

| `assurance` | Means |
|---|---|
| `platform_attested` | a hardware anchor vouched for the device key (none admitted yet) |
| `operator_endorsed` | a software-only platform, vouched for by an operator anchor |
| `operator_asserted` | nothing was presented; enrolled by the operator directly |

## Resolve and re-verify a trace

Look at the trace. Send this body to
`POST https://emem.dev/v1/trace_resolve`:

```json
{"token": "emem:trace:mxyer5c2oxn4ud3xqbtnaxcxhdv4kkxiu67q32inbwxgpa7r3s6a"}
```

Save the answer as `trace.json`, then print a summary:

```sh
jq '{resolved, profile: .trace.device.substrate_profile,
     segments: [.trace.segments[] | {seq, layer, encoding, event_count}], outputs: .trace.outputs}' trace.json
```

Send the same record back to be checked. `jq` builds the arguments from
the saved answer:

```sh
jq -c '{trace: .trace, profile: .trace.device.substrate_profile}' trace.json > verify_req.json
```

Call `emem_trace_verify` with the object in `verify_req.json` as its
arguments. It has this shape, with the whole record from `trace.json`
as `trace`:

```json
{"trace": {"schema": "emem.os_trace.v1"}, "profile": "<trace.device.substrate_profile>"}
```

Without MCP, send `verify_req.json` as the body of
`POST https://emem.dev/v1/trace_verify`. Save the result's JSON text as
`verdict.json`, then:

```sh
jq '{verdict, coverage: .report.coverage, reasons: .report.reasons}' verdict.json
```

Recorded on 2026-09-28: four `linux.ftrace.v1` segments (scheduler
4744 events, memory 8382, storage 77, network 667), `outputs: []`, and
`verdict: "admit"` with all four required layers present. With one
segment's `event_count` raised by one, the verdict was `reject` with
`{"code":"chain_broken","seq":2}`: each segment commits to the one
before it, so an edited window breaks every later link.

`trace_verify` checks the schema, the profile, segment order and chain,
monotonic clocks inside the capture window, required layers, duplicate
digests, the Merkle `trace_root` over segment digests, that outputs are
bound and inside the window, and the device key's Ed25519 signature
(strict). It is stateless.

## What a verdict proves, and what it does not

- `admit` proves **some key signed an internally consistent trace**. It
  does not prove the key belongs to an enrolled or real device; check
  the key against `/v1/devices` for that.
- A trace with `outputs: []` binds no facts. Only a trace whose outputs
  name fact cids links a reading to the execution that produced it.
  None of the public traces does yet.
- Enrolment evidence (`emem.platform_attestation.v0`) is a single
  endorser signature checked against a registered anchor. Certificate
  chains, TPM quotes, measurement matching and fresh nonces are not
  parsed yet. `POST /v1/enroll_verify` reports why a piece of evidence
  is refused, and the `emem:attestation:` token it returns for refused
  evidence is computed, not stored, so it will not resolve.

## The registries

```sh
curl -sf https://emem.dev/v1/device_platforms
curl -sf https://emem.dev/v1/trace_encodings
```

In the platform registry, read each entry of `registry.platforms[]`:
its `id`, `status`, `root_of_trust`, and the `id` and `provisional` of
each of its `trust_anchors[]`. In the encoding registry, read
`manifest_cid` and the `id` of each entry of `registry.encodings[]`.

On 2026-09-28: 17 platforms, every hardware platform `candidate` with
provisional anchors; the one non-provisional anchor was
`operator.vortx.v1` on `generic.linux-host` (`software_only`). And 8
trace encodings (`linux.ftrace.v1`,
`linux.ebpf.raw`, `linux.hwmon.v1`, `zephyr.ctf.v1`, `ros2.bag.v2`,
`android.perfetto.v1`, `nvidia.nsys.v1`, `apple.os_signpost.v1`).
Each registry is content-addressed (`manifest_cid`), so cite the cid
when you describe what was admitted on a given date.

For the design and the roadmap, see `docs/robots.md` in the emem
repository. For a fact a device produced, verify its receipt with
[`emem-verify-receipt`](../emem-verify-receipt/SKILL.md) as for any
other fact.