Inspect a record’s changes over time
Purpose
Staff investigating a discrepancy need to understand what changed, who changed it, and which source performed the work. This capability presents attributed revisions of contacts and organizations without turning history into another editable record. It preserves useful evidence after deletion and distinguishes inspection of the past from restoring an earlier version.
How It Works
A changed save commits one revision containing old and new field values and the record's contemporaneous name. An unchanged save contributes no revision. The capture requires actor and source attribution; an unattributed change fails together with its attempted revision rather than leaving an unexplained write.
History reads use separate authority and reach rules. Live records require access to the record, while deleted-record history can use the history permission and identifies deletion. Pages are newest first with stable cursors and supported filters. Details group contact, affiliation, role, communication, and custom-value changes into readable sections, resolving appropriate labels while hiding excluded captured fields.
Actor display uses the current name, including former users, with a captured fallback. Source identifies the channel or process. Merged-away contact routes direct callers to the survivor's retained history path. Revisions are read-only to the application and survive parent deletion until workspace purge; they do not provide a restore action.
Example
A coordinator investigates why Ruth's title and work phone differ from last week. The history page shows a grouped revision identifying the editor and source, with old and new values for the changed sections. An unchanged round-trip save adds no distracting entry. If the contact is later deleted, an authorized history reader can still inspect retained revisions marked with the record's deleted state.
For Ruth's investigation, the coordinator filters revisions by the relevant date range and follows the returned continuation cursor rather than assuming the first page is the complete history. The old and new title values explain the correction, while the displayed actor can use the person's current name. A relationship label likewise does not certify a historical snapshot of every related name. If Ruth is later merged into another contact, the absorbed identity points to its survivor and the supported survivor path exposes retained history. If she is deleted instead, retained history has its deleted-record access boundary; neither route reconstructs a live Ruth record.
Why It Works This Way
Our reading is that a single revision per changed aggregate connects related edits without requiring staff to reconstruct one save from many independent entries. Commit-time capture protects the agreement between live data and its explanation. Fail-closed attribution prevents a successful write from becoming unauditable, and application read-only access prevents rewriting that account afterwards.
Separate history authority recognizes that earlier values can disclose information beyond an ordinary present-day read. Retention without a parent foreign key prevents deletion from erasing its own evidence. Readable labels and grouped sections make changes interpretable, while contemporaneous record names preserve context when the live name changes. Current actor names and captured fallbacks support recognition without claiming every label is a historical snapshot.
Relationships
Record saves, archive, deletion, and system changes supply the committed differences. Platform identity supplies user display information, and Platform metadata supplies field labels used in presentation. Data Quality supplies merge survivors and retained absorbed-contact access. Workspace lifecycle owns purge. This capability presents captured revisions; it does not own a rollback workflow or allow callers to insert revisions.