---
id: ATS-PFM-QRY-007
scope: CAP-PFM-QRY-007
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-007-01
    title: Shared questions retain runner access
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-01
      - INV-DOM-PFM-QRY-002-01
    preconditions: A shared query has readers with and without its dataset grant.
    steps: Execute as both readers.
    expected: The granted reader receives rows and the other receives 403.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#runs the organization’s query
        for a colleague who may query the dataset
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses to run it for a caller
        who may not query the dataset as 403, however it was shared
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses the run by the dataset’s
        own query permission, not by the sharing model [E2E-SQ-11]
      - TST-PFM-QRY-234
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#runs the organization’s query for
      a colleague who may query the dataset
    category: permission
  - id: ATS-PFM-QRY-007-02
    title: Run requests cannot replace the stored question
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-02
    preconditions: A reusable question has stored paging.
    steps: 'Run with page changes, supplied criteria and an unsupported paging key.'
    expected: Allowed paging merges; attempts to alter unsupported content return 400.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#takes the page size the caller
        asks for over the one the definition stored
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#counts every matching row and
        not the page, for a caller that asks for both a total and a smaller page
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a body carrying anything
        but the page as 400
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a page carrying a key
        the query language does not have as 400
      - TST-PFM-QRY-234
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#takes the page size the caller
      asks for over the one the definition stored
    category: validation
  - id: ATS-PFM-QRY-007-03
    title: Run-time declarations match their uses
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-03
    preconditions: A definition asks for a date value.
    steps: 'Save undeclared input use, an incompatible declaration and invalid parameter structure.'
    expected: Each invalid definition returns a located 400 problem.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a save whose token is
        not declared as 400 naming the criterion
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a save whose declaration
        does not match its criterion as 400 at definition.parameters[0].dataType
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a save whose parameters
        are not a list as 400
      - TST-PFM-QRY-234
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a save whose token is not
      declared as 400 naming the criterion
    category: validation
  - id: ATS-PFM-QRY-007-04
    title: Run-time inputs are validated by name
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-04
    preconditions: A saved query requires a date input.
    steps: >-
      Run with a valid value, omission, incorrect type and unrequested name; supply a value to a query asking
      for none.
    expected: Only the valid input executes; other cases fail at the supplied or missing name.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#runs with the value given,
        answering only the contacts it keeps
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a run without the
        required value as 400 at parameters.updatedBefore
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a value of the wrong
        type as 400 at its key
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses a key the query does not
        ask for as 400 at that key
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#keeps a text value exactly as
        sent, never trimmed by the boundary
      - TST-PFM-QRY-234
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#runs with the value given,
      answering only the contacts it keeps
    category: boundary
  - id: ATS-PFM-QRY-007-05
    title: Refinement preserves the original population
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-05
      - INV-DOM-PFM-QRY-002-07
    preconditions: The stored question excludes some dataset rows.
    steps: 'Apply outside criteria, negation and an attempted scope change.'
    expected: No excluded rows enter the result and the scope replacement is refused.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#narrows
        to the rows that also meet the refinement’s criteria
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#never
        widens: criteria naming a contact outside the query answer none of it
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#never
        widens: a negated refinement still answers only the query’s rows
      - >-
        services-platform:modules/queries/tests/e2e/reports.e2e.spec.js#refuses a refinement that states what
        only the saved query decides as 400
      - TST-PFM-QRY-343
      - TST-PFM-QRY-233
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#narrows
      to the rows that also meet the refinement’s criteria
    category: invariant
    binding_note: >-
      The cited suites contribute separate assertions. The complete combined example is not a single
      executable journey.
  - id: ATS-PFM-QRY-007-06
    title: Readers can adapt displayed columns
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-06
    preconditions: A saved question selects three fields.
    steps: Refine with other fields permitted by the dataset.
    expected: The same population is presented using the chosen replacement columns.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#answers
        the columns the refinement names instead of the stored ones, over the same rows
      - TST-PFM-QRY-343
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#answers
      the columns the refinement names instead of the stored ones, over the same rows
    category: rule
  - id: ATS-PFM-QRY-007-07
    title: Refinement cannot answer required inputs
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-07
    preconditions: A saved question requires a run-time value.
    steps: Introduce a run-time token through refinement and omit the original required value.
    expected: Both uses are rejected.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#refuses
        criteria that ask for a value when run, which only a stored definition may
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#still
        asks for the value: a refinement does not stand in for a required parameter
      - TST-PFM-QRY-343
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js#refuses
      criteria that ask for a value when run, which only a stored definition may
    category: validation
  - id: ATS-PFM-QRY-007-08
    title: Population paging is complete and resumable
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-08
    preconditions: A question matches two thousand six hundred contacts.
    steps: 'Enumerate identities, request exact and capped counts, then change criteria before cursor reuse.'
    expected: Three ordered pages cover each identity once; counts mark caps and the changed-query cursor is rejected.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#answers
        three pages of 1,000, 1,000 and 600 ids
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#answers
        every planted contact once, none repeated and none missed, in record id order
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#answers
        the same definition hash on every page
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#stops
        at its cap and says so
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#refuses
        a cursor taken before the criteria changed, rather than paging a mixture
      - TST-PFM-QRY-347
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#answers
      three pages of 1,000, 1,000 and 600 ids
    category: rule
  - id: ATS-PFM-QRY-007-09
    title: Population access is rebuilt for each person
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-09
    preconditions: Requested users include the disallowed status and customer cases.
    steps: Invoke population reading for each identity.
    expected: Invalid identities or access return access denied and invisible questions return not found.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#refuses
        a user who does not exist as access_denied
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#refuses
        a suspended user as access_denied, naming the status
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#refuses
        a portal user as access_denied
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#refuses
        a user of another customer, who has no access to the tenant, as access_denied
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#answers
        access_denied once the owner’s dataset key is taken away
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#answers
        saved_query_not_found for a colleague’s private saved query, which the owner may not open
      - TST-PFM-QRY-341
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#refuses
      a user who does not exist as access_denied
    category: permission
  - id: ATS-PFM-QRY-007-10
    title: Unsuitable questions cannot become populations
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-10
    preconditions: A question uses Recently Viewed.
    steps: Request its population and try a page beyond one thousand identities.
    expected: The question is invalid for populations and the page size is rejected.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#answers
        saved_query_invalid for a saved query of the person’s recently viewed records
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#answers
        invalid_request for a limit above 1,000
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#refuses
        a saved query of the person’s recently viewed records, which is no population
      - TST-PFM-QRY-341
      - TST-PFM-QRY-347
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js#answers
      saved_query_invalid for a saved query of the person’s recently viewed records
    category: validation
    binding_note: >-
      The cited suites contribute separate assertions. The complete combined example is not a single
      executable journey.
  - id: ATS-PFM-QRY-007-11
    title: Population logs omit records and values
    level: api
    proves:
      - BR-CAP-PFM-QRY-007-11
    preconditions: An application enumerates a saved question’s population.
    steps: Inspect its execution log output.
    expected: Query and dataset context remain while criterion values and record identities are absent.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#logs
        the saved query and its dataset when the population is resolved
      - >-
        services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#logs
        no criteria value and no record id
      - TST-PFM-QRY-347
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js#logs
      the saved query and its dataset when the population is resolved
    category: invariant
  - id: ATS-PFM-QRY-007-12
    title: A colleague runs a shared question with personal values
    category: interaction
    level: api
    exercises:
      - CAP-PFM-QRY-006
      - CAP-PFM-QRY-007
    proves:
      - BR-CAP-PFM-QRY-006-02
      - BR-CAP-PFM-QRY-007-01
    preconditions: Two users share one role and a saved personal-task question with a requested date.
    steps: 'Run the shared question as each user with the same date, then remove one user’s dataset grant and rerun.'
    expected: Each successful answer contains that runner’s tasks; the revoked runner receives no result.
    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/saved-queries.e2e.spec.js#answers not found for a role the
        caller does not hold, and excludes the record from the list [E2E-SQ-09]
      - >-
        services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js#refuses to run it for a caller
        who may not query the dataset as 403, however it was shared
  - id: ATS-PFM-QRY-007-13
    title: Finding a report does not grant joined data
    category: interaction
    level: api
    exercises:
      - CAP-PFM-QRY-007
      - CAP-PFM-QRY-011
    proves:
      - BR-CAP-PFM-QRY-007-01
      - BR-CAP-PFM-QRY-011-03
    preconditions: >-
      A report uses a visible saved question whose base dataset is accessible but whose joined dataset is
      denied.
    steps: 'Find and open the report, then run its source question as the viewer.'
    expected: Catalog discovery can succeed while the source execution refuses the inaccessible join.
    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/saved-queries.e2e.spec.js#refuses to run it for a caller
        who may not query the dataset as 403, however it was shared
      - 'services-platform:modules/queries/services/reports/report-library.ts:readableReports'
evidence:
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/reports.e2e.spec.js'
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/saved-queries.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/saved-queries/record-ids-invocation.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/saved-queries/run-with-refinement.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/saved-queries/saved-query-record-ids.integration.spec.js
coverage_notes:
  transition: >-
    This capability has no formal lifecycle of its own. Audience and definition changes remain rule,
    permission and concurrency proofs; related lifecycles are exercised through interaction scenarios.
coverage:
  rule: covered
  transition: not-applicable
  validation: covered
  permission: covered
  edge: 'gap: FND-PFM-QRY-057'
  failure: 'gap: FND-PFM-QRY-057'
  boundary: covered
  concurrency: 'gap: FND-PFM-QRY-057'
  invariant: covered
  interaction: covered
coverage_findings:
  - FND-PFM-QRY-057
transition_obligations: []
unproved_rules: []
---

# Run a saved question for the current reader: Capability Test Specification

## Coverage

| Rule | Scenario or Finding |
|---|---|
| `BR-CAP-PFM-QRY-007-01` | `ATS-PFM-QRY-007-01`, `ATS-PFM-QRY-007-12`, `ATS-PFM-QRY-007-13` |
| `BR-CAP-PFM-QRY-007-02` | `ATS-PFM-QRY-007-02` |
| `BR-CAP-PFM-QRY-007-03` | `ATS-PFM-QRY-007-03` |
| `BR-CAP-PFM-QRY-007-04` | `ATS-PFM-QRY-007-04` |
| `BR-CAP-PFM-QRY-007-05` | `ATS-PFM-QRY-007-05` |
| `BR-CAP-PFM-QRY-007-06` | `ATS-PFM-QRY-007-06` |
| `BR-CAP-PFM-QRY-007-07` | `ATS-PFM-QRY-007-07` |
| `BR-CAP-PFM-QRY-007-08` | `ATS-PFM-QRY-007-08` |
| `BR-CAP-PFM-QRY-007-09` | `ATS-PFM-QRY-007-09` |
| `BR-CAP-PFM-QRY-007-10` | `ATS-PFM-QRY-007-10` |
| `BR-CAP-PFM-QRY-007-11` | `ATS-PFM-QRY-007-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-006` | `ATS-PFM-QRY-007-12` |
| `CAP-PFM-QRY-011` | `ATS-PFM-QRY-007-13` |

## 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.
