ResearchOS
/Wiki

Audit log

Every lab-head change to a record is recorded as one row per changed field in that record's audit file. The audit trail is the read-only history of those changes. Open it from the Audit trail button, or per record from the lab-head menu, to see who changed what, when, and what the value was before and after.

The Audit trail viewer. Each row is one field change, with the before and after values shown inline.

How to open it

Click Open audit trail in the Audit trail section of Settings, or choose View audit trail in the lab-head menu on any member record. The viewer opens as a popup. If no target member is selected, the viewer shows a member picker first; select a member to load their trail. The viewer is read-only. Nothing you do in it changes any record.

What each row records

Each audit entry corresponds to one field change in one record. A single save that touches three fields writes three entries. Here is what each entry contains.

  • actor: the lab head username who made the edit.
  • target_user: the member whose record was changed.
  • record_type: a string identifying the kind of record, for example task, note, or purchase_item.
  • record_id: the numeric or string id of the specific record that was changed.
  • field_path: a dot-separated path through the record shape identifying which field changed, for example name, assigned_to, or sub_tasks.0.title.
  • old_value: the value before the change.
  • new_value: the value after the change.
  • session_id: a synthetic grouping id stamped on related entries from the same action, for example lab-head-action. Not a timed session, just a label that connects rows that came from the same operation.
  • timestamp: ISO 8601 UTC.

Where the file lives

Soft-write edits to a member's records are written to users/<member>/_pi_audit.json inside that member's folder. Announcement writes (post, edit, delete) go to a separate _pi_audit.json at the lab folder root, because announcements are lab-scoped rather than owned by any single member.

Both files use the same entry schema. The viewer reads the per-user file for member record edits. The files are append-only on the write side. The reader is free to sort and filter.

Forensic use cases

  • A purchase shows up as approved and the member wants to confirm who signed off and when. Filter by record_type: purchase_item and the approved field path.
  • A task was reassigned and the original assignment needs to be confirmed. Look for the assigned_to field path on the relevant task id.
  • A note was edited by the lab head and the original text needs to be recovered. The old_value on the body field carries the pre-edit text verbatim.