---
id: ATS-PFM-MTD-018
scope: CAP-PFM-MTD-018
product_area: platform
module: metadata
revision: 2
status: proposed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-MTD-018-01
    title: Creating links validates both endpoints
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-01
    preconditions: Registered types and compatible records exist.
    steps:
      - do: 'Use an unknown type, missing or foreign endpoint, self-link and a route-supplied endpoint.'
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          a record associated with itself
    expected: Invalid cases fail and the route-supplied counterpart creates a valid link.
    negative: true
    data_needs: Registered types and compatible records exist.
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a type the tenant does not have
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a from record that does not exist, writing nothing
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a record of another tenant, which the tenant policy never lets the seam see
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a record associated with itself
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#creates the association with
        the path’s contact as its from side, without the write path’s keys
      - TST-PFM-MTD-045
      - TST-PFM-MTD-036
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
      a record associated with itself
    category: validation
    assertions:
      - expect: Invalid cases fail and the route-supplied counterpart creates a valid link.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          a record associated with itself
  - id: ATS-PFM-MTD-018-02
    title: Future endings retain the occupied place
    level: browser
    proves:
      - BR-CAP-PFM-MTD-018-02
      - BR-CAP-PFM-MTD-018-03
    preconditions: A charter occupies Osprey until a future date.
    steps:
      - do: >-
          Book overlaps from today and the inclusive end date, then an adjacent booking and inspect after
          expiry.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
          a second link of a one-place type that starts today, naming the link whose end date has not passed
    expected: 'Overlaps fail, the adjacent span succeeds and the current place becomes free after the end date.'
    negative: true
    data_needs: A charter occupies Osprey until a future date.
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
        a second link of a one-place type that starts today, naming the link whose end date has not passed
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
        a link starting on the end date itself, the end date being inclusive
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#allows
        the next link from the day after the end date
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#frees
        the place on the day after an end date that has passed
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S06.spec.ts#PLAT-M6-S06: a charter
        ending next month still holds Osprey and a second charter from today is refused naming the first
      - TST-PFM-MTD-044
      - TST-PFM-MTD-020
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
      a second link of a one-place type that starts today, naming the link whose end date has not passed
    category: boundary
    assertions:
      - expect: 'Overlaps fail, the adjacent span succeeds and the current place becomes free after the end date.'
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
          a second link of a one-place type that starts today, naming the link whose end date has not passed
  - id: ATS-PFM-MTD-018-03
    title: Overlapping spans cannot share restricted places
    level: browser
    proves:
      - BR-CAP-PFM-MTD-018-03
      - INV-DOM-PFM-MTD-006-04
    preconditions: 'Pair, cardinality and primary fixtures contain existing links.'
    steps:
      - do: 'Add overlapping, adjacent, unbounded and competing primary links through API and console.'
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
          a second link of one pair whose dates overlap the first, leaving the first alone
    expected: >-
      Conflicts identify the existing place, adjacent spans succeed and the console saves no conflicting
      insurer.
    negative: true
    data_needs: 'Pair, cardinality and primary fixtures contain existing links.'
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
        a second link of one pair whose dates overlap the first, leaving the first alone
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#allows
        a second link of one pair that starts the day after the first ends
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#reads
        a null start as from the beginning: an undated link overlaps one that ended in the past
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a second open owner of a one-to-many type’s to record, naming it
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
        two primaries of one from record whose dates overlap, and allows them when the dates do not
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S04.spec.ts#PLAT-M6-S04: a second
        insurer for Osprey is refused naming the first, and nothing is saved
      - TST-PFM-MTD-044
      - TST-PFM-MTD-045
      - TST-PFM-MTD-018
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
      a second link of one pair whose dates overlap the first, leaving the first alone
    category: invariant
    assertions:
      - expect: >-
          Conflicts identify the existing place, adjacent spans succeed and the console saves no conflicting
          insurer.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
          a second link of one pair whose dates overlap the first, leaving the first alone
  - id: ATS-PFM-MTD-018-04
    title: Concurrent occupancy remains exclusive
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-04
      - INV-DOM-PFM-MTD-006-05
    preconditions: A one-place relationship exists.
    steps:
      - do: Race overlapping creates and separately race adjacent spans.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
          one of two writers of overlapping links of one pair, as a refusal and not a database error
    expected: Only one conflicting writer succeeds while adjacent writers can both succeed.
    negative: true
    data_needs: A one-place relationship exists.
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#leaves
        the boat with one open owner when two owners are written at once
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
        one of two writers of overlapping links of one pair, as a refusal and not a database error
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#lets
        two writers of adjacent links of one place both succeed
      - TST-PFM-MTD-045
      - TST-PFM-MTD-044
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
      one of two writers of overlapping links of one pair, as a refusal and not a database error
    category: concurrency
    assertions:
      - expect: Only one conflicting writer succeeds while adjacent writers can both succeed.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#refuses
          one of two writers of overlapping links of one pair, as a refusal and not a database error
  - id: ATS-PFM-MTD-018-05
    title: Dates and primary flags depend on the type
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-05
    preconditions: Dated and undated types vary in primary support.
    steps:
      - do: 'Submit forbidden dates, a reversed span, an invalid calendar day and a forbidden primary.'
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          an end before the start on a dated type
    expected: Every unsupported input fails.
    negative: true
    data_needs: Dated and undated types vary in primary support.
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        dates on an undated type
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        an end before the start on a dated type
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a date that is not a calendar day
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a primary on a type that has none
      - TST-PFM-MTD-045
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
      an end before the start on a dated type
    category: validation
    assertions:
      - expect: Every unsupported input fails.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          an end before the start on a dated type
  - id: ATS-PFM-MTD-018-06
    title: Link correction cannot replace endpoints
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-06
      - INV-DOM-PFM-MTD-006-06
    preconditions: A stored link has a current version.
    steps:
      - do: 'Replace an endpoint, correct notes and repeat with a stale version.'
        provenance: test
        source: >-
          services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a
          replacement that names another record
    expected: Endpoint replacement and stale changes fail while valid notes change.
    negative: true
    data_needs: A stored link has a current version.
    bound_to:
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a replacement
        that names another record
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#replaces the notes of the
        association read back, at its version
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        a stale version and leaves the association as it was
      - TST-PFM-MTD-036
      - TST-PFM-MTD-045
    provenance: test
    source: >-
      services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a replacement
      that names another record
    category: invariant
    assertions:
      - expect: Endpoint replacement and stale changes fail while valid notes change.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 400 to a
          replacement that names another record
  - id: ATS-PFM-MTD-018-07
    title: Ending uses valid dated spans
    level: browser
    proves:
      - BR-CAP-PFM-MTD-018-07
    preconditions: 'Open, expired and undated links exist.'
    steps:
      - do: 'End with default or explicit days, an invalid earlier day, an expired link and an undated type.'
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          an end before the association started, leaving it open
    expected: >-
      Valid dated endings are stored, invalid and unsupported endings fail, and ended links appear in
      historical browsing.
    negative: true
    data_needs: 'Open, expired and undated links exist.'
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#ends
        an open association of a dated type today in the tenant’s zone when no day is given
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        an end before the association started, leaving it open
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        to end an association that already ended
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        to end an association of an undated type
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S05.spec.ts#PLAT-M6-S05: an ended
        crew place shows under Show Ended with its dates and a mistaken entry leaves no history
      - TST-PFM-MTD-045
      - TST-PFM-MTD-019
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
      an end before the association started, leaving it open
    category: transition
    assertions:
      - expect: >-
          Valid dated endings are stored, invalid and unsupported endings fail, and ended links appear in
          historical browsing.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          an end before the association started, leaving it open
  - id: ATS-PFM-MTD-018-08
    title: Removal distinguishes open and historical links
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-08
    preconditions: 'Open dated, end-dated and undated links exist.'
    steps:
      - do: Remove each link.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#removes
          a link that has an end date when it is deleted, correcting history, and ends one with none
    expected: The open dated link ends today and the other links are deleted.
    negative: false
    data_needs: 'Open dated, end-dated and undated links exist.'
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#ends,
        rather than deletes, an open association of a dated type
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#deletes
        an ended association of a dated type, correcting its history
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#deletes
        an association of an undated type
      - TST-PFM-MTD-045
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#removes
      a link that has an end date when it is deleted, correcting history, and ends one with none
    category: transition
    assertions:
      - expect: The open dated link ends today and the other links are deleted.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#removes
          a link that has an end date when it is deleted, correcting history, and ends one with none
  - id: ATS-PFM-MTD-018-09
    title: Link limits include history
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-09
      - INV-DOM-PFM-MTD-006-07
    preconditions: A record already holds one thousand links of a type.
    steps:
      - do: Create another link.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          an association past the per-record limit of the type, writing nothing
    expected: Creation fails and historical links count toward the limit.
    negative: true
    data_needs: A record already holds one thousand links of a type.
    bound_to:
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
        an association past the per-record limit of the type, writing nothing
      - >-
        services-platform:modules/associations/tests/integration/services/persistence/associations.in-force.integration.spec.js#counts
        the links in force and the ended ones together against the per-record limit
      - TST-PFM-MTD-045
      - TST-PFM-MTD-044
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
      an association past the per-record limit of the type, writing nothing
    category: boundary
    assertions:
      - expect: Creation fails and historical links count toward the limit.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
          an association past the per-record limit of the type, writing nothing
  - id: ATS-PFM-MTD-018-10
    title: Both endpoint pages show the connection
    level: browser
    proves:
      - BR-CAP-PFM-MTD-018-10
    preconditions: 'Contact, organization and custom-record relationships exist.'
    steps:
      - do: List from both directions and refresh each relevant console page.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the
          organization’s path in the reverse direction, naming the contact
    expected: Directional labels and opposite names appear locally and another workspace sees none of the links.
    negative: false
    data_needs: 'Contact, organization and custom-record relationships exist.'
    bound_to:
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the
        organization’s path in the reverse direction, naming the contact
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the contact’s
        path in the forward direction, naming the organization
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists nothing of the tests
        tenant to a context of the other tenant, which the path cannot reach
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S03.spec.ts#PLAT-M6-S03: a
        registrar adds Tom as crew of Osprey and Tom's page lists Osprey after a refresh
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S10.spec.ts#PLAT-M6-S10: a boat
        and its mooring are linked and each page shows the other
      - TST-PFM-MTD-036
      - TST-PFM-MTD-017
      - TST-PFM-MTD-024
    provenance: test
    source: >-
      services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the organization’s
      path in the reverse direction, naming the contact
    category: interaction
    assertions:
      - expect: Directional labels and opposite names appear locally and another workspace sees none of the links.
        provenance: test
        source: >-
          services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#lists it on the
          organization’s path in the reverse direction, naming the contact
  - id: ATS-PFM-MTD-018-11
    title: Link actions respect staff tiers
    level: browser
    proves:
      - BR-CAP-PFM-MTD-018-11
    preconditions: 'Standard, read-only and API reader contexts exist.'
    steps:
      - do: Maintain links as the standard user and attempt those actions as readers.
        provenance: test
        source: >-
          react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a
          standard user links, ends and removes but has no Relationship Types screen, and a read-only
          colleague sees no actions
    expected: 'The standard user succeeds, reader cards lack actions and unauthorized API creation fails.'
    negative: true
    data_needs: 'Standard, read-only and API reader contexts exist.'
    bound_to:
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a
        standard user links, ends and removes but has no Relationship Types screen, and a read-only colleague
        sees no actions
      - >-
        services-platform:modules/associations/tests/e2e/associations.e2e.spec.js#answers 403 to an
        association create by a caller who may only read
      - TST-PFM-MTD-026
      - TST-PFM-MTD-036
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a standard
      user links, ends and removes but has no Relationship Types screen, and a read-only colleague sees no
      actions
    category: permission
    assertions:
      - expect: 'The standard user succeeds, reader cards lack actions and unauthorized API creation fails.'
        provenance: test
        source: >-
          react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S12.spec.ts#PLAT-M6-S12: a
          standard user links, ends and removes but has no Relationship Types screen, and a read-only
          colleague sees no actions
  - id: ATS-PFM-MTD-018-12
    title: Locks remain effective for retired types
    level: api
    proves:
      - BR-CAP-PFM-MTD-018-13
    preconditions: A deactivated type has locked and unlocked links.
    steps:
      - do: 'Edit and end an update-locked link, remove a locked link and maintain an unlocked one.'
        provenance: proposed
        source: 'services-platform:modules/associations/services/persistence/associations.ts:updateAssociation'
    expected: Locks refuse the protected operations and the unlocked existing link can still change.
    negative: true
    data_needs: A deactivated type has locked and unlocked links.
    bound_to: []
    provenance: proposed
    source: 'services-platform:modules/associations/services/persistence/associations.ts:updateAssociation'
    category: failure
    assertions:
      - expect: Locks refuse the protected operations and the unlocked existing link can still change.
        provenance: proposed
        source: 'services-platform:modules/associations/services/persistence/associations.ts:updateAssociation'
  - id: ATS-PFM-MTD-018-13
    title: Ending a link changes deletion protection and evidence
    category: interaction
    level: api
    exercises:
      - CAP-PFM-MTD-018
      - CAP-PFM-MTD-014
      - CAP-PFM-MTD-015
      - CAP-PFM-MTD-019
    proves:
      - BR-CAP-PFM-MTD-018-07
      - BR-CAP-PFM-MTD-014-05
      - BR-CAP-PFM-MTD-015-01
      - BR-CAP-PFM-MTD-019-01
    preconditions: A dated restricting link joins two custom records.
    steps:
      - do: 'End it on a past valid date, inspect both histories and its event, then delete an endpoint.'
        provenance: proposed
        source: &ref_0
          - >-
            services-platform:modules/associations/tests/integration/services/persistence/associations.integration.spec.js#refuses
            an end before the association started, leaving it open
          - 'services-platform:docs/associations.md#7a. History'
          - >-
            services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.events.integration.spec.js#publishes
            nothing when the transaction that wrote the record rolls back, in the ledger or the queue
          - >-
            services-platform:modules/associations/tests/integration/db/apply-endpoint-deletion.integration.spec.js#answers
            what endpointDeletionOutcome says for an open association on the to side under restrict
    expected: 'Compare ended browsing, captured change and subsequent deletion outcome.'
    negative: false
    data_needs: A dated restricting link joins two custom records.
    bound_to: []
    provenance: proposed
    source: *ref_0
    assertions:
      - expect: 'Compare ended browsing, captured change and subsequent deletion outcome.'
        provenance: proposed
        source: *ref_0
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: the association specs named in each
    scenario.
  - 'react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: Playwright PLAT-M6-S03 to S07, S10, S12.'
  - >-
    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: 'gap: FND-PFM-MTD-080'
  transition: covered
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-MTD-080'
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: covered
  interaction: covered
coverage_obligations:
  - rule: BR-CAP-PFM-MTD-018-01
    scenarios:
      - ATS-PFM-MTD-018-01
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-02
    scenarios:
      - ATS-PFM-MTD-018-02
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-03
    scenarios:
      - ATS-PFM-MTD-018-02
      - ATS-PFM-MTD-018-03
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-04
    scenarios:
      - ATS-PFM-MTD-018-04
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-05
    scenarios:
      - ATS-PFM-MTD-018-05
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-06
    scenarios:
      - ATS-PFM-MTD-018-06
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-07
    scenarios:
      - ATS-PFM-MTD-018-07
      - ATS-PFM-MTD-018-13
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-08
    scenarios:
      - ATS-PFM-MTD-018-08
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-09
    scenarios:
      - ATS-PFM-MTD-018-09
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-10
    scenarios:
      - ATS-PFM-MTD-018-10
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-11
    scenarios:
      - ATS-PFM-MTD-018-11
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - rule: BR-CAP-PFM-MTD-018-13
    scenarios:
      - ATS-PFM-MTD-018-12
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
interactions:
  - with: CAP-PFM-MTD-014
    scenarios:
      - ATS-PFM-MTD-018-13
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - with: CAP-PFM-MTD-015
    scenarios:
      - ATS-PFM-MTD-018-13
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
  - with: CAP-PFM-MTD-019
    scenarios:
      - ATS-PFM-MTD-018-13
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-018-link-records-to-one-another-dated-primary-and-in-force-until.md
---

# Maintain Dated Links Between Records: Capability Test Specification

## Coverage

- Obligation 01: 1 scenario 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: 1 scenario cite this obligation.
- Obligation 07: 2 scenarios cite this obligation.
- Obligation 08: 1 scenario cite this obligation.
- Obligation 09: 1 scenario cite this obligation.
- Obligation 10: 1 scenario cite this obligation.
- Obligation 11: 1 scenario cite this obligation.
- Obligation 13: 1 scenario cite this obligation.

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

The ended connection is explained in history and no longer protects its endpoint. The structured interaction rows identify the related capabilities exercised and any remaining gap. Cross-capability workflow seams remain subject to the detailed coverage audit.
