---
id: CAP-PFM-QRY-001
title: Discover the data available for questions
feature: FEAT-PFM-QRY-01
product_area: platform
module: queries
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - CAP-RPT-QRY-008
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 1'
  - 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 5'
  - 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 6'
  - 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 7'
  - 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 18'
  - >-
    services-platform:docs/queries/semantic-query-layer.md#6.5 Visibility versus access (Andrew, 2026-10-21,
    CRM-ACC-0064)
purpose: >-
  Give staff a clear inventory of queryable records and a description of the fields and relationships
  available to them.
outcomes:
  - Staff can distinguish available datasets from missing access.
  - Descriptions expose permitted query information.
  - Metadata changes appear in the next description.
concepts:
  - CON-PFM-QRY-001
actors:
  - ACT-PFM-013
  - ACT-PFM-014
  - ACT-PFM-016
surfaces:
  - console
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: platform.queries.read
    where_checked: api
    scope: tenant
  - key: '<application>.<dataset>.query (the owner''s key, e.g. crm.contacts.query)'
    where_checked: service
    scope: tenant
  - key: <application>.<records>.read where the owner declares it (e.g. crm.organizations.read)
    where_checked: service
    scope: tenant
  - key: 'platform.custom-records.query (scoped to custom_object:<object key>)'
    where_checked: service
    scope: record
rules:
  - id: BR-CAP-PFM-QRY-001-01
    proved_by: [ATS-PFM-QRY-001-01, ATS-PFM-QRY-001-14, TST-PFM-QRY-225]
    statement: >-
      The dataset catalog includes all registered workspace datasets, marks each person’s access, and counts
      usable datasets per application rather than hiding unauthorized entries.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#answers each dataset with whether this
      caller may use it
    origin: 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 1'
  - id: BR-CAP-PFM-QRY-001-02
    proved_by: [ATS-PFM-QRY-001-02, ATS-PFM-QRY-001-13, ATS-PFM-QRY-005-17, TST-PFM-QRY-225]
    statement: >-
      Dataset descriptions and runs require query-surface access and the dataset’s query permission; missing
      access is refused with the permission named, while an unregistered dataset is not found.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    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
    origin: 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 1'
  - id: BR-CAP-PFM-QRY-001-03
    proved_by: [ATS-PFM-QRY-001-03, TST-PFM-QRY-254]
    statement: >-
      When the dataset also declares a record-read permission, readers need both permissions, and a denied
      read permission makes its query surfaces unavailable despite a query grant.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    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
    origin: >-
      services-platform:docs/queries/semantic-query-layer.md#6.5 Visibility versus access (Andrew, 2026-10-21,
      CRM-ACC-0064)
  - id: BR-CAP-PFM-QRY-001-04
    proved_by: [ATS-PFM-QRY-001-04, TST-PFM-QRY-224]
    statement: >-
      A dataset query also requires access to its owning application, and a missing application grant produces
      a refusal naming that permission.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-001-05
    proved_by: [ATS-PFM-QRY-001-05, TST-PFM-QRY-225, TST-PFM-QRY-296]
    statement: >-
      A description combines registered fields, workspace custom information and labels with permitted
      relationships, while excluding physical storage details.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#tells the console nothing of how a
      field is stored
    origin: 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 5'
  - id: BR-CAP-PFM-QRY-001-06
    proved_by: []
    statement: >-
      The product should expose each registered record column for querying unless its owner records an
      exclusion reason.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 6'
    origin: 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 6'
  - id: BR-CAP-PFM-QRY-001-07
    proved_by: [ATS-PFM-QRY-001-06, TST-PFM-QRY-263]
    statement: >-
      A changed field, label, classification or registration invalidates the relevant cached description so
      the next request reflects it.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    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
    origin: >-
      services-platform:docs/queries/semantic-query-layer.md#7.4b The description cache [Built, 2026-10-14]
      (Andrew, 2026-10-14)
  - id: BR-CAP-PFM-QRY-001-08
    proved_by: [ATS-PFM-QRY-001-07, ATS-PFM-QRY-001-12, ATS-PFM-QRY-002-17, TST-PFM-QRY-262, TST-PFM-QRY-276]
    statement: >-
      Descriptions advertise initial columns, ordering, criteria and discovery statuses, but execution does
      not add those suggested criteria to a submitted query.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-001-09
    proved_by: [ATS-PFM-QRY-001-08, TST-PFM-QRY-222]
    statement: >-
      Active custom objects become workspace datasets without deployment and require the custom-record query
      permission scoped to the particular object.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/custom-object-datasets.e2e.spec.js#is refused objects.boats
      with 403
    origin: 'services-platform:docs/queries/semantic-query-layer.md#Decisions Recorded (Andrew, 2026-10-08) 18'
  - id: BR-CAP-PFM-QRY-001-10
    proved_by: [ATS-PFM-QRY-001-09, TST-PFM-QRY-225]
    statement: >-
      Application deployments register datasets through an internal invocation, whose response identifies
      rejected declarations so deployment can report them.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: 'services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#names what it refused in the answer'
    origin: none
  - id: BR-CAP-PFM-QRY-001-11
    proved_by: [ATS-PFM-QRY-001-10, TST-PFM-QRY-332]
    statement: >-
      Registration rejects workspace datasets without a workspace-bearing source and references that cross
      between workspace and system dataset scopes.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-001-12
    proved_by: [ATS-PFM-QRY-001-11, TST-PFM-QRY-332]
    statement: >-
      Registered record-opening fields must belong directly to the record; unknown fields and selected
      collection values are rejected.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      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
    origin: none
scenarios:
  - id: SC-CAP-PFM-QRY-001-01
    given: A person may query contacts but lacks organization query access.
    when: They request the dataset catalog.
    then: Contacts is authorized and Organizations remains listed without authorization.
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/datasets.e2e.spec.js#marks the datasets of that key
      authorized in the list, and the others not
  - id: SC-CAP-PFM-QRY-001-02
    given: A custom contact field is added after a description is cached.
    when: The workspace requests another contact description.
    then: The description includes the added field.
    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
edge_cases: []
constraints: []
depends_on: []
related:
  - CAP-PFM-QRY-002
  - CAP-PFM-QRY-005
  - CAP-PFM-QRY-008
journeys:
  - JNY-PFM-QRY-002
open_questions: []
operations:
  - listQueryDatasets
  - describeQueryDataset
tables:
  - registered-query-objects.table.ts
  - registered-query-picks.table.ts
  - registered-query-collections.table.ts
  - registered-query-computed-fields.table.ts
  - registered-query-configured-relationships.table.ts
  - query-description-stamps.table.ts
evidence:
  - 'Pinned reference: services-platform:docs/queries/semantic-query-layer.md'
  - '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/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/registration/register-query-application.integration.spec.js
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-006, TC-LOG-001, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-QRY-01-01, FAS-PFM-QRY-01-02, FAS-PFM-QRY-01-03, FAS-PFM-QRY-01-04]
suites: [TST-PFM-QRY-222, TST-PFM-QRY-224, TST-PFM-QRY-225, TST-PFM-QRY-254, TST-PFM-QRY-262, TST-PFM-QRY-263, TST-PFM-QRY-276, TST-PFM-QRY-296, TST-PFM-QRY-332]
---

# Discover the data available for questions

## Purpose

Give staff a clear inventory of queryable records and a description of the fields and relationships available to them.

## How It Works

Staff begin by browsing the available datasets. The catalog helps them distinguish missing access from missing data. Opening an available dataset supplies the information used to build a question. Workspace labels and custom fields make that description recognizable to the customer. Applications maintain the declarations behind this shared vocabulary. Registration reports problems before a declaration can be used. A dataset description supplies starting choices for a screen without silently adding them to execution. The product should decide when more granular field and row restrictions become part of this contract.

## Relationships

Dataset discovery supplies the descriptions used by execution, custom tables and reusable recipes.
