docs(specs): spec, plan and tasks for GraphQL query cost [INFP-739]

Draft
FA
6d ago
+1785-0

Jira: INFP-739. A GitHub issue for this work is not known.

This PR adds the design documents of the feature in dev/specs/infp-739-graphql-query-cost/. It changes no code. The implementation is in #11003, which targets this PR's branch.

TL;DR

  • Problem: a team that renders artifacts or runs generators from GraphQL queries over a large data set cannot tell, before or after a run, how much work a query causes or which relationship field causes it. Infrahub records only the depth and height of each query, so an engineer has to trace a run to find the field that multiplies the database rows.
  • What is needed:
    • the actual nodes, resolver calls and database rows of each relationship field, returned when a request to /graphql or /api/query sends a header
    • an expected and a worst-case estimate of the same figures for each relationship field, built from peer statistics that a scheduled task computes from main
    • the same estimate from the InfrahubGraphQLQueryReport query, without running the submitted query
  • Not decided yet:
    • how old the statistics may be, which the refresh schedule sets
    • whether infrahub-private-tests needs a CI change to run the synthetic data set
    • which trace and which customer the CablingPlanLogical figures come from
    • a maintainer's confirmation of three changes in "Ask First" areas, listed below

Why an estimate from average peer counts is not enough

From spec.md, "Summary":

  • The work of a query depends mostly on how many peers each relationship returns, and that number varies widely between nodes.
  • On one customer's CablingPlanLogical query, an estimate from averages gives about 23,000 single-relationship resolver calls, against an actual 183,000. Counting the devices at the first step and using averages after it gives about 254,000.
  • Neo4j's own statistics cannot give the number of peers of each relationship, because every relationship goes through the same IS_RELATED edge and Relationship vertex, and the relationship identifier is only a property.

The trace these figures come from is not linked, and the customer is not named in the sources.

Design documents in this PR

  • spec.md: two P1 user stories, the functional requirements FR-001 to FR-018, the success criteria SC-001 to SC-004, the assumptions, what is out of scope and the open questions
  • plan.md: the technical approach, the constitution check, the files to add and change, the design notes and the risks
  • research.md: the facts the design depends on and the design decisions D1 to D12, for example:
    • the name and values of the request header (D1)
    • how the actual counts are recorded (D3)
    • the content and cache layout of the statistics (D5)
    • the counted first step (D9)
    • the estimate algorithm (D10)
  • data-model.md: the cache keys of the statistics, the estimation tree, and the estimate and actual counts of a field
  • contracts/: the request header and the extensions.query_cost content, as a description and as a JSON schema, and the GraphQL contract of InfrahubGraphQLQueryReport
  • quickstart.md: manual steps to check the feature on a development stack with the demo data
  • tasks.md: 46 tasks in 7 phases
  • critiques/critique-20261007-184332.md: a critique of the spec and the plan. Its findings are applied to the documents above.
  • alignment-check.md: a check of spec.md against the INFP-739 brief. It found five minor additions and clarifications, and no requirement of the brief that is missing, weakened or contradicted.
  • checklists/requirements.md: the quality checklist of the spec

Changes in "Ask First" areas that need a maintainer's confirmation

AGENTS.md, "Ask First" lists changes to ask about before they land. According to spec.md, "Governance gates crossed", the feature makes three of them:

  • GraphQL schema change: a new variables argument and new estimate fields on InfrahubGraphQLQueryReport
  • API contract change: a new request header on /graphql and /api/query, and new extensions content in the response
  • Authorization change: a read-permission check on InfrahubGraphQLQueryReport, with no new permission

Not crossed:

  • a database schema or migration change: the statistics are stored in the cache, not in the graph
  • a new dependency
  • a CI/CD workflow change in opsmill/infrahub

The INFP-739 brief records the three changes as decided. According to tasks.md, "Before the PR leaves draft", the implementation PR is not marked ready before a maintainer confirms them. #11003 lists them with a checkbox for each.

Out of scope

From spec.md, "Out of Scope", among other items:

  • limiting how many artifact and generator runs happen at once by their total estimated cost (related: INFP-689)
  • sizing Cypher pages and loader batches from the estimate (related: INFP-502)
  • Prometheus metrics, a single combined cost figure, and admission based on cost
  • estimating the reads caused by display labels rendered from templates, profile values and permission filtering
  • mutations

Changes that the implementation PR makes to these documents

#11003 updates some of these documents to match the code that landed, and adds two files:

  • tasks.md: 45 of the 46 tasks are ticked. T046, a PR in opsmill/infrahub-private-tests, is not done.
  • data-model.md, research.md, plan.md, quickstart.md and contracts/: corrections and additions from the implementation, for example:
    • the point in the request where counting starts
    • the response when no estimate can be computed
    • the fields whose first step is not counted
    • two quickstart instructions that did not work
  • pr-description.md: the description of #11003
  • opsmill-implement-report.md: the implementation report, with the decisions that each implementation step flagged

Suggested review order

[CLAUDE RECOMMENDED – based on which documents each document refers to] spec.md, then contracts/, then plan.md with research.md and data-model.md, then tasks.md.

Sources

  • INFP-739: the card and the idea brief in its comments
  • the documents listed under "Design documents in this PR"

Generated with Claude Code