---
id: CAP-PFM-MTD-014
title: Explain Custom Record Changes
feature: FEAT-PFM-MTD-05
product_area: platform
module: metadata
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-CO-XAP-011
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/milestones/PLAT-M5-custom-records.md#Scope (audit and record history), PLAT-M5 D3'
  - 'services-platform:docs/milestones/plans/PLAT-M5-plan.md#PLAT-M5-S07'
  - 'services-platform:docs/record-history.md'
purpose: >-
  Readers need to understand corrections and lifecycle actions without reconstructing them from current
  values. Transactional history supplies that account.
outcomes:
  - >-
    Readers need to understand corrections and lifecycle actions without reconstructing them from current
    values.
  - Deleted or archived-object records can retain readable history.
actors:
  - ACT-PFM-009
  - ACT-PFM-012
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: platform.custom-records.history
    where_checked: api
    scope: record
  - key: platform.custom-records.read
    where_checked: service
    scope: record
rules:
  - id: BR-CAP-PFM-MTD-014-01
    proved_by: [ATS-PFM-MTD-012-18, ATS-PFM-MTD-013-10, ATS-PFM-MTD-014-01, ATS-PFM-MTD-014-06, ATS-PFM-MTD-019-10, TST-PFM-MTD-007, TST-PFM-MTD-057, TST-PFM-MTD-070]
    statement: >-
      Committed record, value and relationship changes capture author, time, source and before-and-after
      fields in transactional history, while unchanged business values create no revision.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers
      the association, the update and the creation, newest first
    origin: none
  - id: BR-CAP-PFM-MTD-014-02
    proved_by: [ATS-PFM-MTD-014-02, TST-PFM-MTD-057]
    statement: >-
      Revision presentation follows form sections and property labels, resolves option labels, includes
      composed names and labels relationship changes from the relevant side.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#names
      each changed property by its label, with its values before and after as the drawer shows them
    origin: none
  - id: BR-CAP-PFM-MTD-014-03
    proved_by: [ATS-PFM-MTD-011-08, ATS-PFM-MTD-014-03, ATS-PFM-MTD-014-07, TST-PFM-MTD-057]
    statement: >-
      History requires its own permission and object reach, additionally checks record read access while the
      record exists and permits deleted-record history under history access.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#refuses
      a caller who may read boats but not their history
    origin: none
  - id: BR-CAP-PFM-MTD-014-04
    proved_by: [ATS-PFM-MTD-014-04, TST-PFM-MTD-057]
    statement: 'Archived object records retain readable timelines, individual revisions and actor lists.'
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers
      the timeline of a record of an archived object
    origin: 'services-platform:docs/milestones/PLAT-M5-custom-records.md#PLAT-M5 D3'
  - id: BR-CAP-PFM-MTD-014-05
    proved_by: [ATS-PFM-MTD-014-06, ATS-PFM-MTD-018-13, TST-PFM-MTD-070]
    statement: >-
      Link changes enter the starting record history and the other endpoint history when it is a custom
      record; CRM endpoint revisions are stored in Platform and remain absent from the CRM drawer.
    kind: policy
    enforced_at:
      - database
    must_prove: true
    provenance: documented
    source: 'services-platform:docs/associations.md#7a. History'
    origin: none
  - id: BR-CAP-PFM-MTD-014-06
    proved_by: [ATS-PFM-MTD-014-05, ATS-PFM-MTD-014-07, TST-PFM-MTD-053]
    statement: >-
      CRM merge changes to custom records capture one revision per transaction, including reference values
      before the move and the surviving contact afterwards.
    kind: policy
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/db/custom-object-records-merge.integration.spec.js#attributes
      the change to the merge: its source, its actor and its merge id
    origin: 'services-platform:docs/milestones/plans/PLAT-M6-plan.md#5. D4 (Andrew, 2026-10-21: move to survivor)'
  - id: BR-CAP-PFM-MTD-014-07
    proved_by: []
    statement: >-
      History supports actor, operation, source and date filters, rejects unsupported parameters and remains
      until authorized workspace lifecycle purging removes it.
    kind: policy
    enforced_at:
      - api
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/e2e/custom-object-record-history.e2e.spec.js#refuses a
      query parameter the timeline does not take
    origin: none
  - id: BR-CAP-PFM-MTD-014-08
    proved_by: []
    statement: >-
      Revision presentation includes only properties available in the current description and admitted by the
      caller’s audience, so archived property values remain retained but undisplayed.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-platform:modules/custom-objects/history/custom-object-record-history.config.ts:presentationOf
    origin: none
scenarios:
  - id: SC-CAP-PFM-MTD-014-01
    given: 'A boat has creation, edit and ownership revisions.'
    when: Open the timeline.
    then: 'Ownership, editing and creation appear from most recent to earliest, each with its author.'
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/e2e/custom-object-record-history.e2e.spec.js#answers the
      boat’s timeline, its patch and its creation newest first
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-MTD-012
related:
  - CAP-PFM-MTD-011
  - CAP-PFM-MTD-018
journeys:
  - JNY-PFM-MTD-002
open_questions:
  - OQ-PFM-MTD-003
concepts:
  - CON-PFM-MTD-005
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1:
    modules/custom-objects/aws/api/custom-object-record-history.routes.ts ,
    history/custom-object-record-history.config.ts, services/persistence/record-revisions.ts,
    db/record-revisions.table.ts, custom-object-record-change-events.table.ts;
    modules/associations/history/association-history.config.ts, db/association-change-events.table.ts; tests
    e2e/custom-object-record-history.e2e.spec.js,
    integration/services/history/custom-object-record-history.integration.spec.js,
    integration/services/persistence/record-revisions*.integration.spec.js,
    unit/custom-object-record-history.config.spec.ts; docs/record-history.md, docs/custom-objects.md §24.
  - >-
    react-console at baf6dae382d6f41dce976c7f848667ccc37e076f:
    components/console/custom-objects/custom-record-screen.tsx ; Playwright PLAT-M5-S07.
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-003, TC-DAT-004, TC-LOG-002, TC-LOG-003, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-MTD-05-03, FAS-PFM-MTD-05-04]
suites: [TST-PFM-MTD-007, TST-PFM-MTD-053, TST-PFM-MTD-057, TST-PFM-MTD-070]
---

# Explain Custom Record Changes

## Purpose

Readers need to understand corrections and lifecycle actions without reconstructing them from current values. Transactional history supplies that account.

## How It Works

A reader opens the record history using its separate permission. The service checks access to the object and the existing record. It returns a timeline ordered from recent to earlier changes. Opening a revision groups changed information as staff recognize it in the form. Field and option labels make the values understandable. Deleted or archived-object records can retain readable history. CRM endpoint link changes are also captured by Platform, but the CRM drawer does not currently combine them with its own timeline.

## Relationships

Record saves and relationship changes supply revisions. Object descriptions supply labels and grouping, while Security governs readership.
