04 / INVESTIGATION & RESPONSE
From a signal
to a decision with a name on it.
An alert tells you something happened. A path tells you how it could have happened, which steps actually carried, and which ones the edge already stopped. Response then follows one rule: a model may propose, and only a person may approve.
THE LOOP THIS PRODUCT HAS TO CLOSE
EDGE + GITHUBingest
The only live inbound paths. Ten connector kinds are registered and fail closed.
BUILTgraph
Entities, edges and provenance, projected from events that really happened.
BUILT, THIN INPUTenrich
Classification and entitlement resolution over whatever the graph actually holds.
BUILTanalyze
Exposure scans, posture rules, path search, rollout simulation.
BUILT, NO BASELINEprofile
Per-entity reach and identity profiles. No behavioural or peer baseline.
ONE ACTIONremediate
Propose, approve, execute, verify. The only effector is revoking a session.
WHAT DOES NOT ARRIVE
Findings are only as wide as the events behind them. With no identity, drive or SaaS ingestion, the paths this module searches are the ones the edge and GitHub recorded: agent sessions, authority decisions, secrets a finding named and the destinations behind them. An investigation into a drive share has nothing to read.
WHAT CANNOT BE ACTED ON
One effector. revoke_session is the only action type in the code, and executing a proposal calls exactly one thing: the revocation append. There is no revoke-share, disable-account or kill-token action, and no notifier of any kind — no chat, mail or ticketing sender exists in the control plane. What this module offers is not breadth of response. It is one action closed with proof.
Nothing in this module runs on the agent's critical path. The edge decides on its own, from its own ledger, and keeps deciding if the control plane is unreachable. What the control plane can do is take authority away, never grant it.
[ 01 ]WHAT A FINDING IS+
Not a score.
A route, in time order.
A path starts where untrusted content arrived and ends at something worth reaching: a secret, a destination, a file. Each move along it is an edge, and each edge names what the agent had to already hold for that move to carry.
THE ENTRY
Where untrusted content arrived.
A pull-request title, a fetched page, a tool result, an MCP server's own description. The entry is an event with an identifier, not a category, and the path is anchored to it.
THE STEPS
Each with its prerequisite.
A step records what it needed the session to hold, such as untrusted content in context or a secret already read, and the events that show it held it. The search is bounded: six hops, fifty paths, a hard expansion limit, because a dense session would otherwise explode combinatorially.
FEASIBLE, OR NOT
The empty set is the good news.
A path is feasible when every step is supported by an event that went ahead or may have. A step with no supporting event was attempted and could not have carried, because everything that would have supported it was stopped at the edge. That distinction is the difference between an incident and a near miss, and it is recorded rather than inferred.
[ 02 ]THE EVIDENCE IT CARRIES+
Every claim points
at something you can open.
Two records sit behind a finding: what the finding did over time, and what the graph can show about the entity it names.
RECORDED TRANSITIONS
one lifecycle move, stored per tenant
on the finding, the decision or the job
A finding's history is a list of moves rather than a current status. Who moved it, when, and from what to what. Relations to other entities are stored the same way, which is what lets an investigation follow a session to a secret to a destination without leaving the record behind.
DATED GRAPH PATHS
reachability from one workforce entity
asked for by an investigator, or directly
Given an entity, such as an agent, a session, a secret or a network destination, the graph returns reachability paths with the dates and evidence identifiers attached. The assistant answers out of the same source, which is why its answers can be checked rather than believed. How the assistant cites ↗
[ 03 ]THE RESPONSE LIFECYCLE, FOR ONE ACTION+
A model may propose.
A person approves.
Everything in this section governs one action: revoking an agent session. It is a state machine rather than a button, so that the most useful thing an automated investigator can do stays the least dangerous thing it can do. Depth here is not breadth, and we would rather have this depth on one action than the appearance of a hundred.
PROPOSEDAnyone may ask.
A person or the investigator proposes, with a rationale and citations. A proposal from the model is marked as coming from the model, and it expires undecided after seven days rather than sitting in a queue forever.
DECIDEDOnly a person answers.
The approver has to be an authenticated person: a model identity is refused at the door. Whoever proposed may not be the one who decides, so an approval always has two names on it.
EXECUTEDA separate step.
Approval is not execution. Executing appends the revocation and records the identifier and sequence it produced, so the act and the decision are two entries rather than one.
VERIFIEDRe-observed, then signed.
Closure is not a status flip. The revocation log is read again and checked for a newer record that re-authorized the session. An unconfirmed closure reads claimed, a confirmed one with no signing key available reads unverifiable, and only a confirmed and signed closure moves the proposal to verified.
RECORDED STATES
proposedapprovedrejectedexecutedverifiedfailed
There is exactly one action type: revoke_session. Executing an approved proposal calls the revocation append and nothing else. It takes authority away from an agent session and it can never grant any, and it is the only effector the control plane has. A single-verb response surface is a smaller thing to get wrong than a general automation engine, and it is the honest description of what is built rather than a design philosophy invented after the fact.
[ 04 ]REVOCATION+
The kill switch lands
on the next tool call.
Containment happens at the point of decision rather than in the transcript afterwards. The two halves of that are deliberately separate.
THE CONTROL PLANE SIDE
append-only, per-tenant sequence
when a person approves and executes
Revocations are appended with a monotonic sequence the workstation daemon polls after, so a missed poll catches up rather than losing an entry. Reasons are categorical codes, never free text: operator, or a finding, remediation or incident identifier. At the tenant capacity bound a new revocation is refused rather than an old one dropped, because a dropped revocation would silently restore authority on a new machine.
THE EDGE SIDE
caveat-agentd, then the hook
on the session's next tool call
The daemon polls for revocations on an interval, thirty seconds by default, and applies what it finds. From then on the hook refuses that session outright: a revoked session is the one case where the answer is a refusal rather than a question. The hook reads this from a file the daemon wrote, never over a connection it makes itself, so revocation costs the decision path nothing.
[ 05 ]SIGNED PROOF+
Seal the session
into something an auditor can verify.
A session can be assembled into a signed statement, in the DSSE and in-toto shape, over the events that were actually recorded. It is built from stores it only reads; the assembler writes nothing.
WHAT THE STATEMENT CONTAINS
- The agent, the model and the basis
- MCP inventory as hashed ids and counts
- Turns, attempts and tool calls by category
- Authority decisions in the window
- Guard mode and guidance deliveries
- Findings by kind, subkind and severity
- Kernel observations as per-kind counts
- Bounded digests, never a path in the clear
- The audit chain head and its coverage
Evidence can be mapped to a regulatory reference from a closed catalogue, and the mapping says the evidence is relevant to the requirement. It never says the requirement is met, because that is an assessor's finding and not a signer's. A reference outside the catalogue is refused rather than carried as free text nobody checked.
[ 06 ]WHAT THE SIGNER DOES NOT ASSERT+
The non-claims,
shipped with the claim.
Every attestation carries this list as fixed text. The last two apply to the module as a whole.
- No code, prompts, file paths or command lines are in the statement. Identifiers and names are hashes or fixed labels.
- UNAVAILABLE means not measured, never zero. A session the edge never recorded reads unavailable rather than reporting a comfortable count of nothing.
- The audit anchor proves the chain position at signing time. It does not assert that the change was correct.
- No sandbox isolation is attested. Kernel observations are counts and digests, and a digest identifies without concealing.
- Tokens are counted only where a runner or provider reported usage. No cost is asserted.
- The kernel view is Linux only. The macOS collector is written against Apple Endpoint Security and cannot run without an Apple-granted entitlement, so it reports UNAVAILABLE. The Windows collector reads the kernel process session and, today, each record header.
- No detection or prevention rate. The replay harness exists and no benchmark corpus has been run through it.
One measured result belongs to this module: on a replay of the Comment and Control attack class, seven of seven exfiltration steps were refused and five of five legitimate review steps were allowed. That is one replay of one attack class against real binaries, not a detection rate. The full ledger, including what has not been measured, is on the security page.
[ 07 ]THE REST OF THE PLATFORM+
Response is the end
of four other stories.
The modules that produce the findings this one acts on.
EVIDENCE, THEN AUTHORITY
Bring the incident
you had to explain.
Walk us through the last one, and we will show you which parts of it this records and which parts it does not.
Talk about a pilot ↗