---
id: ATS-PFM-QRY-003
scope: CAP-PFM-QRY-003
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-003-01
    title: Generation has separate authority
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-01
    preconditions: A caller has query access but lacks generation permission.
    steps: Request a generation and poll an existing one.
    expected: Both operations return 403.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a caller without
        platform.queries.generate as 403, however much else they hold
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a caller without
        platform.queries.generate as 403
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a caller without
      platform.queries.generate as 403, however much else they hold
    category: permission
  - id: ATS-PFM-QRY-003-02
    title: Generation checks its subject
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-02
    preconditions: A caller cannot query the requested dataset.
    steps: Generate for that subject and for an unregistered subject.
    expected: Access is refused with 403 and absence returns 404.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a caller who may not
        query the dataset as 403
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers a dataset nobody
        registered as 404
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a caller who may not
      query the dataset as 403
    category: permission
  - id: ATS-PFM-QRY-003-03
    title: Written requests satisfy text bounds
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-03
    preconditions: The caller can request generation.
    steps: 'Submit empty, oversized and non-text input.'
    expected: All invalid inputs return the same validation code with 400.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses an empty request as
        400, naming the field
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a request longer than a
        person may type as 400
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#carries the same code for a
        request that is not text at all
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses an empty request as 400,
      naming the field
    category: boundary
  - id: ATS-PFM-QRY-003-04
    title: Generation follows its initiating person
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-04
      - INV-DOM-PFM-QRY-002-12
    preconditions: A generation remains in progress in one workspace.
    steps: 'Read it as its requester, another person and from another workspace.'
    expected: Only the initiating person in the originating workspace can read it.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers 200 with the generation
        still working
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses the person who did not
        start it as 404, however much they hold
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#does not answer, in another
        tenant, a generation started in this one
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers 200 with the generation
      still working
    category: permission
  - id: ATS-PFM-QRY-003-05
    title: Generated definitions use ordinary execution
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-05
    preconditions: Generation has produced a valid query.
    steps: Submit that query through normal execution.
    expected: Execution succeeds under the requester’s data access.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers the query the worker
        stored, which is the query the execute route would accept
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#runs the query it answered: the
        console can send it straight to the execute route
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers the query the worker
      stored, which is the query the execute route would accept
    category: invariant
  - id: ATS-PFM-QRY-003-06
    title: Exhausted allowance prevents admission
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-06
    preconditions: The organization has no remaining AI credit.
    steps: Submit a generation request.
    expected: The request fails immediately with allowance details and no model or price disclosure.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses the request itself,
        rather than accepting it and failing two minutes later
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#says what was needed and what
        was left, and nothing of a model or a price
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses the request itself,
      rather than accepting it and failing two minutes later
    category: failure
  - id: ATS-PFM-QRY-003-07
    title: Metering remains separate from visible output
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-07
    preconditions: A generation has completed successfully.
    steps: Inspect its invocation accounting and requester-facing record.
    expected: Accounting records one invocation while visible output omits cost and model.
    negative: false
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#recorded one metered invocation
        for the request, against this operation and its prompt version
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#charged the association for it
        and holds nothing of its allowance
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers nothing of the cost or
        the model to the person who asked: that is the operator’s record
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#recorded one metered invocation
      for the request, against this operation and its prompt version
    category: rule
  - id: ATS-PFM-QRY-003-08
    title: Refinement retains its predecessor
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-09
    preconditions: One generation is complete and another is still working.
    steps: Request refinements of both.
    expected: The completed predecessor yields a linked new generation; the working predecessor is refused.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#is a generation of its own, not
        the one it refines
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a refinement of a
        generation that is still working as 400
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#is a generation of its own, not
      the one it refines
    category: transition
  - id: ATS-PFM-QRY-003-09
    title: Simultaneous-call limits explain retry
    level: api
    proves:
      - BR-CAP-PFM-QRY-003-10
    preconditions: The organization has reached its concurrent AI-call cap.
    steps: Request generation and inspect its settled state.
    expected: Failure identifies the concurrency limit and the invocation records a refusal reason.
    negative: true
    data_needs: Use the existing binding’s controlled fixture data.
    bound_to:
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#leaves a refused invocation
        that names the reason, the generation having been refused rather than failed
      - TST-PFM-QRY-227
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#leaves a refused invocation that
      names the reason, the generation having been refused rather than failed
    category: concurrency
  - id: ATS-PFM-QRY-003-10
    title: Abandonment and retention
    level: unit
    proves:
      - BR-CAP-PFM-QRY-003-11
      - INV-DOM-PFM-QRY-002-11
    preconditions: 'Controlled generations include overdue, recent, settled and expired records.'
    steps: Run recovery with the fixture clock.
    expected: >-
      Overdue work fails, recent and settled work keeps its state, and expired request and outcome records are
      removed.
    negative: true
    data_needs: Use the controlled fixtures and clocks supplied by the cited tests.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#fails
        the generation no worker is going to settle, with the code an operator reads
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#gives
        a generation the worker’s whole timeout and a margin before calling it abandoned
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#deletes
        the generation past its thirtieth day, request and outcome together
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#leaves
        a verdict already written alone, so a worker that finished mid-sweep wins
      - TST-PFM-QRY-307
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#fails
      the generation no worker is going to settle, with the code an operator reads
    category: transition
  - id: ATS-PFM-QRY-003-11
    title: Context refusal and startup compensation
    level: unit
    proves:
      - BR-CAP-PFM-QRY-003-12
    preconditions: A request can include a current query and the worker invocation can fail.
    steps: 'Submit inaccessible and mismatched query context, then fail invocation for a valid request.'
    expected: Invalid context creates no work; startup failure returns and stores a failed generation.
    negative: true
    data_needs: Use the controlled fixtures and clocks supplied by the cited tests.
    bound_to:
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#refuses
        a query on screen naming a field nobody can query, listing the problem under the property it is about
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#refuses
        a query on screen built for another dataset, which is not the query this request is about
      - >-
        services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#fails
        the generation at once when the worker cannot be started, and says so to the caller
      - TST-PFM-QRY-307
    provenance: test
    source: >-
      services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js#refuses
      a query on screen naming a field nobody can query, listing the problem under the property it is about
    category: failure
  - id: ATS-PFM-QRY-003-12
    title: A proposed question cannot bypass execution access
    category: interaction
    level: api
    exercises:
      - CAP-PFM-QRY-002
      - CAP-PFM-QRY-003
    proves:
      - BR-CAP-PFM-QRY-002-01
      - BR-CAP-PFM-QRY-003-05
    preconditions: A completed proposal refers to Contacts and its requester subsequently loses contact query access.
    steps: Open the proposal and submit its query to ordinary execution.
    expected: The proposal remains requester-readable but its execution is refused before contact rows are returned.
    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/integration/services/execute/run-query.integration.spec.js#refuses
        a column no owner registered exactly as it refuses one that does not exist at all
      - >-
        services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#runs the query it answered: the
        console can send it straight to the execute route
evidence:
  - 'Pinned reference: services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/queries/tests/integration/services/generate/start-and-reconcile-generations.integration.spec.js
coverage:
  rule: covered
  transition: 'gap: FND-PFM-QRY-053'
  validation: 'gap: FND-PFM-QRY-053'
  permission: covered
  edge: 'gap: FND-PFM-QRY-053'
  failure: covered
  boundary: covered
  concurrency: covered
  invariant: covered
  interaction: covered
coverage_findings:
  - FND-PFM-QRY-053
transition_obligations:
  - state: STATE-PFM-QRY-003
    transition: 1
    from: working
    to: succeeded
    trigger: The worker returns an accepted final outcome.
    source: 'services-platform:modules/queries/services/generate/run-generation.ts'
    gap: FND-PFM-QRY-053
  - state: STATE-PFM-QRY-003
    transition: 2
    from: working
    to: failed
    trigger: The worker encounters a terminal generation failure.
    source: 'services-platform:modules/queries/services/generate/generation-problem-codes.ts'
    gap: FND-PFM-QRY-053
  - state: STATE-PFM-QRY-003
    transition: 3
    from: working
    to: failed
    trigger: The asynchronous worker invocation fails during admission.
    source: 'services-platform:modules/queries/services/generate/start-generation.ts'
    gap: FND-PFM-QRY-053
  - state: STATE-PFM-QRY-003
    transition: 4
    from: working
    to: failed
    trigger: Reconciliation finds the worker deadline and margin exceeded.
    source: 'services-platform:modules/queries/services/generate/reconcile-generations.ts'
    gap: FND-PFM-QRY-053
  - state: STATE-PFM-QRY-003
    transition: 5
    from: succeeded
    to: removed
    trigger: Retention cleanup finds a success older than thirty days.
    source: 'services-platform:modules/queries/services/generate/reconcile-generations.ts'
    gap: FND-PFM-QRY-053
  - state: STATE-PFM-QRY-003
    transition: 6
    from: failed
    to: removed
    trigger: Retention cleanup finds a failed generation older than thirty days.
    source: 'services-platform:modules/queries/services/generate/reconcile-generations.ts'
    gap: FND-PFM-QRY-053
unproved_rules: []
---

# Draft a query from a written request: Capability Test Specification

## Coverage

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

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