Skip to content

feat: universal QPU - #206

Merged
jpopesculian merged 1 commit into
mainfrom
jpop/universal-qpu
Aug 6, 2026
Merged

feat: universal QPU#206
jpopesculian merged 1 commit into
mainfrom
jpop/universal-qpu

Conversation

@jpopesculian

@jpopesculian jpopesculian commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added a universal QPU interface for submitting programs across supported platforms and quantum frameworks.
    • Added automatic format negotiation, platform selection, compression, shot configuration, job retrieval, and result access.
    • Added support for normalized results from additional quantum frameworks, including Qiskit, Cirq, and CUDA-Q.
    • Expanded API support for data catalogs, workspace versioning, competition templates, provider jobs, resource usage, and storage metadata.
  • Bug Fixes
    • Improved conversion errors and result-count handling.
  • Tests
    • Added comprehensive coverage for QPU workflows and result formats.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@jpopesculian, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0af8f927-5743-4d47-9a13-1a305756c157

📥 Commits

Reviewing files that changed from the base of the PR and between 1614c44 and b5c9d28.

📒 Files selected for processing (12)
  • .github/workflows/ci.yaml
  • pyproject.toml
  • python/aqora/__init__.py
  • python/aqora/_provider/client.py
  • python/aqora/_provider/formats.py
  • python/aqora/_provider/results.py
  • python/aqora/_provider/wire.py
  • python/aqora/qpu.py
  • schema.graphql
  • src/python_module.rs
  • test/test_pytket_provider.py
  • test/test_universal_qpu.py
📝 Walkthrough

Walkthrough

This change adds universal QPU support and broad GraphQL schema extensions. It negotiates program formats, submits provider jobs, normalizes results, and adds catalog, workspace, competition, provider-job, resource, and storage entities.

Changes

Universal QPU provider flow

Layer / File(s) Summary
Serialization formats and source encoding
pyproject.toml, src/python_module.rs, python/aqora/_provider/wire.py, python/aqora/_provider/formats.py, test/test_universal_qpu.py
Registers QIO formats and adds detection and encoding for Qiskit, pytket, HUGR, QIR, and QASM programs.
Platform format negotiation
python/aqora/_provider/client.py, python/aqora/_provider/formats.py, test/test_universal_qpu.py
Reads platform inputFormats metadata and selects a common serialization format.
QPU submission and job lifecycle
python/aqora/__init__.py, python/aqora/qpu.py, test/test_universal_qpu.py
Adds QPU and QPUJob APIs for platform selection, submission, reconstruction, metadata, and result access.
Result conversion and counts
python/aqora/_provider/results.py, python/aqora/qpu.py, test/test_universal_qpu.py, test/test_pytket_provider.py
Adds result conversion and count normalization for QIR, QSYS, Qiskit, Cirq, pytket, and CUDA-Q formats.

GraphQL schema extensions

Layer / File(s) Summary
Data catalog schema and permissions
schema.graphql
Adds data catalog types, dataset associations, permissions, queries, mutations, and entity fields.
Workspace and competition relationships
schema.graphql
Adds cloning, competition templates, event links, provenance, linked submissions, and workspace filters.
Provider jobs and resource metadata
schema.graphql
Adds provider-job ownership and subscriptions, quantum input-format metadata, runner resources, and storage usage types.

Estimated code review effort: 5 (Critical) | ~90 minutes

Sequence Diagram(s)

sequenceDiagram
  participant QPU
  participant Client
  participant Provider
  participant ResultDecoder
  QPU->>Client: request platform input formats
  Client-->>QPU: return advertised formats
  QPU->>QPU: detect and encode programs
  QPU->>Provider: submit serialized payload
  Provider-->>QPU: return job metadata
  QPU->>Provider: retrieve completed result
  Provider-->>ResultDecoder: provide serialized result
  ResultDecoder-->>QPU: return normalized counts
Loading

Possibly related PRs

  • aqora-io/cli#203: Provides the provider, wire-format, result, and GraphQL client functionality extended by this change.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.92% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding universal QPU support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jpop/universal-qpu

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
test/test_universal_qpu.py (3)

693-694: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Annotate the fake measurement map as a ClassVar.

Ruff reports RUF012 for the mutable class attribute.

♻️ Proposed change
     class CirqResult:
-        measurements = {"m": [[0, 1], [1, 0], [0, 1]]}
+        measurements: ClassVar[dict[str, list[list[int]]]] = {
+            "m": [[0, 1], [1, 0], [0, 1]]
+        }

Add from typing import ClassVar to the imports.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_universal_qpu.py` around lines 693 - 694, Update the CirqResult
test fixture’s mutable measurements class attribute to use a ClassVar
annotation, and add the corresponding ClassVar import from typing.

Source: Linters/SAST tools


550-551: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Bind the property access to silence Ruff B018.

The attribute access is the action under test, but Ruff reports it as a useless expression.

♻️ Proposed change
     with pytest.raises(LookupError, match="nexus:Nope"):
-        qpu.input_formats
+        _ = qpu.input_formats
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_universal_qpu.py` around lines 550 - 551, Bind the
qpu.input_formats property access in the pytest.raises block to a throwaway
variable so Ruff B018 recognizes it as intentional, while preserving the
expected LookupError and match assertion.

Source: Linters/SAST tools


569-573: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider covering QPUJob.from_id and QPUJob.counts.

The suite covers submission and ProviderResult.counts, but not the two new QPUJob entry points. from_id builds a QPU from qualified_platform_name(payload.get("platform")) and returns serialization_format is None; counts maps every result. The FakeClient.send handler already returns a platform object for query ProviderJob, so both are cheap to test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_universal_qpu.py` around lines 569 - 573, Add tests in
test_job_reports_the_negotiated_format or the surrounding QPU job tests covering
QPUJob.from_id and QPUJob.counts: verify from_id constructs the QPU using the
payload platform and leaves serialization_format unset, and verify counts maps
every returned result. Reuse the existing FakeClient.send query ProviderJob
response and established test fixtures.
python/aqora/_provider/formats.py (1)

296-305: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Add strict=True to the zip call.

Ruff flags B905 on Line 303. encoders is built from sources, so the lengths always match, and strict=True documents that invariant.

♻️ Proposed change
             programs = [
                 encoder(source.program)
-                for encoder, source in zip(encoders, sources)
+                for encoder, source in zip(encoders, sources, strict=True)
                 if encoder is not None
             ]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/aqora/_provider/formats.py` around lines 296 - 305, Update the zip
call in the serialization loop to pass strict=True, preserving the existing
encoder/source pairing while documenting that encoders and sources always have
equal lengths.

Source: Linters/SAST tools

python/aqora/qpu.py (1)

99-104: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

job._payload reaches into a private attribute of jobs.submit_model's return value.

QPUJob is constructed with the private _payload of the submitted job. A rename inside python/aqora/_provider/jobs.py breaks this call site silently at runtime. Consider exposing a public accessor on ProviderJob, for example a payload property, and using it here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/aqora/qpu.py` around lines 99 - 104, Replace the private job._payload
access in the QPUJob construction flow with a public payload accessor on
ProviderJob. Add a payload property to ProviderJob that returns the submitted
payload, then pass job.payload from the surrounding submission method while
preserving the existing serialization_format behavior.
python/aqora/__init__.py (1)

11-11: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

The new import creates an order-dependent import cycle.

aqora/__init__.py imports .qpu, and python/aqora/qpu.py Line 7 imports Client back from aqora. This resolves only because Client is already bound in the partially initialized aqora module when Line 11 runs. Any reordering of the imports above Line 11 raises ImportError at package import.

Importing Client from its defining module in qpu.py removes the cycle. Note that test/test_universal_qpu.py sets aqora.Client on a fake module, so a change here needs the test fake updated as well.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/aqora/__init__.py` at line 11, Update qpu.py to import Client directly
from its defining module instead of through the aqora package, removing the
order-dependent cycle introduced by aqora/__init__.py importing QPU and QPUJob.
Update the fake aqora module setup in test_universal_qpu.py so it provides the
direct Client dependency expected by qpu.py.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/aqora/_provider/client.py`:
- Line 126: Add inputFormats to the local ProviderPlatformMeta schema definition
used by the ProviderPlatforms query, or gate the meta.inputFormats selection so
it is omitted when unsupported by older servers; ensure the query remains valid
against the local schema and preserves compatibility with servers lacking this
field.

In `@python/aqora/_provider/results.py`:
- Around line 71-95: Update _cudaq_register_counts to validate the payload type
and available elements before every name, outcome, and triplet access. Reject
non-list/integer data and truncated or malformed records with an explicit
payload-validation error that identifies the CUDA-Q provider result, instead of
allowing IndexError or TypeError to escape; preserve normal decoding for valid
arrays.
- Around line 192-196: Update _pytket_counts to group each outcome’s bits
according to the registers in result.to_backend_result().c_bits, join bits
within each register, and separate register groups with spaces before
constructing the counts dictionary. Preserve counts and existing behavior for
single-register results.

---

Nitpick comments:
In `@python/aqora/__init__.py`:
- Line 11: Update qpu.py to import Client directly from its defining module
instead of through the aqora package, removing the order-dependent cycle
introduced by aqora/__init__.py importing QPU and QPUJob. Update the fake aqora
module setup in test_universal_qpu.py so it provides the direct Client
dependency expected by qpu.py.

In `@python/aqora/_provider/formats.py`:
- Around line 296-305: Update the zip call in the serialization loop to pass
strict=True, preserving the existing encoder/source pairing while documenting
that encoders and sources always have equal lengths.

In `@python/aqora/qpu.py`:
- Around line 99-104: Replace the private job._payload access in the QPUJob
construction flow with a public payload accessor on ProviderJob. Add a payload
property to ProviderJob that returns the submitted payload, then pass
job.payload from the surrounding submission method while preserving the existing
serialization_format behavior.

In `@test/test_universal_qpu.py`:
- Around line 693-694: Update the CirqResult test fixture’s mutable measurements
class attribute to use a ClassVar annotation, and add the corresponding ClassVar
import from typing.
- Around line 550-551: Bind the qpu.input_formats property access in the
pytest.raises block to a throwaway variable so Ruff B018 recognizes it as
intentional, while preserving the expected LookupError and match assertion.
- Around line 569-573: Add tests in test_job_reports_the_negotiated_format or
the surrounding QPU job tests covering QPUJob.from_id and QPUJob.counts: verify
from_id constructs the QPU using the payload platform and leaves
serialization_format unset, and verify counts maps every returned result. Reuse
the existing FakeClient.send query ProviderJob response and established test
fixtures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ab846d8-bd55-4af4-9d06-e6901102ae46

📥 Commits

Reviewing files that changed from the base of the PR and between d7fa459 and a05b5e7.

📒 Files selected for processing (9)
  • pyproject.toml
  • python/aqora/__init__.py
  • python/aqora/_provider/client.py
  • python/aqora/_provider/formats.py
  • python/aqora/_provider/results.py
  • python/aqora/_provider/wire.py
  • python/aqora/qpu.py
  • src/python_module.rs
  • test/test_universal_qpu.py

Comment thread python/aqora/_provider/client.py
Comment thread python/aqora/_provider/results.py Outdated
Comment thread python/aqora/_provider/results.py Outdated
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
test/test_universal_qpu.py (2)

255-267: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Import the provider modules explicitly instead of reading sys.modules.

The formats, wire, and results fixtures assume that loading aqora.qpu already imported each aqora._provider.* module. If qpu.py later imports one of them lazily, the fixture raises KeyError and many tests fail with a message that does not point at the cause.

Use importlib.import_module so the fixture states its own dependency.

♻️ Proposed change
 `@pytest.fixture`
 def formats(qpu_mod):
-    return sys.modules["aqora._provider.formats"]
+    return importlib.import_module("aqora._provider.formats")
 
 
 `@pytest.fixture`
 def wire(qpu_mod):
-    return sys.modules["aqora._provider.wire"]
+    return importlib.import_module("aqora._provider.wire")
 
 
 `@pytest.fixture`
 def results(qpu_mod):
-    return sys.modules["aqora._provider.results"]
+    return importlib.import_module("aqora._provider.results")

Add the import at the top of the file:

import importlib
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_universal_qpu.py` around lines 255 - 267, Update the formats, wire,
and results fixtures to explicitly load their provider modules with
importlib.import_module instead of indexing sys.modules, and add the importlib
import required by those fixtures. Preserve each fixture’s existing module
target and return value.

126-128: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for paginated results.

FakeClient.send always returns self.result_pages[0] with hasNextPage: False. result_pages is a list of pages, and resultCount sums every page, so the fake can never exercise the cursor loop in the client. A job with more results than one page is a realistic case for a QPU run.

Return page N based on the after cursor and set hasNextPage accordingly, then add a test that spans two pages.

Also applies to: 175-184

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/test_universal_qpu.py` around lines 126 - 128, Update FakeClient.send to
select the page using the request’s after cursor, return that page’s results,
and set hasNextPage based on whether another result_pages entry remains. Add a
test covering a QPU job whose results span two pages, verifying the client
follows the cursor and combines both pages.
python/aqora/_provider/formats.py (1)

331-334: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Make the message distinguish an empty platform preference list.

encode falls back to the sources' native formats when accepted is empty. In that case the message still says "the platform accepts ...", which names formats the platform never advertised. Pass a flag or the original accepted list so the text can say that the platform stated no preference.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/aqora/_provider/formats.py` around lines 331 - 334, Update the
error-message construction in encode to retain whether the original accepted
list was empty, and use that state to say the platform stated no preference
instead of claiming it accepts the wanted formats. Preserve the existing wording
for non-empty platform preferences.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/aqora/_provider/formats.py`:
- Around line 110-124: Update _qasm_format to skip OpenQASM block comments,
including multi-line /* ... */ comments, before evaluating the first meaningful
line. Track whether scanning is inside a block comment, ignore comment content
and blank lines, then preserve the existing OPENQASM version detection and None
behavior for unsupported input.

In `@python/aqora/_provider/results.py`:
- Around line 101-102: Validate each packed outcome before assigning it in the
counts-building logic: if packed.bit_length() exceeds width, raise ValueError
and do not store the key. Otherwise preserve the existing
bin(packed)[2:].zfill(width) conversion and count assignment.

In `@schema.graphql`:
- Line 2490: Align eventCompetitionPinned with pinEventCompetition by making the
pinned lookup event-scoped and accepting the relevant eventId, or alternatively
enforce a single global pin with replacement semantics and document that
behavior in the schema. Keep the query and mutation scope consistent.
- Around line 3465-3470: Replace the GraphQL Int types used for storage byte
counts with the project’s 64-bit or custom wide scalar. Update
StorageStatus.used, capacity, available, and requested at
schema.graphql:3465-3470, and StorageUsage.used and limit at
schema.graphql:3478-3481, using the same scalar consistently at both sites.

In `@test/test_universal_qpu.py`:
- Around line 548-551: Update test_unknown_platform_raises so the intentional
qpu.input_formats access is assigned to a throwaway local variable inside the
pytest.raises block, preserving the LookupError trigger while satisfying Ruff
B018.

---

Nitpick comments:
In `@python/aqora/_provider/formats.py`:
- Around line 331-334: Update the error-message construction in encode to retain
whether the original accepted list was empty, and use that state to say the
platform stated no preference instead of claiming it accepts the wanted formats.
Preserve the existing wording for non-empty platform preferences.

In `@test/test_universal_qpu.py`:
- Around line 255-267: Update the formats, wire, and results fixtures to
explicitly load their provider modules with importlib.import_module instead of
indexing sys.modules, and add the importlib import required by those fixtures.
Preserve each fixture’s existing module target and return value.
- Around line 126-128: Update FakeClient.send to select the page using the
request’s after cursor, return that page’s results, and set hasNextPage based on
whether another result_pages entry remains. Add a test covering a QPU job whose
results span two pages, verifying the client follows the cursor and combines
both pages.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ea52bf36-dfed-4b1b-890a-db6f2a6968f3

📥 Commits

Reviewing files that changed from the base of the PR and between 1614c44 and fd7e750.

📒 Files selected for processing (12)
  • .github/workflows/ci.yaml
  • pyproject.toml
  • python/aqora/__init__.py
  • python/aqora/_provider/client.py
  • python/aqora/_provider/formats.py
  • python/aqora/_provider/results.py
  • python/aqora/_provider/wire.py
  • python/aqora/qpu.py
  • schema.graphql
  • src/python_module.rs
  • test/test_pytket_provider.py
  • test/test_universal_qpu.py
🚧 Files skipped from review as they are similar to previous changes (6)
  • python/aqora/init.py
  • python/aqora/_provider/client.py
  • pyproject.toml
  • python/aqora/_provider/wire.py
  • src/python_module.rs
  • python/aqora/qpu.py

Comment thread python/aqora/_provider/formats.py
Comment thread python/aqora/_provider/results.py
Comment thread schema.graphql
Comment thread schema.graphql
Comment on lines +3465 to +3470
type StorageStatus {
used: Int
capacity: Int
available: Int
requested: Int
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== schema size =="
wc -l schema.graphql || true

echo "== storage status/usage definitions =="
rg -n "type Storage(Status|Usage)|Scalars|Decimal|BigInt|Long|Byte|ByteCount|storage" schema.graphql

echo "== relevant schema section =="
sed -n '3430,3495p' schema.graphql

echo "== GraphQL Int scalar usage in schema =="
rg -n "scalar Int|type .*Int|: Int|`@default`|`@default`" schema.graphql | head -200

Repository: aqora-io/cli

Length of output: 17309


🌐 Web query:

GraphQL spec Int signed 32-bit scalar maximum 2147483647 scalar types

💡 Result:

The GraphQL specification explicitly defines the Int scalar type as a signed 32-bit integer, with a valid range of -(2^31) to 2^31 - 1, which corresponds to the inclusive range of -2,147,483,648 to 2,147,483,647 [1][2][3]. Key details regarding the Int scalar include: - Strict Specification: GraphQL services must adhere to this definition; a service must not use the Int type to represent 64-bit numbers or other data outside this range [4][2][3]. - Error Handling: If an internal value or input value falls outside this 32-bit range (less than -2^31 or greater than or equal to 2^31), the service is required to raise an execution or request error [5][2][3]. - Alternatives for Larger Numbers: Because not all platforms and transport protocols support integers larger than 32 bits, the GraphQL specification recommends that numeric integer values exceeding this range be handled by using either the String type or a custom-defined scalar type (e.g., a "Long" or "BigInt" scalar) [6][2][3]. This limitation is intentionally maintained to ensure cross-platform compatibility, as many environments and clients—including those relying on JavaScript—have historically had varying or limited support for 64-bit integers [6][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== defined scalars in schema =="
rg -n '^scalar ' schema.graphql || true

echo "== Int scalar definition overrides =="
rg -n 'scalar Int|Int =|Int scalar|GraphQLScalarType|new GraphQLScalarType' .

Repository: aqora-io/cli

Length of output: 434


Use a wide scalar for storage byte counts.

GraphQL Int is signed 32-bit and cannot represent storage values above 2,147,483,647 bytes.

  • schema.graphql#L3465-L3470: Change StorageStatus.used, capacity, available, and requested to a 64-bit/custom wide scalar.
  • schema.graphql#L3478-L3481: Change StorageUsage.used and limit to the same wide scalar.
📍 Affects 1 file
  • schema.graphql#L3465-L3470 (this comment)
  • schema.graphql#L3478-L3481
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@schema.graphql` around lines 3465 - 3470, Replace the GraphQL Int types used
for storage byte counts with the project’s 64-bit or custom wide scalar. Update
StorageStatus.used, capacity, available, and requested at
schema.graphql:3465-3470, and StorageUsage.used and limit at
schema.graphql:3478-3481, using the same scalar consistently at both sites.

Comment thread test/test_universal_qpu.py Outdated
@jpopesculian
jpopesculian merged commit 0810702 into main Aug 6, 2026
1 check passed
@jpopesculian
jpopesculian deleted the jpop/universal-qpu branch August 6, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant