Docs · Guides

Workspace activity

The Activity tab (/workspace/activity) shows an append-only feed of meaningful changes in the active organization: who did what, on which entity, and when.

Who can see it

Only owners and admins can open the feed. Members and viewers see the standard permission message and the API returns 403.

What is recorded

Each successful domain mutation emits one event per HTTP request, for example:

  • Projects, suites, and test cases (create, update, move, archive, delete)
  • Custom fields and bundled test-case edits (one test_case.updated when a PATCH changes fields, steps, or values together)
  • Members, invitations, and API tokens
  • Test runs — create, update, close (including automatic close once every case has a result), abort, delete, clone (“Run again”), add/remove cases, mark cases and steps, assignees, retries, actual-result text edits, and result attachments

Events are stored forever in this release.

Filtering the feed

Use Add filter above the timeline to narrow the organization feed:

  • Actor filters to events performed by one organization member. Events whose user was later deleted remain in the feed, but they do not match a member actor filter.
  • Entity type filters by the kind of object that changed, such as project, test run, defect, custom field, member, invitation, or API token. Select more than one entity type to OR them together.

Filters are reflected in the URL, so owners and admins can share a narrowed activity view. Changing filters reloads the feed from the newest matching event; use Clear filters to return to the full timeline.

Run activity in the feed

Run events use snapshotted labels so the timeline stays readable even if a case is renamed or deleted later.

What happenedWhat you see
Run createdCase count plus optional environment, default assignee, and milestone
Run updatedCollapsible diff for name, description, default assignee, environment, or milestone
Run closedFinal scorecard (passed / failed / blocked / skipped / untested counts, total duration, projected pass/fail). Renders the same whether the run closed automatically (every case got a result) or via Complete.
Run deletedRun name (plain text, no link), final scorecard, and whether it was open or closed at deletion
Actual result editedStep context with from → to text diff on the live execution path
Run cloned (“Run again”)Source run name and the new run’s name/label
Cases addedHow many cases were appended (up to 20 named in the payload)
Case markedLinked case label (PROJECT-42 · Title), status chip from → to, optional elapsed time
Step markedCase link, step position/action, status chip, case-level status after the mark
Case assignedWho assigned whom (including auto-assign on open vs manual patch)
Case retriedPrior status reset to untested and elapsed time cleared when applicable
Case removedCase identity and status at removal
Bulk mark / assign / retry / removeOne row per gesture with count, first few case IDs, and an expandable per-case diff (status chips, assignee transitions, or removal status)
Bulk submit resultOne row per gesture: status, count, first few case IDs, and an expandable per-case status diff (same shape as bulk mark) — split time and any attached defect are not shown in the diff itself
Attachment committed/deletedCase, step, and filenames

Case links open the run execution view when the run still exists; deleted runs fall back to plain text labels.

Activity inside a run

Each run execution view (/projects/{project}/runs/{run}) includes an Activity tab next to Test cases. It shows the same day-grouped timeline and diff primitives as the workspace feed, but scoped to that run only.

SurfaceWho can open itAPI
Workspace ActivityOwners and adminsGET /api/v1/orgs/{orgUlid}/audit-events
Run Activity tabAny role that can read the run (viewer+)GET /api/v1/runs/{runUlid}/audit-events

The tab persists in the URL as ?tab=activity so deep links and the browser back button restore the selection. On a closed run the Test cases tab is read-only, but Activity continues to show the full history. Run links inside the tab are omitted because you are already inside that run.

Timeline layout

The feed is a day-grouped timeline:

  • Events are grouped under sticky day headers (Today, Yesterday, or an absolute date) with a per-day count.
  • A vertical rail connects round actor avatars within each day.
  • Each avatar shows a small action-type badge (create, update, move, or delete) derived from the event action.

Use the footer (showing N events · load more) to page through older entries. Appending a page does not duplicate a day header when new events belong to a day already on screen.

Change details (diff)

Events of type *.updated, *.moved, and member.role_changed carry a structured diff that describes which fields changed and what they changed to:

  • All changes (including a single field) appear in one collapsible group labeled with a zero-padded count and the word change or changes by count (e.g. 01 change, 03 changes). Expand it to see one row per field with the previous value (muted, strikethrough) and the new value (accent-soft, monospace).
  • Null values render as Not set without strikethrough.
  • Long values: strings are truncated to 240 characters and a See more button reveals the full snapshot saved at the moment of the change.
  • Case steps: when a consolidated save changes steps, the feed shows a detailed per-step diff inside the same change group — one row per touched step with a verdict (Added, Removed, Modified, Reordered), field-level from → to lines for action/data/expected (same neutral styling and See more truncation as scalar fields), position moves, and image add/remove by filename. Historical events may still show the legacy count-only row (Steps: 3 → 5). If more than 20 steps change at once, the first 20 rows appear plus a summary line for the rest (totals by verdict stay accurate).
  • Custom field definitions: custom_field.updated records every mutable part of the definition — scalar properties (title, placeholder, Required, default value) as from → to rows, plus phrase-style lines for project visibility (shown in all projects, switched to specific projects, no projects (same copy as the custom-fields table) when scope is left empty, or added/removed per project with snapshotted project names) and option list edits (added, removed, renamed options with snapshotted names). Pure option reorder still uses the separate custom_field.options_reordered action without option lines. Field and reference names are snapshots from emission time, even if later renamed or deleted.
  • Milestone, environment, and defect edits: milestone.updated, environment.updated, and defect.updated carry the same field-level diff as other updates. A milestone shows name, description, dates (start, due, and forecast), and parent milestone by name; status changes — a manual edit or automatic completion — record the status from → to. An environment shows name, slug, description, URL, and the Default flag. A defect shows its assignee and milestone by name. These reference fields render the human-readable label snapshotted at the moment of the change, never the internal id.

Non-update events (*.created, *.deleted, *.archived, *.restored) keep showing their descriptive template without a change group.

Actor types

ActorHow it appears
UserRound initials avatar and display name or email local-part
API tokenKey icon and the token name you chose at creation
SystemNeutral icon and label “System”

If a user or token is deleted later, older events stay in the feed with “Deleted user” / “Deleted token”.

Integrators can read the same data with GET /api/v1/orgs/{orgUlid}/audit-events. See Audit events API.