Smart Agent Teams

Activity log

The append-only audit trail of every change in a company, with who made it.

The activity log records every change made in a company: who did it (a person, an agent or the system), what they did, to which object, and which fields changed. It is the audit trail the board uses to answer "why did this happen?", and the same write that adds a log entry also publishes the live event that refreshes everyone's screens.

How it works

Each mutating endpoint adds one entry in the same database transaction as the change, so an entry exists if and only if the change was committed. Entries are never updated or deleted through the API.

Actors

actor_typeactor_id and actor_nameUsed for
userThe member's user id and name.Changes made with a person's credentials (web app, CLI or API key), including queuing runs.
agentThe agent's id and name.Task creates, updates and comments made by a runner on behalf of an agent, when the request carries run_id of the agent's running run.
systemnull, system.Runs being claimed, finished, cancelled or expired, and agents paused for budget.

Agent attribution through run_id. A runner acts with a person's credentials (often an API key). To have a task change credited to the agent instead of the person, it passes the run_id of the run it is executing on POST /tasks, PATCH /tasks/{task_ref} and POST /tasks/{task_ref}/comments. The run must be running (400 RUN_NOT_RUNNING otherwise). The entry is then recorded with actor_type: agent and the run's agent, and the task's created_by_agent_id or the comment's author is set to the agent. sat runner does this for the task follow-ups it posts.

Verbs and entities

entity_typeVerbs
companycreated, updated
agenthired, proposed (hire through approval), updated, paused, resumed, terminated
taskcreated, updated, moved (only status or order changed), commented, deleted
goalcreated, updated, deleted
projectcreated, updated
routinecreated, updated, deleted, triggered
runqueued, started, succeeded, failed, cancelled
approvalapproved, rejected

entity_label is a readable label stored at write time, such as NF-10 Fix flaky sync test on CI, Grace or Ken · assignment. It is not updated if the object is renamed later.

Changes

changes is an object. For updates it maps each changed field to its old and new value: {"status": ["todo", "in_progress"], "assignee_agent_id": [null, "…"]}. Values that are not JSON types (ids, dates) are stored as strings. A few entries use other shapes:

Entrychanges
Agent paused for budget (actor system){"reason": "budget", "spent_cents": 12137}
Run started{"runner_id": "my-mac:4242"}
Run finished by a runner's reportThe run fields that changed, as [old, new] pairs, for example status, cost_cents, summary
Run cancelled through POST /runs/{run_id}/cancel{"status": ["running", "cancelled"]} (or from queued)
Run expired, or cancelled by terminating its agent{"error": "…stopped reporting (lease expired)"} or {"error": "Agent terminated"}
Approval approved or rejected{"note": "One-off spike"} when a note was given
Create, delete, trigger, queue{}

Fields

AuditOut:

Prop

Type

Use it

The Activity screen listing entries such as "Demo Board queued Grace · manual" and "system succeeded Grace · running → succeeded", each with a relative time, and an Everything filter at the top right

Open Activity. Each line reads "actor verb object · detail", for example "Demo Board moved NF-5 Auth: email + Google sign-in · in progress → in review". For status changes the detail shows old → new; for other updates it lists the changed field names. Select the object to open it (tasks, agents, runs and projects link to their pages; approvals link to the approvals screen).

  • The filter at the top right limits the list to one entity type (Task, Agent, Run, Approval, Goal, Project, Routine, Company) and is kept in the URL as ?type=task.
  • The list shows 50 entries; Load older fetches the next 50.
  • Agent pages have an Activity tab with the same feed for that agent, and the dashboard's Recent activity card shows the latest 12.

Permissions

Any member can read the whole activity log. Nobody can edit or delete entries through the API. Non-members get 404 NOT_FOUND.

Events

Reading the log publishes nothing. Every entry corresponds to a change that also publishes an event (see each feature page), and the web app refreshes the activity feed on every live event.

Limits and known gaps

  • No retention policy is implemented. Entries are kept forever; there is no purge, archive or export.
  • Paging uses created_at with a strict "older than" comparison. Entries that share the exact same timestamp across a page boundary can be skipped.
  • A run's queued entry is attributed to the member whose credentials queued it, even when the scheduler or a task assignment caused it.
  • Cancelling a run is recorded as system with verb cancelled, not as the person who cancelled it.
  • Only task changes can be attributed to an agent. Other writes a runner makes (for example run reports) appear as system or as the credential's owner.
  • The CLI, the web app and the API filter by one entity type at a time; there is no filter by actor, verb or date range other than before.
  • entity_label and actor_name are snapshots and go stale after renames.

On this page