---
id: ATS-PFM-MTD-014
scope: CAP-PFM-MTD-014
product_area: platform
module: metadata
revision: 2
status: proposed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-MTD-014-01
    title: The timeline identifies committed changes and authors
    level: browser
    proves:
      - BR-CAP-PFM-MTD-014-01
    preconditions: 'A boat has creation, edit, relationship and lifecycle changes.'
    steps:
      - do: Read its timeline and open the console history.
        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
    expected: Changes appear newest first with their authors and revision descriptions.
    negative: false
    data_needs: 'A boat has creation, edit, relationship and lifecycle changes.'
    bound_to:
      - >-
        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
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#presents
        each item in the shape of the contract’s RevisionSummary, by the console user who made it
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S07.spec.ts#PLAT-M5-S07: publish,
        archive and restore from the boat page; History names each revision and who made it
      - TST-PFM-MTD-057
      - TST-PFM-MTD-007
    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
    category: rule
    assertions:
      - expect: Changes appear newest first with their authors and revision descriptions.
        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
  - id: ATS-PFM-MTD-014-02
    title: Revision detail follows recognizable field groups
    level: api
    proves:
      - BR-CAP-PFM-MTD-014-02
    preconditions: 'A revision changes grouped properties, list values and ownership.'
    steps:
      - do: Read the revision detail.
        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
    expected: >-
      Sections follow form grouping, values use labels and before-and-after information, and ownership uses
      the reverse relationship label.
    negative: false
    data_needs: 'A revision changes grouped properties, list values and ownership.'
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#presents
        the property groups as sections in the boat form’s order, under the groups’ names
      - >-
        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
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#names
        a list value by its option’s label
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#names
        the owner’s association by the type’s reverse label and the contact
      - TST-PFM-MTD-057
    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
    category: rule
    assertions:
      - expect: >-
          Sections follow form grouping, values use labels and before-and-after information, and ownership
          uses the reverse relationship label.
        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
  - id: ATS-PFM-MTD-014-03
    title: History access remains separate from record reading
    level: api
    proves:
      - BR-CAP-PFM-MTD-014-03
    preconditions: 'Readers lack history, reach another object or inspect a deleted boat.'
    steps:
      - do: Request history under each grant.
        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
    expected: >-
      Missing history permission fails, wrong-object reach is hidden and deleted-record history remains
      readable with history permission.
    negative: true
    data_needs: 'Readers lack history, reach another object or inspect a deleted boat.'
    bound_to:
      - >-
        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
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers
        404 to a caller whose assignments reach only another object
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers
        a deleted boat’s history from its revisions, saying it is deleted
      - TST-PFM-MTD-057
    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
    category: permission
    assertions:
      - expect: >-
          Missing history permission fails, wrong-object reach is hidden and deleted-record history remains
          readable with history permission.
        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
  - id: ATS-PFM-MTD-014-04
    title: Archived objects keep their history surfaces
    level: api
    proves:
      - BR-CAP-PFM-MTD-014-04
    preconditions: An archived custom object has record revisions.
    steps:
      - do: 'Read timeline, revision detail and actors.'
        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
    expected: All three histories remain available.
    negative: false
    data_needs: An archived custom object has record revisions.
    bound_to:
      - >-
        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
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#answers
        one revision of a record of an archived object
      - >-
        services-platform:modules/custom-objects/tests/integration/services/history/custom-object-record-history.integration.spec.js#lists
        the actors of a record of an archived object
      - TST-PFM-MTD-057
    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
    category: transition
    assertions:
      - expect: All three histories remain available.
        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
  - id: ATS-PFM-MTD-014-05
    title: Merge revisions retain the prior reference
    level: api
    proves:
      - BR-CAP-PFM-MTD-014-06
    preconditions: A custom record refers to a duplicate contact.
    steps:
      - do: Merge it into the survivor and read the custom-record revision.
        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
    expected: The reference moves and history retains the former value with the survivor afterwards.
    negative: false
    data_needs: A custom record refers to a duplicate contact.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/integration/db/custom-object-records-merge.integration.spec.js#keeps
        the old value and shows the survivor, as one update
      - >-
        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
      - TST-PFM-MTD-053
    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
    category: interaction
    assertions:
      - expect: The reference moves and history retains the former value with the survivor afterwards.
        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
  - id: ATS-PFM-MTD-014-06
    title: Relationship history is captured on its applicable endpoints
    level: api
    proves:
      - BR-CAP-PFM-MTD-014-05
      - BR-CAP-PFM-MTD-014-01
    preconditions: A contact and custom record are linked.
    steps:
      - do: Change the link and inspect their captured revisions.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#writes
          the association on the contact, a native from record, under its own record type
    expected: >-
      The starting endpoint and applicable custom endpoint histories record the change; CRM drawer integration
      remains deferred.
    negative: false
    data_needs: A contact and custom record are linked.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#writes
        the association on the contact, a native from record, under its own record type
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#mirrors
        the association on the boat, a custom to record, as its reverse association
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#records
        a re-pointed from record as a removal on the contact it left and an addition on the one it joined
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#writes
        no revision for a save that changed nothing
      - TST-PFM-MTD-070
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#writes
      the association on the contact, a native from record, under its own record type
    category: interaction
    assertions:
      - expect: >-
          The starting endpoint and applicable custom endpoint histories record the change; CRM drawer
          integration remains deferred.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/integration/services/persistence/record-revisions.integration.spec.js#writes
          the association on the contact, a native from record, under its own record type
  - id: ATS-PFM-MTD-014-07
    title: A merge updates references and retained history under history reach
    category: interaction
    level: api
    exercises:
      - CAP-PFM-MTD-014
      - CAP-PFM-MTD-011
      - CAP-PFM-MTD-012
      - CAP-PFM-MTD-018
      - CAP-PFM-MTD-019
    proves:
      - BR-CAP-PFM-MTD-014-06
      - BR-CAP-PFM-MTD-014-03
      - BR-CAP-PFM-MTD-019-08
    preconditions: A custom record names a duplicate contact and has an attributed revision.
    steps:
      - do: >-
          Merge the contact, read the record and revision with history permission and repeat the history
          request without that permission.
        provenance: proposed
        source: &ref_0
          - >-
            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
          - >-
            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
          - >-
            services-platform:modules/custom-objects/tests/integration/db/custom-object-records-merge.integration.spec.js#names
            the surviving contact in every property that named a merged one
    expected: 'Compare the survivor value, prior reference and history refusal.'
    negative: false
    data_needs: A custom record names a duplicate contact and has an attributed revision.
    bound_to: []
    provenance: proposed
    source: *ref_0
    assertions:
      - expect: 'Compare the survivor value, prior reference and history refusal.'
        provenance: proposed
        source: *ref_0
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: the history and merge specs named in each
    scenario.
  - 'react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: Playwright PLAT-M5-S07.'
  - >-
    Codex testing back-fill: pinned capability, domain object, state model and workflow obligations reviewed;
    existing bound test files and exact case titles checked.
coverage:
  rule: covered
  transition: covered
  validation: 'gap: FND-PFM-MTD-076'
  permission: covered
  edge: 'gap: FND-PFM-MTD-076'
  failure: 'gap: FND-PFM-MTD-076'
  boundary: 'gap: FND-PFM-MTD-076'
  concurrency: 'gap: FND-PFM-MTD-076'
  invariant: 'gap: FND-PFM-MTD-076'
  interaction: covered
coverage_obligations:
  - rule: BR-CAP-PFM-MTD-014-01
    scenarios:
      - ATS-PFM-MTD-014-01
      - ATS-PFM-MTD-014-06
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-02
    scenarios:
      - ATS-PFM-MTD-014-02
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-03
    scenarios:
      - ATS-PFM-MTD-014-03
      - ATS-PFM-MTD-014-07
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-04
    scenarios:
      - ATS-PFM-MTD-014-04
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-05
    scenarios:
      - ATS-PFM-MTD-014-06
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-06
    scenarios:
      - ATS-PFM-MTD-014-05
      - ATS-PFM-MTD-014-07
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-07
    scenarios: []
    finding: FND-PFM-MTD-076
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - rule: BR-CAP-PFM-MTD-014-08
    scenarios: []
    finding: FND-PFM-MTD-076
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
interactions:
  - with: CAP-PFM-MTD-011
    scenarios:
      - ATS-PFM-MTD-014-07
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
  - with: CAP-PFM-MTD-018
    scenarios:
      - ATS-PFM-MTD-014-07
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-014-see-every-change-to-a-custom-record-and-who-made-it.md
---

# Explain Custom Record Changes: Capability Test Specification

## Coverage

- Obligation 01: 2 scenarios cite this obligation.
- Obligation 02: 1 scenario cite this obligation.
- Obligation 03: 2 scenarios cite this obligation.
- Obligation 04: 1 scenario cite this obligation.
- Obligation 05: 1 scenario cite this obligation.
- Obligation 06: 2 scenarios cite this obligation.
- Obligation 07: The coverage finding records the missing scenario.
- Obligation 08: The coverage finding records the missing scenario.

Category coverage identifies the kind of proof present. Detailed transition, permission and invariant obligations and unbound proposals remain in the coverage finding until their individual cases are accounted for.

## Interactions With Related Capabilities

Reference movement remains explainable without weakening history access. The structured interaction rows identify the related capabilities exercised and any remaining gap. Cross-capability workflow seams remain subject to the detailed coverage audit.
