---
id: ATS-PFM-MTD-011
scope: CAP-PFM-MTD-011
product_area: platform
module: metadata
revision: 2
status: proposed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-PFM-MTD-011-01
    title: One-object grants do not widen to other types
    level: api
    proves:
      - BR-CAP-PFM-MTD-011-01
    preconditions: A role is scoped to Boat.
    steps:
      - do: List Boat and Manufacturer records.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#refuses the
          same role another object’s records, answering as if the object were not there
    expected: Boats are available while manufacturers return not found.
    negative: true
    data_needs: A role is scoped to Boat.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#lets a role
        scoped to custom_object:boat list boats
      - >-
        services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#refuses the same
        role another object’s records, answering as if the object were not there
      - TST-PFM-MTD-051
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#refuses the same
      role another object’s records, answering as if the object were not there
    category: permission
    assertions:
      - expect: Boats are available while manufacturers return not found.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#refuses the
          same role another object’s records, answering as if the object were not there
  - id: ATS-PFM-MTD-011-02
    title: Roles-only access needs the object assignment
    level: browser
    proves:
      - BR-CAP-PFM-MTD-011-02
      - INV-DOM-PFM-MTD-004-09
    preconditions: Enforcement Actions is restricted to Investigators.
    steps:
      - do: Read and browse as broad staff and as a scoped investigator.
        provenance: test
        source: >-
          react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S14.spec.ts#PLAT-M5-S14:
          restricted to the Investigators role and granted in Security: only investigators see and edit
    expected: Broad staff receive not found and no entry point; investigators can view and edit.
    negative: true
    data_needs: Enforcement Actions is restricted to Investigators.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#keeps a
        roles-only object from a customer-wide assignment, answering as if it were not there
      - >-
        services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#lets an
        assignment scoped to the roles-only object reach it
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S14.spec.ts#PLAT-M5-S14:
        restricted to the Investigators role and granted in Security: only investigators see and edit
      - TST-PFM-MTD-051
      - TST-PFM-MTD-014
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S14.spec.ts#PLAT-M5-S14: restricted
      to the Investigators role and granted in Security: only investigators see and edit
    category: permission
    assertions:
      - expect: Broad staff receive not found and no entry point; investigators can view and edit.
        provenance: test
        source: >-
          react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S14.spec.ts#PLAT-M5-S14:
          restricted to the Investigators role and granted in Security: only investigators see and edit
  - id: ATS-PFM-MTD-011-03
    title: Built-in tiers carry their intended keys
    level: unit
    proves:
      - BR-CAP-PFM-MTD-011-03
    preconditions: Generated tier policies are available.
    steps:
      - do: 'Inspect Administrator, User and Read Only grants.'
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#gives
          Platform User reading, querying, creating and updating records and their history, and reading
          definitions
    expected: Their definition and record permissions match the corresponding tiers.
    negative: false
    data_needs: Generated tier policies are available.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#gives
        Platform Administrator every key of the two resources
      - >-
        services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#gives
        Platform User reading, querying, creating and updating records and their history, and reading
        definitions
      - >-
        services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#gives
        Platform Read Only reading and querying records and their history, and reading definitions
      - TST-PFM-MTD-072
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#gives Platform
      User reading, querying, creating and updating records and their history, and reading definitions
    category: rule
    assertions:
      - expect: Their definition and record permissions match the corresponding tiers.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#gives
          Platform User reading, querying, creating and updating records and their history, and reading
          definitions
  - id: ATS-PFM-MTD-011-04
    title: Lifecycle removal uses delete permission
    level: unit
    proves:
      - BR-CAP-PFM-MTD-011-04
    preconditions: Record routes are declared.
    steps:
      - do: Inspect archive and restore authorization.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#requires
          one key per route, each a console route, the health route public, every record route scoped to its
          object
    expected: Both actions require object-scoped delete permission.
    negative: false
    data_needs: Record routes are declared.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#requires one
        key per route, each a console route, the health route public, every record route scoped to its object
      - TST-PFM-MTD-072
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#requires one
      key per route, each a console route, the health route public, every record route scoped to its object
    category: permission
    assertions:
      - expect: Both actions require object-scoped delete permission.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#requires
          one key per route, each a console route, the health route public, every record route scoped to its
          object
  - id: ATS-PFM-MTD-011-05
    title: Exposure projections narrow property readership
    level: unit
    proves:
      - BR-CAP-PFM-MTD-011-06
    preconditions: The record contains properties at each exposure level.
    steps:
      - do: 'Project it for staff, owner, portal and public audiences.'
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows a portal member the
          portal and public properties
    expected: The visible property sets narrow by audience while retaining record standard fields.
    negative: false
    data_needs: The record contains properties at each exposure level.
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows staff every property, a
        property with no exposure rule included
      - >-
        services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows the owner the owner, portal
        and public properties
      - >-
        services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows a portal member the portal
        and public properties
      - >-
        services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows the public the public
        properties only
      - TST-PFM-MTD-073
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows a portal member the portal
      and public properties
    category: permission
    assertions:
      - expect: The visible property sets narrow by audience while retaining record standard fields.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/unit/exposure.spec.ts#shows a portal member the
          portal and public properties
  - id: ATS-PFM-MTD-011-06
    title: Portal predicates evaluate allowed ties
    level: api
    proves:
      - BR-CAP-PFM-MTD-011-07
    preconditions: 'Owners, crew, role holders and publication and eligibility fixtures exist.'
    steps:
      - do: 'Evaluate operation predicates for current, expired, archived and foreign-workspace cases.'
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
          the owner the boat it owns now, and neither an ended ownership nor an archived boat
    expected: Only the supported local access conditions grant records and archived records remain unavailable.
    negative: true
    data_needs: 'Owners, crew, role holders and publication and eligibility fixtures exist.'
    bound_to:
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
        the owner the boat it owns now, and neither an ended ownership nor an archived boat
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
        a member with no linked contact nothing through owner
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
        nothing through owner_organization to a member whose role there has ended
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
        the union of an operation’s rules
      - >-
        services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
        nothing in another tenant, whose c1 owns nothing there
      - TST-PFM-MTD-069
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
      the owner the boat it owns now, and neither an ended ownership nor an archived boat
    category: validation
    assertions:
      - expect: Only the supported local access conditions grant records and archived records remain unavailable.
        provenance: test
        source: >-
          services-platform:modules/custom-objects/tests/integration/services/persistence/portal-ownership-predicates.integration.spec.js#grants
          the owner the boat it owns now, and neither an ended ownership nor an archived boat
  - id: ATS-PFM-MTD-011-07
    title: Readers receive no edit actions
    level: browser
    proves:
      - BR-CAP-PFM-MTD-011-08
    preconditions: Read-only and inaccessible-object users exist.
    steps:
      - do: 'Open the boat list, boat page and linked contact page.'
        provenance: test
        source: >-
          react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S08.spec.ts#PLAT-M5-S08: a
          read-only volunteer is offered no edit actions; a person without access sees no menu and no card
    expected: Readers have no edit controls and inaccessible users receive no object menu or card.
    negative: true
    data_needs: Read-only and inaccessible-object users exist.
    bound_to:
      - >-
        react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S08.spec.ts#PLAT-M5-S08: a
        read-only volunteer is offered no edit actions; a person without access sees no menu and no card
      - TST-PFM-MTD-008
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S08.spec.ts#PLAT-M5-S08: a read-only
      volunteer is offered no edit actions; a person without access sees no menu and no card
    category: permission
    assertions:
      - expect: Readers have no edit controls and inaccessible users receive no object menu or card.
        provenance: test
        source: >-
          react-console:acceptance/custom-objects/playwright/journeys/PLAT-M5-S08.spec.ts#PLAT-M5-S08: a
          read-only volunteer is offered no edit actions; a person without access sees no menu and no card
  - id: ATS-PFM-MTD-011-08
    title: An object-specific grant controls independent action permissions
    category: interaction
    level: api
    exercises:
      - CAP-PFM-MTD-011
      - CAP-PFM-MTD-010
      - CAP-PFM-MTD-012
      - CAP-PFM-MTD-013
      - CAP-PFM-MTD-014
    proves:
      - BR-CAP-PFM-MTD-011-02
      - BR-CAP-PFM-MTD-011-04
      - BR-CAP-PFM-MTD-014-03
    preconditions: Two objects have records; one uses roles-only reach.
    steps:
      - do: >-
          Use an object-scoped reader with history permission to open navigation, records and history; attempt
          update, archive and publication without their grants.
        provenance: proposed
        source: &ref_0
          - >-
            services-platform:modules/custom-objects/tests/e2e/custom-object-records.e2e.spec.js#keeps a
            roles-only object from a customer-wide assignment, answering as if it were not there
          - >-
            services-platform:modules/custom-objects/tests/unit/custom-object-permission-keys.spec.ts#requires
            one key per route, each a console route, the health route public, every record route scoped to its
            object
          - >-
            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: 'Inspect visible objects, history access and each refused action.'
    negative: false
    data_needs: Two objects have records; one uses roles-only reach.
    bound_to: []
    provenance: proposed
    source: *ref_0
    assertions:
      - expect: 'Inspect visible objects, history access and each refused action.'
        provenance: proposed
        source: *ref_0
evidence:
  - >-
    services-platform at ad3f6a6582843008ed0f5a17b131878d15829af1: the permission, exposure, predicate and e2e
    specs named in each scenario.
  - 'react-console at baf6dae382d6f41dce976c7f848667ccc37e076f: Playwright PLAT-M5-S08 and S14.'
  - >-
    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: 'gap: FND-PFM-MTD-073'
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-MTD-073'
  failure: 'gap: FND-PFM-MTD-073'
  boundary: 'gap: FND-PFM-MTD-073'
  concurrency: 'gap: FND-PFM-MTD-073'
  invariant: 'gap: FND-PFM-MTD-073'
  interaction: covered
coverage_obligations:
  - rule: BR-CAP-PFM-MTD-011-01
    scenarios:
      - ATS-PFM-MTD-011-01
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - rule: BR-CAP-PFM-MTD-011-02
    scenarios:
      - ATS-PFM-MTD-011-02
      - ATS-PFM-MTD-011-08
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - rule: BR-CAP-PFM-MTD-011-03
    scenarios:
      - ATS-PFM-MTD-011-03
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - rule: BR-CAP-PFM-MTD-011-04
    scenarios:
      - ATS-PFM-MTD-011-04
      - ATS-PFM-MTD-011-08
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - rule: BR-CAP-PFM-MTD-011-06
    scenarios:
      - ATS-PFM-MTD-011-05
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - rule: BR-CAP-PFM-MTD-011-07
    scenarios:
      - ATS-PFM-MTD-011-06
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - rule: BR-CAP-PFM-MTD-011-08
    scenarios:
      - ATS-PFM-MTD-011-07
    finding: null
    provenance: documented
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
interactions:
  - with: CAP-PFM-MTD-010
    scenarios:
      - ATS-PFM-MTD-011-08
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - with: CAP-PFM-MTD-012
    scenarios:
      - ATS-PFM-MTD-011-08
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
  - with: CAP-PFM-MTD-014
    scenarios:
      - ATS-PFM-MTD-011-08
    finding: null
    provenance: proposed
    source: >-
      specs/platform/metadata/planning/capabilities/CAP-PFM-MTD-011-decide-which-staff-reach-a-custom-object-s-records-and-which.md
---

# Control Custom Record Audiences: Capability Test Specification

## Coverage

- Obligation 01: 1 scenario cite this obligation.
- Obligation 02: 2 scenarios cite this obligation.
- Obligation 03: 1 scenario cite this obligation.
- Obligation 04: 2 scenarios cite this obligation.
- Obligation 06: 1 scenario cite this obligation.
- Obligation 07: 1 scenario cite this obligation.
- Obligation 08: 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

Read and history reach do not grant lifecycle or edit actions. The structured interaction rows identify the related capabilities exercised and any remaining gap. Cross-capability workflow seams remain subject to the detailed coverage audit.
