---
id: ATS-PFM-QRY-001
scope: CAP-PFM-QRY-001
product_area: platform
module: queries
revision: 2
status: proposed
approved_by: null
approved_at: null
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  rhythm-v2-docs: 99376625d3e7ac26936413cfc31a88fba6562464
scenarios:
  - id: ATS-PFM-QRY-001-01
    title: Catalog separates existence from access
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-01
    preconditions: The caller has surface access and one dataset grant.
    steps: List datasets with that grant and with no dataset grants.
    expected: Entries retain their authorization flags; denied entries remain visible.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#answers each dataset with whether
        this caller may use it
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#lists every dataset as unauthorized
        for a caller holding no dataset permission
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#counts no authorized dataset in the
        application for such a caller
      - TST-PFM-QRY-225
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#answers each dataset with whether this
      caller may use it
    category: permission
  - id: ATS-PFM-QRY-001-02
    title: Dataset access and absence differ
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-02
      - INV-DOM-PFM-QRY-001-01
    preconditions: Contacts is registered but the caller lacks its query grant.
    steps: 'Describe and execute Contacts, then request an unregistered subject.'
    expected: The denied operations return 403; the missing subject returns 404.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses a dataset the caller holds no
        query permission for as 403
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#answers 404 for a dataset no
        application registered
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses to describe it for a caller
        holding the surface key and not the dataset key
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses to run a query on it for that
        caller
      - TST-PFM-QRY-225
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses a dataset the caller holds no
      query permission for as 403
    category: permission
  - id: ATS-PFM-QRY-001-03
    title: Record read denial overrides a query grant
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-03
    preconditions: A role allows organization queries but denies organization reading.
    steps: Describe Organizations and inspect the dataset catalog.
    expected: Organizations is refused and unauthorized; Contacts remains available.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/describe/dataset-effective-permissions.integration.spec.js#refuses
        Organizations to a caller denied crm.organizations.read, though the role still grants
        crm.organizations.query
      - >-
        services-platform:modules/queries/tests/integration/services/describe/dataset-effective-permissions.integration.spec.js#lists
        Organizations as unauthorized and Contacts as authorized for that caller
      - TST-PFM-QRY-254
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/describe/dataset-effective-permissions.integration.spec.js#refuses
      Organizations to a caller denied crm.organizations.read, though the role still grants
      crm.organizations.query
    category: permission
  - id: ATS-PFM-QRY-001-04
    title: Application access is independently required
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-04
    preconditions: Test roles lack application access despite a dataset grant.
    steps: Execute the contact question under each role and a fully granted role.
    expected: Denied roles receive 403 naming the missing permission; the granted role succeeds.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/dataset-effective-permissions.e2e.spec.js#refuses a role
        holding the dataset key without the application's access key 403, naming the key
      - >-
        services-platform:modules/queries/tests/e2e/dataset-effective-permissions.e2e.spec.js#answers 200 to a
        plain grant of the dataset key and the application key
      - TST-PFM-QRY-224
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/dataset-effective-permissions.e2e.spec.js#refuses a role
      holding the dataset key without the application's access key 403, naming the key
    category: permission
  - id: ATS-PFM-QRY-001-05
    title: Descriptions withhold storage and inaccessible relationships
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-05
    preconditions: The reader can query contacts but lacks related-dataset access.
    steps: Describe Contacts and request a value through the inaccessible relation.
    expected: The description omits storage details and the related field is treated as unavailable.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#tells the console nothing of how a
        field is stored
      - >-
        services-platform:modules/queries/tests/integration/services/execute/run-query.integration.spec.js#refuses
        a field of a dataset the caller may not query exactly as it refuses one that does not exist
      - TST-PFM-QRY-225
      - TST-PFM-QRY-296
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#tells the console nothing of how a
      field is stored
    category: invariant
    binding_note: >-
      The cited suites contribute separate assertions. The complete combined example is not a single
      executable journey.
  - id: ATS-PFM-QRY-001-06
    title: Metadata invalidates the appropriate description
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-07
      - INV-DOM-PFM-QRY-001-05
    preconditions: A contact description is already cached.
    steps: 'Add a field, rename a classification and revise registration, requesting a new description after each.'
    expected: Changes appear immediately; another workspace’s change does not invalidate this cache.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/describe/description-stamp-coverage.integration.spec.js#describes
        a custom field the tenant adds on the very next build
      - >-
        services-platform:modules/queries/tests/integration/services/describe/description-stamp-coverage.integration.spec.js#describes
        an affiliation type’s new name on the very next build
      - >-
        services-platform:modules/queries/tests/integration/services/describe/description-stamp-coverage.integration.spec.js#describes
        a registration change, which moves the global stamp, on the very next build
      - >-
        services-platform:modules/queries/tests/integration/services/describe/description-stamp-coverage.integration.spec.js#keeps
        answering from the cache after a change in another tenant
      - TST-PFM-QRY-263
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/describe/description-stamp-coverage.integration.spec.js#describes
      a custom field the tenant adds on the very next build
    category: invariant
  - id: ATS-PFM-QRY-001-07
    title: Discovery suggestions do not alter execution
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-08
    preconditions: The fixture includes several statuses and an active-only discovery default.
    steps: Execute without a status condition and with an explicit inactive condition.
    expected: Both requests follow their submitted criteria rather than injected defaults.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/execute/discovery-defaults.integration.spec.js#answers
        every contact of the tenant whatever its status, nothing having injected the reported criteria
      - >-
        services-platform:modules/queries/tests/integration/services/execute/discovery-defaults.integration.spec.js#answers
        the inactive contacts of the caller’s tenant, a rule never narrowing what a query asks for
      - >-
        services-platform:modules/queries/tests/integration/services/describe/describe-discovery.integration.spec.js#starts
        a new query with the rule written as one ordinary criterion
      - TST-PFM-QRY-276
      - TST-PFM-QRY-262
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/execute/discovery-defaults.integration.spec.js#answers
      every contact of the tenant whatever its status, nothing having injected the reported criteria
    category: rule
    binding_note: >-
      The cited suites contribute separate assertions. The complete combined example is not a single
      executable journey.
  - id: ATS-PFM-QRY-001-08
    title: Custom-object access remains object-scoped
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-09
    preconditions: An active Boats object exists with grants scoped to different objects.
    steps: 'List, describe and execute it with matching and nonmatching grants.'
    expected: The matching reader can use it; the other sees unauthorized and receives 403.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/custom-object-datasets.e2e.spec.js#lists objects.boats
        under the objects application, authorized for the holder
      - >-
        services-platform:modules/queries/tests/e2e/custom-object-datasets.e2e.spec.js#is refused
        objects.boats with 403
      - >-
        services-platform:modules/queries/tests/e2e/custom-object-datasets.e2e.spec.js#is answered
        objects.boats as not authorized in the catalog
      - TST-PFM-QRY-222
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/custom-object-datasets.e2e.spec.js#lists objects.boats under
      the objects application, authorized for the holder
    category: permission
  - id: ATS-PFM-QRY-001-09
    title: Registration errors remain response data
    level: api
    proves:
      - BR-CAP-PFM-QRY-001-10
      - INV-DOM-PFM-QRY-001-03
    preconditions: One application declaration is valid and another is invalid.
    steps: Invoke registration for both declarations.
    expected: Success identifies the application; rejection identifies the declaration problem.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#accepts the manifest, naming the
        application it registered
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#answers a refusal rather than
        throwing, so the deploy step reads it
      - 'services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#names what it refused in the answer'
      - TST-PFM-QRY-225
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#accepts the manifest, naming the
      application it registered
    category: transition
  - id: ATS-PFM-QRY-001-10
    title: Scope incompatibilities fail registration
    level: unit
    proves:
      - BR-CAP-PFM-QRY-001-11
    preconditions: Declarations include a missing workspace source and cross-scope references.
    steps: Submit each incompatible declaration.
    expected: 'Rejection identifies the relevant source, field or scope mismatch.'
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
        a tenant-scoped dataset whose base has no tenant_id, naming the relation and the scope it should
        declare
      - >-
        services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
        a tenant-scoped dataset that references a system one, naming the field and both scopes
      - >-
        services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
        a system dataset that references a tenant one, naming the field and both scopes
      - TST-PFM-QRY-332
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
      a tenant-scoped dataset whose base has no tenant_id, naming the relation and the scope it should declare
    category: validation
  - id: ATS-PFM-QRY-001-11
    title: Opening fields belong to the record
    level: unit
    proves:
      - BR-CAP-PFM-QRY-001-12
    preconditions: Declarations mark a selected collection value or missing field as a record-opening field.
    steps: Register both declarations.
    expected: Both are refused before registration completes.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
        a link field the dataset does not have
      - >-
        services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
        a pick as a link field, because a pick is not a field of the record itself
      - TST-PFM-QRY-332
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js#refuses
      a link field the dataset does not have
    category: validation
  - id: ATS-PFM-QRY-001-12
    title: A discovery suggestion does not hide inactive records
    category: interaction
    level: api
    exercises:
      - CAP-PFM-QRY-001
      - CAP-PFM-QRY-002
    proves:
      - BR-CAP-PFM-QRY-001-08
      - BR-CAP-PFM-QRY-002-01
    preconditions: Contacts includes active and inactive records; the description suggests active records.
    steps: 'Read the description, then run an unfiltered contact question and a question selecting inactive records.'
    expected: The first answer contains both statuses and the second contains only the inactive fixture.
    negative: false
    data_needs: >-
      Use an isolated workspace with the described source records, access grants and a surviving control
      workspace.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses a dataset the caller holds no
        query permission for as 403
      - >-
        services-platform:modules/queries/tests/integration/services/execute/current-user-criterion.integration.spec.js#answers
        a second caller their own tasks, from the very same criterion
  - id: ATS-PFM-QRY-001-13
    title: A tailored dataset disappears from new choices before execution stops
    category: interaction
    level: api
    exercises:
      - CAP-PFM-QRY-001
      - CAP-PFM-QRY-005
    proves:
      - BR-CAP-PFM-QRY-001-02
      - BR-CAP-PFM-QRY-005-10
    preconditions: One assigned tailored dataset supplies a retained question.
    steps: 'Read its description, deprecate it, reopen the retained question, then disable it and run again.'
    expected: >-
      Deprecation removes the new choice while the retained question still resolves; disabling produces the
      explicit refusal.
    negative: true
    data_needs: >-
      Use an isolated workspace with the described source records, access grants and a surviving control
      workspace.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses a dataset the caller holds no
        query permission for as 403
      - 'services-platform:modules/queries/services/custom-tables/assignment-visibility.ts:visibleCustomTables'
  - id: ATS-PFM-QRY-001-14
    title: A recipe can be discovered before its subject is usable
    category: interaction
    level: api
    exercises:
      - CAP-PFM-QRY-001
      - CAP-PFM-QRY-008
    proves:
      - BR-CAP-PFM-QRY-001-01
      - BR-CAP-PFM-QRY-008-02
    preconditions: A contact recipe is active and the caller lacks contact query access.
    steps: 'List datasets and recipes, then try drafting the contact recipe.'
    expected: >-
      Both catalogs expose the subject with unavailable access; drafting is refused without a runnable
      question.
    negative: true
    data_needs: >-
      Use an isolated workspace with the described source records, access grants and a surviving control
      workspace.
    bound_to: []
    provenance: proposed
    source:
      - >-
        services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#refuses a dataset the caller holds no
        query permission for as 403
      - >-
        services-platform:modules/queries/tests/e2e/query-recipes.e2e.spec.js#refuses a draft of a dataset
        this caller may not query as 403
evidence:
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/custom-object-datasets.e2e.spec.js'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/dataset-effective-permissions.e2e.spec.js'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/describe/dataset-effective-permissions.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/describe/describe-discovery.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/describe/description-stamp-coverage.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/execute/discovery-defaults.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/execute/run-query.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/registration/register-query-application.integration.spec.js
coverage:
  rule: covered
  transition: 'gap: FND-PFM-QRY-051'
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-QRY-051'
  failure: 'gap: FND-PFM-QRY-051'
  boundary: 'gap: FND-PFM-QRY-051'
  concurrency: 'gap: FND-PFM-QRY-051'
  invariant: 'gap: FND-PFM-QRY-051'
  interaction: covered
coverage_findings:
  - FND-PFM-QRY-051
transition_obligations:
  - state: STATE-PFM-QRY-002
    transition: 1
    from: active
    to: retired
    trigger: Application registration omits an existing dataset.
    source: >-
      services-platform:modules/queries/services/registration/register-query-application.ts:registerQueryApplication
    gap: FND-PFM-QRY-051
  - state: STATE-PFM-QRY-002
    transition: 2
    from: retired
    to: active
    trigger: A valid application manifest includes the retired dataset again.
    source: 'services-platform:modules/queries/db/registered-query-objects.table.ts (retired_at)'
    gap: FND-PFM-QRY-051
unproved_rules: []
---

# Discover the data available for questions: Capability Test Specification

## Coverage

| Rule | Scenario or Finding |
|---|---|
| `BR-CAP-PFM-QRY-001-01` | `ATS-PFM-QRY-001-01` |
| `BR-CAP-PFM-QRY-001-02` | `ATS-PFM-QRY-001-02`, `ATS-PFM-QRY-001-12`, `ATS-PFM-QRY-001-13`, `ATS-PFM-QRY-001-14` |
| `BR-CAP-PFM-QRY-001-03` | `ATS-PFM-QRY-001-03` |
| `BR-CAP-PFM-QRY-001-04` | `ATS-PFM-QRY-001-04` |
| `BR-CAP-PFM-QRY-001-05` | `ATS-PFM-QRY-001-05` |
| `BR-CAP-PFM-QRY-001-07` | `ATS-PFM-QRY-001-06` |
| `BR-CAP-PFM-QRY-001-08` | `ATS-PFM-QRY-001-07` |
| `BR-CAP-PFM-QRY-001-09` | `ATS-PFM-QRY-001-08` |
| `BR-CAP-PFM-QRY-001-10` | `ATS-PFM-QRY-001-09` |
| `BR-CAP-PFM-QRY-001-11` | `ATS-PFM-QRY-001-10` |
| `BR-CAP-PFM-QRY-001-12` | `ATS-PFM-QRY-001-11` |

## Interactions With Related Capabilities

The combined examples change a source, its audience or its retained state before checking the dependent outcome. Unbound examples remain proposed, and the coverage finding retains design obligations that these examples do not establish.

| Related Capability | Scenario |
|---|---|
| `CAP-PFM-QRY-002` | `ATS-PFM-QRY-001-12` |
| `CAP-PFM-QRY-005` | `ATS-PFM-QRY-001-13` |
| `CAP-PFM-QRY-008` | `ATS-PFM-QRY-001-14` |

## Evidence and Binding Limits

The source revisions pin the inspected assertions. A test binding identifies written assertions, and does not establish a successful run or approval of the expected behavior.
