Skip to main content
Every audit event is one JSON object: the same in the history, in an export’s JSON Lines, on a server’s output and to its webhook.

The format

An AI assistant's restart, approved
Lumovi writes each on one line. A field with nothing to say is left out, rather than empty or null. Whatever’s sent, an event stays one line of at most 64 KiB:
  • Text is cut at whole characters, and ends in …: names (a user, a cluster, an object) at 256 characters, sentences (summary, command, error) at 4,000, a detail or a note at 1,000. Half of a character pair, which no two JSON tools read alike, becomes � (U+FFFD).
  • Details: at most 50, a list at most 100 items, and 16 KiB in all. Past that, the rest are left out, and truncated: true says so. forwardedFor keeps 200 characters, and userAgent 300.
  • An event over 64 KiB even so has its sentences cut to 1,000 characters, at most 10 groups, and only truncated: true in its details.
  • A number in its details that isn’t a whole one within JSON’s safe range, like 1e21 or 0.1, is kept as its text: "1e+21", "0.1". JSON tools write those each their own way, and this way every hash is the same in all of them.

Errors about Secrets

What the cluster, or an admission webhook, says about a Secret can quote its values. So when a change to a Secret fails, from the page or an AI assistant, its error says what happened, by its cause, and not what the cluster said: Each followed by “What the cluster said of the Secret isn’t kept: it can quote its values.” Lumovi’s own refusals, by read-only mode or access, are kept as they’re said. An AI assistant’s tool call about a Secret that fails says “It failed. What the cluster said of the Secret isn’t kept: it can quote its values.”: one whose kind has “secret” in it, in any case, like Secret or SealedSecret, or with a manifest of a Secret. A tool call that’s refused is kept as Lumovi said it.

Actions

Each action, by kind, and what the page calls it.

Changes (change)

Access (access)

Sign-ins (sign-in)

On a server, unless people sign in at an authenticating proxy. Sign-ins that don’t succeed are recorded too, each, up to 60 a minute. Past that, they’re counted, and one event a minute, by Lumovi itself, says how many and from where: “25 more sign-ins didn’t succeed, each not recorded: more than 60 were tried in a minute”. So does one as the server stops, for those it hasn’t said yet. They’re nobody’s own: only auditors see them.

AI assistants (assistant)

Settings (settings)

Server (server)

With the changes level, a server records everything but the Access kind and assistant.tool, but for an assistant’s call to change something that was refused: that’s a change asked for, and it’s kept, with changing: true in its details.

Outcomes

Approvals

approval.status says what became of an AI assistant’s change: waitedMs runs from when the person was asked to their answer. by is the person: only they answer their assistants’ changes. The change’s tool call (assistant.tool) comes out the same: refused when rejected, cancelled when nobody answered or it was withdrawn. A call that ends while the change still waits for its answer is success, with waiting: true: nothing has happened yet, and the change’s own event, or the wait_for_change call that gets the answer, says what did. A change an assistant’s permissions don’t allow, or the cluster’s dry run turns down, has no approval: nobody was asked.

Details

What each action adds in details, when it applies:

Check it hasn't changed

How the chain works, and how to check it.

Audit log for your team

The server’s output, a webhook, and who reads everyone’s.