Linked runs: intent and effect

Two systems watch the same laptop and neither sees the whole thing. A runtime hook sees what the agent intended — the tool it asked for, the arguments, the policy verdict. An endpoint sensor sees what the process actually did — the subprocess it spawned, the address it connected to, the file it wrote. Trefur links them.

Why the two views differ

An agent asks to run a command; the hook records the request and the verdict. What that command goes on to do — install a package, open a connection, write a file — happens after the hook has answered and outside what it can see. The sensor records those effects and knows nothing about the conversation that asked for them, or whether a policy allowed it.

Held apart, each view has a blind spot that matters:

  • Agent activity on a machine with no hook installed looks like nothing at all in the runtime view.
  • An agent process that no session explains — started outside the hooks, or by someone who removed them — looks like ordinary activity in the endpoint view.

Linking the two turns both blind spots into something you can see and act on.

What you get

Linked runs on the run page

Open a run and, where a matching view of the same work exists, a Linked runs panel lists it. Each entry says which side it came from:

  • Endpoint evidence — you are looking at a runtime session, and this is what the sensor recorded of the process it ran in.
  • Runtime session — you are looking at what the sensor saw, and this is the session that explains it.

Each entry carries the other run's agent name, where the evidence came from, how the two were joined — by process lineage or by host and time — how much of the two runs overlap, when it started, and a link to open it. Several sessions can link to one process — two terminals, or an editor hosting several conversations — and where the runtime side reports process lineage, all of them are listed, not just one. The same summary appears inline when you expand a row in the runs list.

The panel appears only when there is something to show. A run with no counterpart renders nothing.

Two findings

FindingSeverityRaised when
edr_unattributed_agent_processMediumAn agent process ran on a host that does have runtime coverage, and no session accounts for it.
edr_coverage_gapInfoA host is producing agent activity and has no runtime coverage at all.

The two say different things. A coverage gap is an enrolment fact — a machine where the hooks were never installed — so it is informational and repeats are suppressed rather than raised again for every process. An unattributed process on a covered host is the more interesting one: the hooks are there and this activity still went around them.

Both appear in the Risk Center like any other finding, and both are carried by the OCSF export as detection findings.

How a machine is identified

The two sides are brought together under a keyed per-workspace digest of the machine name — never the machine name itself. The name is not stored on a run, a step or a finding on either side. The digest is stable within your workspace, so the same laptop matches across both feeds, and it is not comparable outside it.

This is the one thing the feature depends on. Where Trefur cannot derive that digest for a run, the run is closed with no match rather than matched on something else: no link, no finding, and no guess.

What you need for it to work

  1. Runtime coverage on the machines you care about — the Claude Code hooks or another collector input that reports agent activity.
  2. An endpoint feed connected: endpoint security feeds.

With only one of the two, you still get that side's runs. You do not get links, and the only finding that can be raised is the coverage gap.

Limits

  • An endpoint run is not judged the moment it arrives. Endpoint feeds run behind real time and a collector may have been buffering, so judging waits for the runtime side to have had its chance to appear. A process is not called unattributed as soon as it is seen.
  • Linking is at the level of a run, not a step. Where several sessions share one process, Trefur links all of them to it and does not attribute an individual step to one session.
  • A containerised agent is not modelled. The process identifiers it reports and the ones the sensor reports do not line up, so the two cannot be joined on lineage. The run may still be linked by host and time; on a host where every session does report lineage, it can instead be raised as an unattributed agent process. That is a false positive rather than a missing link, and it is the case to know about before you act on that finding.
  • A run is judged once. Evidence that arrives afterwards does not reopen it.
  • The panel shows a bounded number of links per run. A run with more than that shows the first of them, with no way to page through the rest.
  • A link is evidence that two views describe the same work. It is not a claim that the session caused everything the sensor recorded.
  • A link is visible to anyone who can open the run it hangs off — there is no separate role gate on it. The two findings appear in the Risk Center under the same visibility rules as any other finding.