For a while the readme said the audit log stored the argument keys but never the values. That reads clean, and it was close, but it was not exactly what the code does. In 1.6.2 we corrected the wording to match reality, and the reality is more useful than the tidy version.
What an audit log is actually for
An audit log answers one question after the fact: what happened, who did it, and to what. In this plugin every governed call an agent makes leaves a row. That row is not there to help the agent. It is there for the human who owns the site, so that a week later they can look at a client they connected, an ability they turned on, or a request they half remember approving, and reconstruct it without guessing.
That job sets a hard requirement. The record has to carry enough detail to be worth reading. A log that only says “an agent did something” is not an audit trail, it is a light on a dashboard. You want to know which post it touched, which setting it changed, whether the call succeeded or was denied. The whole point of governance being off by default and least privilege is that you can see, and later prove, exactly what any agent was ever offered and what it actually did. The log is where that proof lives.
What the log holds, and what it does not
Here is the accurate model, per call: the acting user, the ability name, the argument keys, and a short note of what the call touched. That note is identifiers only, things like ids, meta key names, slugs, and status values. Alongside that it stores the status of the call and a timestamp. Since 1.5.0 the same log also records governance events, so a toggle flipped or a setting changed shows up next to the agent activity, not in some separate place.
What it does not store is free-text argument content. If an agent updates a post, the log notes that a post with a given id was touched. It does not keep the post body. If a call carries an email address as a value, the address does not land in the log. The argument key is recorded so you know the shape of what was sent. The free-text value behind it is not.
All of this stays on your site. The log lives in your own database, and you can clear it from admin whenever you want. The plugin makes no outbound calls and carries no telemetry, so nothing in that log is copied anywhere. It exists for you to read and, when you decide, to delete.
Why identifiers and free-text are not the same risk
The distinction between an identifier and a free-text value is the whole reason the correction was worth making. They carry very different weight when the thing an agent touched is personal data.
An identifier is a pointer. “Post 412 was updated” tells you where to look. It does not reproduce the content of post 412, and it does not sit in the log waiting to leak the sensitive thing inside it. A free-text value is the sensitive thing itself. A post body, a comment, an email address, a customer note. If those landed in the audit log, then clearing a post would still leave a copy of its contents in a second table, and anyone who could read the log could read data the record was never meant to hold. An audit trail that quietly becomes a second store of the data it was auditing is a liability, not a control.
So the log keeps the pointers and drops the payload. You can follow “post 412, status changed to draft, by this user, denied” all the way back to the object and inspect it in place, under the site’s normal permissions, where it already lives. The log tells you where to look without becoming another thing to protect. For anyone reviewing agent activity over personal data, that is the line that lets them keep a detailed record and stay honest about what that record contains.
The claim we corrected
The old wording, “argument keys but never the values,” implied an absolute that the code never actually promised. Identifier-only values have been in the log by design since 1.5.0. The readme just described it too simply, and too simply in a direction that oversold the caution. So we changed the words to say what is true: identifier-only values are kept, free-text content is not.
We sell governance. The core habit we ask of anyone running this plugin is to verify a claim against the code rather than trust a promise on a page. It would be strange to ask that of our users and not hold our own copy to the same test. An audit record that is precise about what it stores is worth more than a rounder claim that sounds safer, because the precise one survives someone actually checking it. A governance product that will correct itself in public is easier to trust than one whose promises are just slightly too clean to be real.
If you want the fuller picture, the security page covers how the plugin decides what an agent is ever offered, features walks the controls, and the release roundup, What we fixed in the 1.6.2 hardening release, lists the rest of what shipped alongside this correction.
