The audit log
Every recorded action in the log with the sentence it writes, the filter over it — and what the log is not.
The Audit screen, for the admin role: who did what and when. Every row carries the time, the actor, the action, the subject, the address the request came from, and one short sentence besides — never JSON, never a diff.
What is recorded
Every action Runjet knows, and the sentence it writes for it. The sentences are quoted as they appear in the log.
| Action | When | Sentence |
|---|---|---|
job.create | a new job | schedule …, enabled/disabled |
job.update | editing a job | what changed: schedule a → b, renamed from …, command, catch-up on, alerts off, long-run alert … |
job.delete | deleting a job | command "…", and its run history |
job.run | running by hand | queued on N agent(s), M skipped |
job.untag | removing a tag | removed a tag |
agent.create | enrolling an agent | issued a one-time enrollment token |
agent.enable, agent.disable | the switch on an agent | receives work again, stops receiving work |
agent.reset | a reset | revoked its key; every job on that host stops until it re-enrols |
agent.delete | deleting an agent | and its run history |
agent.plan_lock | choosing an agent during a downgrade | what was chosen — the decision, not the doing |
user.create | the first account at registration | — |
user.invite | an invitation, or a resend | as role; resent; the previous link stopped working |
user.accept | accepting an invitation | set their own password |
user.name | a change of name, your own or somebody else's | the new name |
user.role | a change of role | viewer → operator |
user.block, user.unblock | blocking | blocked, can sign in again |
user.password | changing your own password; a password set by code | changed their own |
user.reset_requested | a request for a code | a code was sent; sent by an administrator |
user.delete | deleting an account | their sessions ended; what they did stays on record |
user.plan_lock | choosing an account during a downgrade | what was chosen |
workspace.export | an export | — |
workspace.timezone | the zone schedules fire in | both zones: UTC → Europe/Prague |
billing.capacity | buying extra agents | extra agents 10 → 12 |
auth.login, auth.logout | signing in, signing out | authenticated |
auth.login_failed | a failed sign-in | wrong email or password |
token.create, token.revoke | API tokens (switched off today) | it stops working now |
A change of plan is not in the log; it is in Runjet's own log and on the invoice.
The actor
Three kinds: an account, a token and the system — the last for rows with nobody behind them, such as a workspace's first account or a failed sign-in. The names of actors and subjects are stored in the row, not referenced: the row "X deleted job Y" is worth having after both X and Y are gone, and that is exactly the case the log exists for.
The filter
The Actor field searches in the actor's name; the Action picker offers every action from the table above. It pages by scrolling.
What the log is not
A row is written after the action, not inside it, so that the record cannot block the thing it records — and a process killed exactly between the action and the write loses one row. This is operational history, not tamper-evident evidence. Nor is anything Runjet does by itself recorded: a cron tick, a swept output, a sent email, a change of plan. Who ran what and when is in the run history.