← The ADLC library
Governance & security · 1

Proving what an agent did, six months later

The question is never asked on the day. It is asked half a year later, by someone who was not there, about a change nobody remembers, and your answer has to survive that.

The meeting is in February. The change was made in August. There are six people in the room and none of them were on the team that made it. Somebody from risk has a printout, and on the printout is a line that says a permission check was relaxed on a customer-facing endpoint. They want to know three things: who decided that, what they were trying to achieve, and whether anything else was changed at the same time for the same reason.

The engineer who is nominally responsible pulls up the pull request. It merged. It has one approval. The approval is from a colleague who left in November. The pull request description is a single line that reads “implements ticket PLAT-4471”. PLAT-4471 says “tidy up auth middleware”. The commit was authored by an agent under a service account.

Nobody in the room is being obstructive. There is no allegation. But there is also no answer, and the absence of an answer is going to cost more time and more credibility than the change itself ever saved.

I want to talk about that gap, because it is the single most common governance failure I see in teams that have moved a lot of their delivery to agents, and it is almost never caused by carelessness on the day. It is caused by recording the wrong things, cheaply, and only discovering which things were the right ones much later.

The thing that decays is context, not data

Here is the counterintuitive part. In that February meeting, data was not scarce. There were logs. There were commits. There was a CI run with timestamps and a build artefact and a deploy record. If anything, there was too much data, spread across five systems with five different retention policies and no shared identifier tying them together.

What was scarce was context. Specifically, four things had evaporated:

Intent. Why this change, and why now. Not the ticket title, the actual reasoning. A human developer used to carry this in their head and leak fragments of it into the pull request description, a Slack thread, a comment on the ticket. That leakage was unreliable but it was something. An agent leaks nothing unless the process makes it leak.

Authority. Who decided this was acceptable, and on what basis were they entitled to decide it. An approval click from a departed colleague is evidence that a click happened. It is weak evidence about authority, because it does not record what the approver was approving against.

Scope. What else moved with it. In August this was obvious to everyone involved. In February it requires reconstructing a week of activity from five systems.

Reversibility. How you would undo it, and whether undoing it is still possible. This one is almost never recorded at the time, because at the time it feels obvious.

Data has good retention. Context has terrible retention. It lives in people, and people leave, forget, and reinterpret. Any scheme for proving what happened has to assume that in six months the only thing left is what was written down deliberately.

What the logs preserved

  • A commit hash and timestamp
  • A service account name
  • A CI run that went green
  • An approval event
  • A deploy record in a third system

What the room actually asked for

  • Why this change was made
  • What criteria it was judged against
  • Whose authority stood behind it
  • What else moved with it
  • How it could be undone
Both columns describe the same event. Only one of them answers a question asked six months later.

Attribution is not a name

The instinct, once a team notices this, is to fix attribution. Make sure every change has an owner. Ban service accounts. Require a human name on every commit.

This is well-meant and it mostly makes things worse. What you get is a human name attached to work that human did not do and could not describe. That is not attribution, it is laundering. The name gives a reviewer false confidence and gives an auditor a target who cannot answer questions about the thing they are named on.

Real attribution for agent work has to record a chain, not a person:

  • The human intent that initiated the work, expressed as something checkable rather than a wish.
  • The agent action that acted on that intent, including which agent, running under which configuration, with which permissions.
  • The human authority that accepted the result, and crucially, what they accepted it against.

That last clause carries all the weight. “Alex approved this” is nearly meaningless in February. “Alex approved this against these five acceptance criteria, of which four were mechanically verified and one was accepted by judgement with this note” is a defensible statement about a decision. It survives Alex leaving, because it does not depend on Alex’s memory.

Write the record at the moment of the action

The second failure mode is reconstruction. Teams that get burned once often respond by building a reporting pipeline that assembles the story afterwards: a job that walks commits, joins them to tickets, infers approvals, and produces a nice document.

Reconstructed evidence has a structural weakness. It is a claim about the past made by a system that could have been changed since. If the joining logic has a bug, if a ticket was edited, if a branch was force-pushed, the reconstruction quietly produces a confident and wrong story. And you find out it was wrong at exactly the worst moment, because nobody stress-tests the reporting pipeline until someone external is reading its output.

The alternative is to write the record at the moment the action is taken, as part of taking it. Not a log line emitted as a side effect, but a record that is part of the transaction: the action does not count as done until the record of it exists. This is the same discipline as double-entry bookkeeping, and it exists for the same reason. It is not that ledgers are more accurate than memory. It is that they are written at the point of the event by the party performing it, so they cannot be smoothed over later without leaving a mark.

What changedThe concrete effect: a status moved, a field was set, a gate passed, a merge was allowed.
WhyThe rule, criterion or instruction that produced the action, quoted rather than summarised.
On whose authorityThe identity, the role, and the scope that permitted it at the time it happened.
How to undo itThe prior state and the specific action that restores it, written before it is needed.
Four fields. Any automated action that cannot fill all four is an action you have not really governed.

Those four fields are the whole thing. I have watched teams design elaborate governance schemes and then discover that the useful residue is exactly this: what, why, whose authority, how to undo. Every question in the February meeting is answerable from those four fields, and almost none of them are answerable without.

This is the shape of the audit trail GroundTruth writes for automated changes, and I will not pretend that is a coincidence, but the shape is not proprietary. You can build it in an afternoon with a database table and a discipline about never letting an automated action happen outside it. The discipline is the hard part.

The completeness problem

Here is the question that separates people who have been through a real audit from people who have not. Somebody looks at your beautifully structured evidence and asks: how do you know this is all of it?

You can produce a perfect record of a hundred changes and it proves nothing about the hundred and first. The value of a change record is not in the quality of any individual entry. It is in the credibility of the claim that the set is complete, that no automated action occurred outside it.

Completeness comes from architecture, not from effort. There are only two ways to get it:

Chokepoint. Every automated action goes through one path, and that path writes the record. If an agent can only move a ticket by calling one service, and that service records every call, the population is complete by construction. If agents can also move tickets by hitting the tracker API directly with a personal token, it is not, and no amount of process will make it so.

Reconciliation. You periodically compare the record against the state of the world and flag anything you cannot account for. This is weaker, because it detects gaps rather than preventing them, but it catches the chokepoint being bypassed, which the chokepoint by definition cannot.

Do both. The chokepoint gives you the claim. The reconciliation gives you evidence for the claim, which is a different thing and the one you will actually be asked for.

Retention is a design decision, not an ops setting

Six months is not a long time. In several regulated contexts the relevant horizon is measured in years, and the retention period that matters is usually not the one your observability vendor defaults to.

Two practical points that cost teams real money when they get them wrong.

First, your evidence has to outlive the systems that produced it. If your proof of what happened is a set of links into a tracker, a CI provider and a chat tool, then your evidence has an expiry date set by whichever of those you churn first, or by whichever one prunes history soonest. Links are not evidence. Extracted, self-contained records are.

Second, retention interacts badly with deletion obligations. You may be required to keep change records for years and simultaneously required to delete certain personal data on request. Those two are only compatible if your change records do not carry payloads they did not need. Record the identity that acted, the criteria text, the state transition. Do not record whatever happened to be in the request body. Every unnecessary field in a long-retention store is a future problem.

What good looks like in the February meeting

Run the scene again with the four fields in place.

Somebody asks who decided to relax the permission check. You pull one record. It says: the middleware change was made by an agent acting on ticket PLAT-4471, whose acceptance criteria are quoted in full and include a specific criterion about anonymous access to a health endpoint. It says the change was gated on those criteria, four checked mechanically and one accepted manually with a note from a named engineer holding a role that permitted the acceptance. It says two other changes were made under the same ticket, with links. It says the prior configuration and the exact steps to restore it.

The meeting takes eleven minutes instead of three weeks. The change might still turn out to have been a bad idea. That is a different conversation, and a much healthier one, because it is about the decision rather than about whether anybody can reconstruct the decision.

That is the whole ambition here. Not to prevent mistakes, which is not achievable, but to make sure that six months later the organisation is arguing about the right thing.

Where this breaks down

I have made this sound tidier than it is.

The most obvious limit is that a record of what an agent did is not a record of whether it should have done it. You can have flawless provenance for a catastrophically bad decision. Proof answers “what happened and who stood behind it”. It is silent on “was that wise”, and there is a real risk that a beautiful audit trail creates a false sense of safety, in the same way that a green test suite does. I have seen teams get much better at evidence and no better at judgement, and evidence is the easier of the two to buy.

The second limit is coverage. Everything above assumes the interesting actions pass through a place you control. Plenty do not. A developer pasting agent output into a console, an agent with credentials to a SaaS admin panel, a data change made through a vendor UI: none of that hits your chokepoint. The proportion of your risk that lives outside the instrumented path is the proportion of this scheme that does not apply, and that proportion is usually higher than people estimate on first pass. Measure it before you promise anyone completeness.

The third is the cost of the “why” field. Intent is genuinely hard to capture, because the honest answer is often “the criteria said so and the criteria were written in a hurry”. Recording a quoted criterion is not the same as recording a reason. A team with vague acceptance criteria will produce a change record whose “why” column is a row of vague criteria, faithfully preserved. The evidence layer inherits the quality of the specification layer and cannot exceed it.

Fourth, there is an uncomfortable tension between proof and speed that nobody has fully resolved. Every field you require at the moment of action is friction at the moment of action. The four above are, in my experience, close to the minimum that survives a real audit, but they are not free, and a team under delivery pressure will find ways to fill them perfunctorily. A record that is complete and meaningless passes an inspection and fails a February meeting.

And finally: none of this makes an organisation compliant with anything. Compliance is the outcome of a programme with owners, testing, and remediation. Evidence is an input to that programme. Anyone selling you the second as the first, including anyone selling software, is describing a smaller thing than they are naming.

The takeaway

The question is asked in February, not August, by someone who was not there. Design for that reader. Record four things at the moment of every automated action: what changed, why, on whose authority, and how to undo it. Get completeness from a chokepoint and prove it with reconciliation. Keep the records self-contained so they outlive the tools that made them.

Everything else in governance is downstream of having those four fields and being able to say, credibly, that you have them for every automated change and not just the ones you remembered.

The next piece looks at how those records are made tamper-evident, which is where the conversation usually collides with a lot of unnecessary cryptographic marketing, and what the underlying mechanism actually buys you once you strip that away.