Something got through. A customer reports a refund they did not request, or a support agent notices a reply sent to an address nobody recognises, and the question arrives: what did the agent do?
Most teams discover at this point that their agent telemetry answers a different question. The traces record what the model said. Every prompt, every completion, every tool call and its arguments, often beautifully rendered.
None of that tells you what the agent was permitted to do, which is the only question that matters in an incident.
What did it actually do? Not what it proposed, attempted or discussed. Which side effects landed.
What could it have done? Which capabilities were held, for how long, over which resources. This is the blast radius, and it determines whether you are investigating one order or every order.
Where did the instruction come from? Which channel carried the content that led to the action. This is what tells you whether anything else is contaminated.
A conventional trace answers none of these well. The gate record from chapter 9 answers the first two directly, and chapter 6's provenance answers the third.
Four records. Everything else is optional.
The gate verdict, from chapter 9: timestamp, session, tool, argument origins, outcome, DeniedBy, reason. Every proposal, including the denied ones, because the denials are the pattern.
The capability grant: what was issued, to which task, derived from which user, expiring when. This is the answer to question two and you cannot reconstruct it afterwards.
The provenance edge: when a tainted value is produced, which source produced it. Not the value. The lineage.
The egress decision: destination, allowed or denied, budget consumed.
Argument origins are logged, never argument values. Logging the values recreates the exposure you spent chapters 6 and 10 preventing, and turns your log store into the thing an attacker wanted in the first place.
public sealed record GateRecord(
DateTimeOffset At,
string SessionId,
string TaskId,
string ToolName,
IReadOnlyList<(string Name, Provenance Origin, string SourceRef)> Arguments,
Outcome Outcome,
string DeniedBy,
string ReasonForAudit);SourceRef is the field that earns its place during an investigation. It points at the document, ticket or memory record that produced each tainted argument, which is how you get from one bad refund to the poisoned document, and from there to everything else that document touched.
The first hour is spent answering one question: how far does this go?
With the four records it is a query rather than an archaeology project.
Start with the action. Find its gate record. Read the argument origins and follow SourceRef to the source. Then invert: find every task that read that source, every action those tasks took, and every memory record they wrote. Chapter 12's SourceTaskId is what makes that last step possible.
Each of those steps is a lookup against a field you chose to record. The next section walks one through end to end, because the value of this is difficult to believe in the abstract and obvious once you have watched it run.
A customer calls about a refund they did not request. £2,400, three days ago.
Minute five. Find the gate record for that refund. It exists, because every proposal is recorded. Outcome Allow. The amount argument carries origin Tainted, SourceRef pointing at upload:invoice-88431.pdf.
That single line has already told you three things. It was not a billing bug. The amount came from a customer-supplied document. And the gate allowed it, which means either no policy marked IssueRefund irreversible, or someone approved it. The DeniedBy field is empty and there is no approval record, so it is the first. You have the root cause in five minutes and it is a missing policy rather than a clever attack.
Minute twenty. Invert on the source. Two other tasks read upload:invoice-88431.pdf that same week, one of which sent an email while the other wrote a memory record.
Minute forty. Follow each. The email went to an address that also came from the document, which chapter 10's provenance rule would have refused had it been applied to SendEmail. That is a second finding and a worse one, because it is exfiltration rather than fraud. The memory record is chapter 12's problem: it is still in the store, still tainted, still being retrieved.
Minute fifty-five. Scope. One document, three tasks, one fraudulent refund, one exfiltration, one poisoned memory record, all enumerable by query. You know exactly which customer's data left and can notify precisely rather than broadly.
Now run the same hour without provenance in the logs. You have a refund, a transcript in which the model says reasonable things throughout, and no way to connect it to a document. The scope is the entire window in which the agent was running. The notification is everyone. The root cause is a meeting.
The difference between those two hours is four log records and a SourceRef field.
Capabilities expire on their own, which is chapter 8 paying off during an incident. Minutes of exposure rather than a standing grant somebody has to remember to revoke.
Two things still need a switch.
Stop the agent. A flag that halts task issuance, held outside the agent's own configuration so that a compromised agent cannot reach it. Test it on a quiet Tuesday, because the first time you use it should not be the first time it runs.
Invalidate outstanding grants. Expiry handles the ones that were about to lapse. An explicit revocation list handles the rest, and it needs to be checked by the gate rather than only at issuance.
Download the full PDF for free?
Free download — no account required