Blog About Contact Sign in
← Back to Blog

Capsule Specification

February 15, 2025 Marqov Team
capsulespecificationdocumentationreference

Capsule Specification

A Capsule is Marqov’s core abstraction for defining reproducible, portable compute workloads. Think of it as a declarative specification that captures everything needed to execute a hybrid quantum-classical computation: the code, dependencies, data, target hardware, and execution parameters.

Philosophy

The Problem with Ad-Hoc Execution

Traditional approaches to running quantum workloads suffer from several issues:

# The typical workflow (problematic)
$ pip install qiskit pennylane  # Which versions?
$ python my_circuit.py          # Which backend?
$ # ... weeks later ...
$ python my_circuit.py          # Different results. Why?

Without explicit specification, experiments become unreproducible. Dependencies drift, backends change, parameters get lost in notebooks, and the “it worked on my machine” problem multiplies across quantum providers.

Capsules as the Solution

A Capsule captures the complete execution context in a single, versioned document:

apiVersion: marqov.com/v1
kind: Capsule
metadata:
  name: my-vqe-experiment
  version: 1.0.0
  tags: [quantum, optimization, vqe]
spec:
  backend:
    type: quantum
    providers: [ibm_quantum, aws_braket]
    requirements:
      qubits: 4
      connectivity: linear
  environment:
    python: "3.11"
    dependencies:
      - qiskit>=1.0
      - pennylane>=0.35
  artifacts:
    - path: circuit.py
      type: source
    - path: params.json
      type: data
  execution:
    entrypoint: python circuit.py
    timeout: 3600

This specification embodies three core principles:

  1. Reproducibility: Every execution of this Capsule will use identical dependencies, parameters, and configurations
  2. Portability: The same Capsule runs on IBM Quantum, AWS Braket, or local simulators without modification
  3. Declarative Intent: You specify what you want to run, not how to configure each provider’s SDK

Schema Reference

Document Structure

Every Capsule document has four top-level fields:

FieldRequiredDescription
apiVersionYesSchema version (currently marqov.com/v1)
kindYesResource type (must be Capsule)
metadataYesIdentification and organizational data
specYesThe workload specification

Metadata

The metadata section identifies and organizes your Capsule:

metadata:
  name: my-vqe-experiment
  version: 1.0.0
  tags: [quantum, optimization, vqe]
  labels:
    team: research
    project: hydrogen-simulation
  annotations:
    description: "VQE for H2 ground state energy"
    paper: "https://arxiv.org/abs/..."

Metadata Fields

FieldRequiredTypeDescription
nameYesstringUnique identifier (lowercase, alphanumeric, hyphens)
versionYesstringSemantic version (e.g., 1.0.0, 2.1.0-beta)
tagsNoarraySearchable keywords for discovery
labelsNoobjectKey-value pairs for organization and filtering
annotationsNoobjectArbitrary metadata (descriptions, links, etc.)

Naming Conventions

Names must follow DNS subdomain rules:

  • Lowercase letters, numbers, and hyphens only
  • Must start with a letter
  • Maximum 63 characters
# Valid names
name: vqe-h2-simulation
name: qaoa-maxcut-v2
name: grover-search-4qubit

# Invalid names
name: VQE_Experiment    # Uppercase and underscore
name: 123-circuit       # Starts with number
name: my circuit        # Contains space

Spec: Backend

The backend section specifies where your workload should execute:

spec:
  backend:
    type: quantum
    providers: [ibm_quantum, aws_braket, ionq]
    requirements:
      qubits: 4
      connectivity: linear
      errorRate: 0.01
    preferences:
      priority: cost          # cost | performance | availability
      region: us-east

Backend Fields

FieldRequiredTypeDescription
typeYesstringquantum, classical, or hybrid
providersNoarrayAllowed providers (any if omitted)
requirementsNoobjectHard constraints the backend must satisfy
preferencesNoobjectSoft preferences for backend selection

Backend Types

Quantum - Executes on quantum hardware or simulators:

backend:
  type: quantum
  providers: [ibm_quantum]
  requirements:
    qubits: 8
    connectivity: heavy-hex

Classical - Executes on classical compute (HPC, GPU clusters):

backend:
  type: classical
  requirements:
    memory: 64GB
    gpu: true
    gpuMemory: 24GB

Hybrid - Requires coordinated quantum and classical resources:

backend:
  type: hybrid
  quantum:
    providers: [ibm_quantum, aws_braket]
    requirements:
      qubits: 4
  classical:
    requirements:
      memory: 32GB
      cpu: 8

Requirements

Hard constraints that backends must satisfy:

FieldTypeApplies ToDescription
qubitsintegerquantumMinimum qubit count
connectivitystringquantumlinear, ring, all-to-all, heavy-hex
errorRatefloatquantumMaximum single-qubit gate error
t1stringquantumMinimum T1 coherence time (e.g., 100us)
t2stringquantumMinimum T2 coherence time
memorystringclassicalRequired RAM (e.g., 64GB)
cpuintegerclassicalMinimum CPU cores
gpubooleanclassicalGPU required
gpuMemorystringclassicalRequired GPU memory

Preferences

Soft preferences that influence backend selection when multiple options satisfy requirements:

preferences:
  priority: performance  # cost | performance | availability
  region: us-east       # Prefer specific region
  queue: express        # Queue/tier preference

Spec: Environment

The environment section defines the software runtime:

spec:
  environment:
    python: "3.11"
    dependencies:
      - qiskit>=1.0,<2.0
      - pennylane>=0.35
      - numpy>=1.24
      - scipy>=1.11
    system:
      - libopenblas-dev
    variables:
      QISKIT_IN_PARALLEL: "TRUE"
      OMP_NUM_THREADS: "4"

Environment Fields

FieldRequiredTypeDescription
pythonNostringPython version (default: 3.11)
dependenciesNoarrayPython packages (pip format)
systemNoarraySystem packages (apt format)
variablesNoobjectEnvironment variables
requirementsNostringPath to requirements.txt file

Dependency Specification

Dependencies use standard pip version specifiers:

dependencies:
  # Exact version
  - qiskit==1.0.2

  # Minimum version
  - pennylane>=0.35

  # Version range
  - numpy>=1.24,<2.0

  # Any version
  - matplotlib

  # Git dependency
  - git+https://github.com/org/repo.git@v1.0.0

  # Local wheel (relative to Capsule)
  - ./wheels/custom_package-1.0-py3-none-any.whl

Using requirements.txt

For complex dependency sets, reference an external file:

environment:
  python: "3.11"
  requirements: requirements.txt

The requirements.txt is then included as an artifact.

Spec: Artifacts

The artifacts section declares files included with the Capsule:

spec:
  artifacts:
    - path: circuit.py
      type: source
      description: "Main VQE circuit implementation"

    - path: params.json
      type: data
      description: "Initial variational parameters"

    - path: results/
      type: output
      description: "Directory for output files"

    - path: requirements.txt
      type: config

Artifact Fields

FieldRequiredTypeDescription
pathYesstringRelative path to file or directory
typeYesstringArtifact type (see below)
descriptionNostringHuman-readable description
checksumNostringSHA-256 hash for integrity verification

Artifact Types

TypeDescriptionExamples
sourceSource code files.py, .qasm, .ipynb
dataInput data files.json, .csv, .h5
configConfiguration files.yaml, .toml, requirements.txt
modelTrained models or parameters.pkl, .pt, .safetensors
outputOutput directories (created at runtime)results/, logs/

Integrity Verification

For reproducibility, include checksums:

artifacts:
  - path: pretrained_params.pkl
    type: model
    checksum: sha256:a1b2c3d4e5f6...

Marqov verifies checksums before execution, ensuring you run exactly what you expect.

Spec: Execution

The execution section defines how to run the workload:

spec:
  execution:
    entrypoint: python circuit.py
    args:
      - --shots=8192
      - --optimizer=COBYLA
    timeout: 3600
    retries: 3
    resources:
      shots: 8192
      maxCircuits: 100

Execution Fields

FieldRequiredTypeDescription
entrypointYesstringCommand to execute
argsNoarrayCommand-line arguments
timeoutNointegerMaximum execution time in seconds
retriesNointegerRetry count on failure
resourcesNoobjectResource limits and quotas
hooksNoobjectLifecycle hooks

Entrypoint Patterns

The entrypoint can be specified several ways:

# Direct Python script
entrypoint: python circuit.py

# Module execution
entrypoint: python -m mypackage.main

# Jupyter notebook
entrypoint: papermill input.ipynb output.ipynb

# Shell script
entrypoint: bash run.sh

# With inline arguments
entrypoint: python circuit.py --config config.yaml

Resource Limits

Control quantum resource consumption:

resources:
  shots: 8192           # Shots per circuit execution
  maxCircuits: 100      # Maximum circuits per job
  maxQubits: 8          # Maximum qubits to use
  estimatedRuntime: 30m # Hint for scheduling

Lifecycle Hooks

Execute code at specific points:

hooks:
  preExecution:
    - python setup.py prepare
  postExecution:
    - python collect_results.py
  onFailure:
    - python notify.py --status=failed

Advanced Features

Parameterization

Capsules support parameter injection for experimentation:

apiVersion: marqov.com/v1
kind: Capsule
metadata:
  name: vqe-sweep
  version: 1.0.0
spec:
  parameters:
    - name: num_layers
      type: integer
      default: 4
      description: "Ansatz circuit depth"
    - name: optimizer
      type: string
      default: COBYLA
      enum: [COBYLA, SPSA, ADAM]
    - name: shots
      type: integer
      default: 8192

  execution:
    entrypoint: python circuit.py
    args:
      - --layers={{ num_layers }}
      - --optimizer={{ optimizer }}
      - --shots={{ shots }}

Execute with different parameters:

marqov run vqe-sweep.yaml --set num_layers=8 --set optimizer=SPSA

Multi-Stage Workflows

Define complex workflows with multiple stages:

apiVersion: marqov.com/v1
kind: Capsule
metadata:
  name: vqe-full-pipeline
  version: 1.0.0
spec:
  stages:
    - name: prepare
      backend:
        type: classical
      execution:
        entrypoint: python prepare_hamiltonian.py
      outputs:
        - hamiltonian.json

    - name: optimize
      backend:
        type: hybrid
      dependencies:
        - prepare
      execution:
        entrypoint: python run_vqe.py
      outputs:
        - optimal_params.json

    - name: analyze
      backend:
        type: classical
      dependencies:
        - optimize
      execution:
        entrypoint: python analyze_results.py

Provider-Specific Overrides

When backends require specific configuration:

spec:
  backend:
    type: quantum
    providers: [ibm_quantum, aws_braket]

  overrides:
    ibm_quantum:
      instance: "ibm-q/open/main"
      resilience_level: 1
      transpilation:
        optimization_level: 3

    aws_braket:
      device: "arn:aws:braket:us-east-1::device/qpu/ionq/Aria-1"
      disable_qubit_rewiring: false

Overrides are applied only when executing on the matching provider, keeping your Capsule portable while allowing provider-specific optimization.

Versioning

Semantic Versioning

Capsules use semantic versioning (MAJOR.MINOR.PATCH):

metadata:
  name: my-experiment
  version: 1.2.3
  • MAJOR: Breaking changes (different algorithm, incompatible outputs)
  • MINOR: New features (additional outputs, new parameters)
  • PATCH: Bug fixes (same inputs produce same outputs)

Version Constraints

Reference specific versions or ranges:

# Exact version
marqov run my-experiment@1.2.3

# Latest patch
marqov run my-experiment@1.2

# Latest minor
marqov run my-experiment@1

# Latest
marqov run my-experiment@latest

Immutability

Published Capsule versions are immutable. Once my-experiment@1.0.0 exists:

  • It cannot be modified or overwritten
  • The same specification always produces the same execution
  • Results are traceable to exact Capsule versions

To make changes, increment the version number.

Complete Example

Here’s a production-ready Capsule for a VQE chemistry simulation:

apiVersion: marqov.com/v1
kind: Capsule
metadata:
  name: h2-ground-state-vqe
  version: 2.1.0
  tags: [quantum-chemistry, vqe, hydrogen]
  labels:
    team: chemistry
    project: molecular-simulation
  annotations:
    description: "VQE calculation for H2 ground state energy"
    paper: "https://arxiv.org/abs/2024.xxxxx"
    contact: "quantum-team@example.com"

spec:
  parameters:
    - name: bond_distance
      type: float
      default: 0.735
      description: "H-H bond distance in Angstroms"
    - name: ansatz_layers
      type: integer
      default: 2
      description: "Number of variational layers"
    - name: shots
      type: integer
      default: 8192
      description: "Measurement shots per circuit"

  backend:
    type: hybrid
    quantum:
      providers: [ibm_quantum, aws_braket]
      requirements:
        qubits: 4
        connectivity: linear
      preferences:
        priority: performance
    classical:
      requirements:
        memory: 8GB
        cpu: 4

  environment:
    python: "3.11"
    dependencies:
      - qiskit>=1.0,<2.0
      - qiskit-nature>=0.7
      - pyscf>=2.4
      - numpy>=1.24
      - scipy>=1.11
      - h5py>=3.9
    variables:
      QISKIT_IN_PARALLEL: "TRUE"
      OMP_NUM_THREADS: "4"

  artifacts:
    - path: src/vqe_runner.py
      type: source
      description: "Main VQE implementation"
    - path: src/ansatz.py
      type: source
      description: "Ansatz circuit definitions"
    - path: src/hamiltonian.py
      type: source
      description: "Molecular Hamiltonian construction"
    - path: config/default_params.json
      type: config
      description: "Default initial parameters"
    - path: results/
      type: output
      description: "Output directory for results"

  execution:
    entrypoint: python src/vqe_runner.py
    args:
      - --bond-distance={{ bond_distance }}
      - --layers={{ ansatz_layers }}
      - --shots={{ shots }}
      - --output=results/
    timeout: 7200
    retries: 2
    resources:
      shots: 8192
      maxCircuits: 200
    hooks:
      postExecution:
        - python src/validate_results.py results/

  overrides:
    ibm_quantum:
      resilience_level: 2
      transpilation:
        optimization_level: 3
        approximation_degree: 0.95

Validation

Before execution, Marqov validates Capsules against the schema:

marqov validate my-capsule.yaml

Common validation errors:

ErrorCauseFix
Invalid nameName contains invalid charactersUse lowercase, numbers, hyphens only
Missing required fieldRequired field not specifiedAdd the missing field
Unknown fieldTypo or unsupported fieldCheck spelling, consult schema
Invalid versionVersion not semanticUse MAJOR.MINOR.PATCH format
Artifact not foundReferenced file doesn’t existVerify file path and existence

Best Practices

1. Pin Dependencies

# Good: Reproducible
dependencies:
  - qiskit==1.0.2
  - numpy==1.24.3

# Risky: May change
dependencies:
  - qiskit
  - numpy

2. Use Checksums for Critical Files

artifacts:
  - path: trained_model.pkl
    type: model
    checksum: sha256:a1b2c3...

3. Document Parameters

parameters:
  - name: learning_rate
    type: float
    default: 0.01
    description: "Classical optimizer learning rate. Lower values converge slower but more reliably."

4. Set Reasonable Timeouts

execution:
  timeout: 3600  # 1 hour
  # Not: timeout: 86400  # 24 hours (too long, hides problems)
  # Not: timeout: 60     # 1 minute (too short for real quantum)

5. Organize Artifacts

my-capsule/
  capsule.yaml
  src/
    main.py
    utils.py
  config/
    params.json
  data/
    input.csv
  results/          # Output directory

Ready to create your first Capsule? Get started with Marqov or explore example Capsules.