Audit logs
An audit trail answers who did what, when, under which rule, and what happened next — for actions that were refused as well as actions that were taken. A log that records only successes, or that the actor can edit, or that copies the content of the message it describes, is a different artefact wearing the same name.
What separates an audit trail from a log file#
Application logs exist to help somebody debug. An audit trail exists to answer a question months later, usually asked by someone who was not there. The requirements diverge quickly: a debug log wants volume and detail and can be rotated away next week; an audit entry wants completeness on four axes and has to survive.
| Axis | Records | Missing it means |
|---|---|---|
| Actor | Which person, or which automated component | “a change was made” with nobody attached |
| Action | What was decided or attempted, named the same way every time | Entries that cannot be counted or filtered |
| Authority | Which rule, mode or permission allowed it | You know what happened and not why it was allowed |
| Outcome | What actually resulted, including a refusal | A record of intentions rather than events |
Authority is the axis most often dropped, and the one that matters most in an agent system. “A reply was sent” is a fact. “A reply was sent because this channel's autonomy was autonomous and no gate applied” is an answer.
A refusal is a decision#
Connect's trail (audit.py) records what was decided, by what, under which rule, and what happened — including refusals. That inclusion is deliberate and it is the part most systems leave out, because a refusal produces no visible change and so looks like nothing happened.
Consider the cases where the absence is the important event. Outreach was not sent because the recipient is suppressed. A reply was held because the daily allowance was spent. A commercial term was refused because Knowledge did not support it and the question went to a person instead. Without the refusal in the trail, each of those reads as Connect having done nothing, and the person investigating starts by looking for a fault that is not there.
What turns an audit log into a liability#
- Copying content into it. An entry that quotes the body of the message it describes duplicates personal data into a store with a different retention rule and a different access rule. Reference the record; do not reproduce it.
- Recording secrets. Credentials, tokens and full request bodies captured “for debugging” turn an access-controlled log into a place where credentials live.
- Letting the actor edit it. A trail the acting party can amend proves nothing, and its existence invites reliance on it.
- Unbounded retention with no stated purpose. Keeping everything for ever is not caution; it is an unexamined decision that grows a liability every day.
- No access control of its own. Who may read the trail is a separate question from who may use the product, and it needs its own answer.
Does Connect use an audit log?#
Yes. audit.py and audit_api.py hold the accountability trail, and the Decision Log screen (#/autonomy-audit) is where a person reads it. It is available to both audiences over the same implementation — a customer workspace sees its own trail, filtered by the same three isolation layers every other record passes through.
- What is recorded
- Decisions, approvals, refusals, the rule that applied, and the outcome
- Where a person reads it
- The Decision Log,
#/autonomy-audit - Related surfaces
- Needs You holds decisions still waiting; the trail holds decisions already made
- What is not recorded there
- Message bodies. The conversation record holds those, under its own access rules
File changes carry their own version and provenance record as well, so “who changed this document and on what basis” is answerable without reading the trail of every action in the workspace.
Questions#
Can I use the Decision Log to find out why a reply was not sent?
Yes, and that is the case it is best at. The entry names the rule that stopped it — autonomy set to ask before sending, an allowance already spent, a suppression on the recipient — rather than leaving you to infer it from an absence. Needs You shows you the same thing while it is still pending.
Does the audit trail contain what a message said?
No. It records the decision and the outcome and points at the record; the message content stays in the conversation, which has its own access rules and its own retention. Copying content into an audit store would give the same personal data two lifetimes and two sets of permissions.
Who can read a workspace's trail?
People in that workspace, subject to the same isolation every other record gets: the customer allowlist, the workspace kernel, and row-level security in the database. There is no cross-workspace view of decisions.