Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @m2papierz
48 changes: 48 additions & 0 deletions .github/ISSUE_TEMPLATES/bug_report.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Bug report
description: Report a reproducible bug in devqubit
labels: ["bug"]
body:
- type: textarea
id: what
attributes:
label: What happened?
description: Describe the bug clearly.
validations:
required: true

- type: textarea
id: repro
attributes:
label: Steps to reproduce
description: Include a minimal snippet or CLI command.
placeholder: |
1. ...
2. ...
3. ...
validations:
required: true

- type: textarea
id: expected
attributes:
label: Expected behavior
validations:
required: true

- type: input
id: version
attributes:
label: devqubit version
placeholder: e.g. 0.1.0 (or commit SHA)
validations:
required: true

- type: textarea
id: env
attributes:
label: Environment
placeholder: |
OS:
Python:
SDK (Qiskit/Braket/Cirq/PennyLane/Other):
Backend (sim/hardware):
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATES/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: Questions / Discussions
url: https://github.com/devqubit-labs/devqubit/discussions
about: Please ask questions here (Issues are for bugs and actionable requests).
- name: Security vulnerability report
url: https://github.com/devqubit-labs/devqubit/security/advisories/new
about: Please report security issues privately.
10 changes: 10 additions & 0 deletions .github/ISSUE_TEMPLATES/docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Documentation
description: Report missing/unclear docs
labels: ["documentation"]
body:
- type: textarea
id: change
attributes:
label: What should be improved?
validations:
required: true
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATES/feature_request.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Feature request
description: Suggest an improvement or new capability
labels: ["enhancement"]
body:
- type: textarea
id: problem
attributes:
label: Problem statement
description: What problem are you trying to solve?
validations:
required: true

- type: textarea
id: proposal
attributes:
label: Proposed solution
description: What would you like devqubit to do?
validations:
required: true

- type: textarea
id: context
attributes:
label: Context
description: SDK/backend setup, constraints, links to examples.
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
28 changes: 28 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Summary
What does this PR change, and why?

## Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor (no user-facing change)
- [ ] Docs only
- [ ] CI/build tooling
- [ ] Breaking change

## Related issues / context
Link issues, discussions, or prior PRs:
- Closes #

## Changelog (user-facing only)
- [ ] I added a towncrier fragment in `changelog.d/` (skip for internal-only changes)

## Checklist
- [ ] I ran lint locally (`uv run pre-commit run --all-files`)
- [ ] I ran tests locally (`uv run pytest`)
- [ ] I added/updated tests for behavior changes
- [ ] I updated docs/README/examples if needed
- [ ] If I changed dependencies, I updated `uv.lock` (`uv lock`) and committed it
- [ ] I considered backward compatibility and security impact

## Notes for reviewers
Anything tricky, non-obvious, or follow-up work?
30 changes: 20 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Thanks for your interest in contributing to **devqubit**! This guide keeps contr

- Please follow our community rules in **CODE_OF_CONDUCT.md**.
- For security issues, **do not** open a public issue (see [Security](#security)).
- Questions / support: prefer **GitHub Discussions** (Issues are for actionable bugs/requests).

## Project tooling

Expand All @@ -14,16 +15,23 @@ This repository uses:
- **pytest** for tests
- **towncrier** for changelog fragments (only for user-facing changes)

CI runs:
- `pre-commit` (lint/format)
- `pytest` on multiple Python versions (matrix)

## Quickstart

```bash
git clone <REPO_URL>
cd <REPO_DIR>
git clone https://github.com/devqubit-labs/devqubit.git
cd devqubit

# Create/update .venv and install the workspace environment.
# Create/update .venv and install the workspace environment from uv.lock.
# --all-packages installs all workspace members.
# --all-extras installs all optional dependencies (extras) for all members.
uv sync --all-packages --all-extras
# dev dependencies are synced by default (unless you opt out
uv sync --locked --all-packages

# OPTIONAL: install all extras (optional dependencies) as well
uv sync --locked --all-packages --all-extras

# Install git hooks (required)
uv run pre-commit install
Expand All @@ -38,7 +46,7 @@ uv run pytest
If you only want the core packages and want to avoid heavy adapter/UI dependencies:

```bash
uv sync --all-packages
uv sync --locked --all-packages
uv run pytest
```

Expand Down Expand Up @@ -182,21 +190,23 @@ Keep PRs focused and small when possible. If a change is large, split it into in

If you change dependencies:

1. Update the relevant `pyproject.toml`
1. Update the relevant `pyproject.toml` (or use `uv add` / `uv remove`)
2. Update the lockfile and re-sync:

```bash
uv lock
uv sync
uv sync --locked --all-packages
```

If you want to upgrade locked versions:

```bash
uv lock --upgrade
uv sync
uv sync --locked --all-packages
```

Tip: If `uv sync --locked` fails, it usually means uv.lock is out of date - run `uv lock` and commit the updated lockfile.

## Documentation

- If your change affects the CLI, update help text, docs, or examples.
Expand All @@ -215,7 +225,7 @@ When filing a bug report, please include:

Please do **not** report security vulnerabilities via public GitHub issues.

Instead, email: **info@devqubit.com**
Use GitHub “Report a vulnerability” (Private Vulnerability Reporting).

## License

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ so runs are reproducible, comparable, and easy to share.

## Documentation

📚 Read the Docs: **https://<RTD_SLUG>.readthedocs.io**
📚 Read the Docs: **https://devqubit.readthedocs.io**

The documentation source lives in this repository under `docs/`, but the canonical, rendered docs are on Read the Docs.

Expand Down
15 changes: 15 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Security Policy

## Reporting a Vulnerability

Please report security vulnerabilities privately.

Use GitHub "Report a vulnerability" (Private Vulnerability Reporting).

## Response Timeline

We aim to respond within 72 hours, and provide a fix or mitigation plan as soon as possible.

## Supported Versions

We support the latest released minor version (and the latest patch of older minors when feasible).
10 changes: 5 additions & 5 deletions docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ devqubit --version
Pick your SDK:

```bash
pip install devqubit-qiskit # IBM Qiskit (local, Aer)
pip install devqubit-qiskit-runtime # IBM Qiskit Runtime (cloud primitives)
pip install devqubit-braket # Amazon Braket
pip install devqubit-cirq # Google Cirq
pip install devqubit-pennylane # Xanadu PennyLane
pip install devqubit[qiskit] # IBM Qiskit (local, Aer)
pip install devqubit[qiskit-runtime] # IBM Qiskit Runtime (cloud primitives)
pip install devqubit[braket] # Amazon Braket
pip install devqubit[cirq] # Google Cirq
pip install devqubit[pennylane] # Xanadu PennyLane
```

## Where data is stored
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dependencies = [
Homepage = "https://devqubit.com"
Repository = "https://github.com/devqubit-labs/devqubit"
Issues = "https://github.com/devqubit-labs/devqubit/issues"
Documentation = "https://<YOUR-DOCS>"
Documentation = "https://devqubit.readthedocs.io"

[project.optional-dependencies]
# Remote storage dependencies
Expand Down
8 changes: 7 additions & 1 deletion src/devqubit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,14 @@
>>> result = verify_against_baseline(candidate, project="my_project", policy=VerifyPolicy())
>>> assert result.ok

Snapshots
---------
>>> from devqubit.snapshot import ExecutionEnvelope, DeviceSnapshot
>>> envelope = ExecutionEnvelope(device=device_snapshot, ...)

UI
------------
>>> from devqubit_ui import run_server
>>> from devqubit import run_server
>>> run_server(port=8080)

Submodules
Expand All @@ -39,6 +44,7 @@
- devqubit.ci: CI/CD integration (JUnit, GitHub annotations)
- devqubit.bundle: Run packaging utilities
- devqubit.config: Configuration management
- devqubit.snapshot: UEC snapshot schemas
"""

from __future__ import annotations
Expand Down
78 changes: 78 additions & 0 deletions src/devqubit/snapshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: 2026 devqubit

"""
Uniform Execution Contract (UEC) snapshot schemas.

This module provides standardized types for capturing quantum experiment state
across all supported SDKs. The UEC defines four canonical snapshot types plus
a unified envelope container.

Basic Usage
-----------
>>> from devqubit.snapshot import ExecutionEnvelope
>>> envelope = ExecutionEnvelope(
... device=device_snapshot,
... program=program_snapshot,
... execution=execution_snapshot,
... result=result_snapshot,
... )

Validation
----------
>>> from devqubit.snapshot import ValidationResult
>>> result = envelope.validate_schema()
>>> if result.valid:
... print("Schema valid")
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any


__all__ = [
"ExecutionEnvelope",
"DeviceSnapshot",
"ProgramSnapshot",
"ExecutionSnapshot",
"ResultSnapshot",
"ValidationResult",
]


if TYPE_CHECKING:
from devqubit_engine.core.snapshot import (
DeviceSnapshot,
ExecutionEnvelope,
ExecutionSnapshot,
ProgramSnapshot,
ResultSnapshot,
ValidationResult,
)


_LAZY_IMPORTS = {
"ExecutionEnvelope": ("devqubit_engine.snapshot", "ExecutionEnvelope"),
"DeviceSnapshot": ("devqubit_engine.snapshot", "DeviceSnapshot"),
"ProgramSnapshot": ("devqubit_engine.snapshot", "ProgramSnapshot"),
"ExecutionSnapshot": ("devqubit_engine.snapshot", "ExecutionSnapshot"),
"ResultSnapshot": ("devqubit_engine.snapshot", "ResultSnapshot"),
"ValidationResult": ("devqubit_engine.snapshot", "ValidationResult"),
}


def __getattr__(name: str) -> Any:
"""Lazy import handler."""
if name in _LAZY_IMPORTS:
module_path, attr_name = _LAZY_IMPORTS[name]
module = __import__(module_path, fromlist=[attr_name])
value = getattr(module, attr_name)
globals()[name] = value
return value
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


def __dir__() -> list[str]:
"""List available attributes."""
return sorted(set(__all__) | set(_LAZY_IMPORTS.keys()))