---
id: CAP-PFM-QRY-003
title: Draft a query from a written request
feature: FEAT-PFM-QRY-01
product_area: platform
module: queries
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources: []
purpose: Help staff turn a written question into a usable first draft that still passes the normal query checks.
outcomes:
  - A written question supplies a reviewed starting draft.
  - Generated drafts preserve normal execution checks.
  - Organizational AI usage is accounted for.
concepts:
  - CON-PFM-QRY-002
actors:
  - ACT-PFM-013
surfaces:
  - console
  - api
preconditions: []
postconditions: []
permissions:
  - key: platform.queries.generate
    where_checked: api
    scope: tenant
  - key: <application>.<dataset>.query (the owner's key)
    where_checked: service
    scope: tenant
rules:
  - id: BR-CAP-PFM-QRY-003-01
    proved_by: [ATS-PFM-QRY-003-01, TST-PFM-QRY-227]
    statement: >-
      Query generation requires its own permission, independently of query-reading access, and a caller
      lacking that permission is refused.
    kind: permission
    enforced_at:
      - api
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-003-02
    proved_by: [ATS-PFM-QRY-003-02, TST-PFM-QRY-227]
    statement: >-
      Generation requires access to the requested dataset, rejecting unauthorized datasets and reporting
      unregistered datasets as missing.
    kind: permission
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-003-03
    proved_by: [ATS-PFM-QRY-003-03, TST-PFM-QRY-227]
    statement: >-
      Generation accepts bounded, nonempty written text and returns the same validation code for empty,
      oversized or non-text requests.
    kind: validation
    enforced_at:
      - api
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses an empty request as 400,
      naming the field
    origin: none
  - id: BR-CAP-PFM-QRY-003-04
    proved_by: [ATS-PFM-QRY-003-04, TST-PFM-QRY-227]
    statement: >-
      A generation request returns a record to poll, which only its initiating person can read within the
      originating workspace.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      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
    origin: none
  - id: BR-CAP-PFM-QRY-003-05
    proved_by: [ATS-PFM-QRY-003-05, ATS-PFM-QRY-003-12, TST-PFM-QRY-227]
    statement: >-
      A generated query runs through ordinary execution as the requester and therefore cannot expand that
      person’s access.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      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
    origin: none
  - id: BR-CAP-PFM-QRY-003-06
    proved_by: [ATS-PFM-QRY-003-06, TST-PFM-QRY-227]
    statement: >-
      An exhausted organizational AI allowance refuses the request immediately with the required and remaining
      amounts.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-003-07
    proved_by: [ATS-PFM-QRY-003-07, TST-PFM-QRY-227]
    statement: >-
      Each request records one metered organizational invocation while withholding model and cost details from
      its requester.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-003-08
    proved_by: []
    statement: Generation may return clarification and interpretations without providing a query.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: 'services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers no query with a question'
    origin: none
  - id: BR-CAP-PFM-QRY-003-09
    proved_by: [ATS-PFM-QRY-003-08, TST-PFM-QRY-227]
    statement: >-
      Refinement creates a separate generation linked to its predecessor and rejects a predecessor still in
      progress.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#refuses a refinement of a
      generation that is still working as 400
    origin: none
  - id: BR-CAP-PFM-QRY-003-10
    proved_by: [ATS-PFM-QRY-003-09, TST-PFM-QRY-227]
    statement: >-
      An organization at its simultaneous-call limit receives a retry-later generation failure, with the
      refused invocation’s reason recorded.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    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
    origin: none
  - id: BR-CAP-PFM-QRY-003-11
    proved_by: [ATS-PFM-QRY-003-10, TST-PFM-QRY-307]
    statement: >-
      The recovery sweep fails work still unsettled after the worker timeout and margin, preserves an existing
      verdict, and deletes request and outcome records older than thirty days.
    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
    origin: none
    enforced_at:
      - service
    must_prove: true
    kind: policy
  - id: BR-CAP-PFM-QRY-003-12
    proved_by: [ATS-PFM-QRY-003-11, TST-PFM-QRY-307]
    statement: >-
      Generation rejects invalid or inaccessible query context before creating work; failure to invoke the
      worker settles the admitted generation as failed instead of leaving it working.
    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
    origin: none
    enforced_at:
      - service
    must_prove: true
    kind: validation
scenarios:
  - id: SC-CAP-PFM-QRY-003-01
    given: A person can generate a query for an accessible dataset.
    when: They submit a written question.
    then: The returned draft includes the model’s attributed assumptions and explanation.
    provenance: test
    source: >-
      services-platform:modules/queries/tests/e2e/generate-query.e2e.spec.js#answers the assumptions and the
      explanation the model gave, as what it said and not as the system’s own words
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-QRY-001
related:
  - CAP-PFM-QRY-002
journeys: []
open_questions: []
operations:
  - generateDatasetQuery
  - getQueryGeneration
tables:
  - query-generations.table.ts
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
controls: [TC-AI-001, TC-AI-002, TC-AI-003, TC-AI-004, TC-AI-005, TC-AI-006, TC-AI-007, TC-AVL-001, TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-004, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-PI-001, TC-PI-002, TC-PI-004, TC-PI-005, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-QRY-01-01]
suites: [TST-PFM-QRY-227, TST-PFM-QRY-307]
---

# Draft a query from a written request

## Purpose

Help staff turn a written question into a usable first draft that still passes the normal query checks.

## How It Works

Staff describe the question they want to answer. The request creates a generation that the client follows while work proceeds. Platform resolves the permitted dataset description for the model request. AI allowance and simultaneous-call controls can stop the request. A finished generation may contain a query, an explanation or a clarification question. The person reviews the answer and executes any query through the normal query surface. They can submit a refinement as another generation. Access to a generation remains with the person who requested it.

## Relationships

Assisted drafting produces a candidate for ordinary query execution and uses the separate AI allowance service.
