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
19 changes: 16 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,28 @@ jobs:
- run: npm pack --dry-run

variaq-integration:
name: VariaQ 0.6.0 integration
name: VariaQ ${{ matrix.variaq_version }} integration
strategy:
fail-fast: false
matrix:
include:
- variaq_version: "0.6.0"
# Commit behind the verified legacy v0.6.0 tag.
variaq_ref: aeac83b67a9874957458d626c81ba231030f90ab
- variaq_version: "0.8.0rc1"
# Reviewed release/0.8.0rc1 candidate; never use a moving branch.
variaq_ref: 551151a2c2ccfe0301dca1b22fcc8abf5d540f56
- variaq_version: "0.8.0"
# VariaQ 0.8.0 stable merge commit on main; never use a moving branch.
variaq_ref: 2c7ca9c488a5aea91575ec0a95e2111adeb2a0a2
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v6
with:
repository: aaronphifer/variaq
# Immutable release tag for the verified VariaQ 0.6.x integration.
ref: v0.6.0
ref: ${{ matrix.variaq_ref }}
path: .variaq-source
- uses: actions/setup-node@v7
with:
Expand All @@ -56,4 +68,5 @@ jobs:
env:
VARIAQ_TEST_PROJECT: ${{ github.workspace }}/.variaq-source
VARIAQ_TEST_PYTHON: ${{ runner.temp }}/variaq-venv/bin/python
VARIAQ_TEST_VERSION: ${{ matrix.variaq_version }}
run: npm run test:integration
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@

All notable changes to this project will be documented in this file.

## 0.5.1 - Unreleased
## 0.6.0 - Unreleased

Maintenance-only release.
Unreleased compatibility update.

- Accept stable VariaQ 0.8.x series releases and the tested 0.8.0rc1 candidate while retaining 0.6.x and schema-v1 support; paired_solvers comparisons unlock on stable VariaQ 0.8.x.
- Prepare an immutable stable VariaQ 0.8.0 integration CI leg (pin the stable tag SHA when the VariaQ stable branch is pushed).
- Pin the transitive development dependency `source-map-js` to 1.2.2 (GHSA-68fv-2mgg-jv7q) via a narrowly scoped npm override; runtime dependencies remain clean. The five remaining development advisories live inside `node_modules/npm` bundled dependencies that npm overrides cannot reach; they require an upstream npm/bb-app refresh and do not affect the shipped plugin.
- Accept the tested VariaQ 0.8.0rc1 candidate while retaining stable 0.6.x support and schema-v1 validation; preserve candidate suffixes and reject unverified versions.
- Target BB 0.46 / Plugin SDK 0.6.37, update build dependencies, and verify real local integration with both VariaQ 0.6.0 and 0.8.0rc1.
- Forward paired_solvers through existing campaign analysis/report tools and CLI, including expanded CSV paths, without plugin-side science. Reject unsupported run-comparison requests clearly.
- Validate canonical nested campaign solver parameters, including numeric candidate matrices, using non-recursive tool schemas.
- Keep GPU integration explicitly opt-in with VARIAQ_TEST_GPU=1, independently of CUDA-Q CPU tests.
- Run hosted legacy and candidate integration against immutable VariaQ commit pins.
- Document the six development-toolchain audit findings separately from runtime dependencies.

- Fix duplicated plot-format requests in `variaq_report_campaign` when both `formats: ["plots"]` and `plots: true` are supplied; `formats` is now canonical and `plots: true` only ensures "plots" appears once.
- Update GitHub Actions to Node 24-native action versions (`actions/checkout@v6`, `actions/setup-node@v7`, `actions/setup-python@v7`) to resolve Node 20 deprecation warnings while preserving existing workflow behavior.
Expand Down
16 changes: 15 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,20 @@ solver installation.

## Real VariaQ integration

Install VariaQ 0.2.0 separately with Python 3.12 and its `quantum` extra, then
Install VariaQ 0.6.0 or the local 0.8.0rc1 candidate separately with Python 3.12 and its `quantum` extra, then
run:

```bash
VARIAQ_TEST_PROJECT=/path/to/variaq \
VARIAQ_TEST_PYTHON=/path/to/variaq/.venv/bin/python \
VARIAQ_TEST_VERSION=0.8.0rc1 \
npm run test:integration
```

To validate the stable VariaQ 0.8.0 release instead, point
`VARIAQ_TEST_VERSION=0.8.0` at the pinned stable-tag checkout (the exact commit
SHA is pinned at release time, mirroring the CI matrix placeholder).

These tests cover the CLI contract and local exact, heuristic, and Qiskit
flows. They must not reimplement VariaQ solver-correctness tests.

Expand All @@ -39,10 +44,14 @@ CUDA-Q is optional. On a compatible local or self-hosted machine:
```bash
VARIAQ_TEST_PROJECT=/path/to/variaq \
VARIAQ_TEST_PYTHON=/path/to/variaq/.venv/bin/python \
VARIAQ_TEST_VERSION=0.8.0rc1 \
VARIAQ_TEST_CUDAQ=1 \
npm run test:integration
```

GPU integration additionally requires `VARIAQ_TEST_GPU=1`. Set the expected
version to `0.6.0` when validating the legacy tagged checkout.

Use `npm run smoke` for a deterministic installed-plugin workflow. GPU work is
opt-in with `VARIAQ_SMOKE_GPU=1`; neither physical-QPU nor remote-provider tests
belong in the plugin's required CI.
Expand All @@ -56,3 +65,8 @@ belong in the plugin's required CI.
BB, or Plugin SDK versions.
- Do not commit local settings, experiment databases, generated problems,
credentials, dependency directories, coverage, logs, or build output.

CI runs the legacy and candidate integration suite against the immutable VariaQ
commit pins in `.github/workflows/ci.yml`. Keep `VARIAQ_TEST_VERSION` matched to
each source revision. A candidate pin must come from reviewed release-branch
code; do not substitute main, v0.7, a moving candidate branch, or an unverified build.
76 changes: 57 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ logic — VariaQ remains authoritative for all of these.

## Prerequisites

- BB 0.43.x with Plugin SDK 0.4.104
- BB 0.46.x with Plugin SDK 0.6.37
- Node.js 22.19 or a compatible version supported by BB
- Linux-native Python 3.12
- a separate VariaQ 0.6.x installation; 0.6.0 is the verified version
- a separate VariaQ 0.6.x installation or the local 0.8.0rc1 candidate

Create a VariaQ environment separately from this repository:

Expand Down Expand Up @@ -179,20 +179,48 @@ prose parsing or run-ID scraping.

## Version compatibility

The verified combination is:

```text
bb-plugin-variaq 0.5.0
VariaQ 0.6.0
Plugin SDK 0.4.104
BB host 0.43.x
VariaQ schema 1
The current checkout targets BB 0.46.x / Plugin SDK 0.6.37 and schema version `1`.
It accepts stable VariaQ 0.6.x and 0.8.x series releases plus the explicitly
tested `0.8.0rc1` candidate. Real local integration was verified against the
immutable `v0.6.0` tag and the reviewed v0.8 candidate checkout. Patch
acceptance within 0.6.x and 0.8.x is a version policy; every patch was not
independently executed. VariaQ 0.5.x, 0.7.x, 0.9.x, other release candidates
(including rc2 and later) and future schemas remain unsupported. A suffix is
never silently stripped from a version. Status/version report unsupported
environments with a warning; schema parsing still rejects non-v1 output. This
does not authorize running an unverified version.

The BB engine/SDK pins have moved from BB 0.43 / SDK 0.4.104 to the actual BB
0.46 host. Old BB 0.43 host compatibility is not claimed. Package identity is
`0.6.0` (unreleased); this work does not publish a plugin or a VariaQ release.

### Paired-solver analysis in the 0.8 series

On verified VariaQ 0.8.x stable releases and the tested `0.8.0rc1` candidate,
existing `variaq_analyze_campaign` and `variaq_report_campaign` tools accept
`compare: "paired_solvers"`; CLI equivalents accept `--compare paired_solvers`.
This forwards VariaQ's analysis, including instances, pairs, precision,
repeat/seed controls, null/reason values and timing scopes. Reports forward all
generated paths, including per-run, pair and repeat CSVs. The plugin computes
no objectives, gaps, pairing, timings or speedups.

```sh
bb variaq analyze-campaign CAMPAIGN_ID --compare paired_solvers --json
bb variaq report-campaign CAMPAIGN_ID --output-dir paired --formats json,csv,markdown --compare paired_solvers --json
```

bb-plugin-variaq 0.5.x is verified against VariaQ 0.6.x and schema version `1`.
Patch releases within the 0.5 plugin series and 0.6 VariaQ series are accepted.
Other VariaQ series or future schema versions are reported as unsupported with a
clear compatibility error.
Canonical campaign overrides use `solver_config: {qaoa: {seed: 42,
parameters: {p: 1, optimizer_trials: 2, shots: 32, warmup: false,
candidate_parameters: [[0.5, 0.25], [0.8, 0.4]]}}}`. Scalar controls, scalar
lists and numeric matrices are validated without recursive agent-tool schemas.
Legacy flat scalar override shapes remain accepted; VariaQ remains authoritative
about their interpretation. No backend math or optimizer is duplicated here.

VariaQ's `analyze runs` CLI has no `--compare` contract. Use ordinary run analysis
for explicit run selections, and a stored campaign for comparisons. Unsupported
run-comparison requests receive a clear error. Paired campaign/report requests
on 0.6.x also fail clearly, without fallback or solver execution. Legacy campaign
comparison modes remain available on both supported versions.

## CUDA-Q and GPU behavior

Expand Down Expand Up @@ -271,7 +299,7 @@ Starting with bb-plugin-variaq 0.5.0 and VariaQ 0.6.0:

## Limitations

- VariaQ 0.6.0 provides local execution only; there is no physical-QPU path.
- Supported VariaQ versions provide local execution only; there is no physical-QPU path.
- There is no IBM Runtime/provider integration and no credential handling.
- Generic CI does not require CUDA-Q, an NVIDIA GPU, a physical QPU, or remote
services.
Expand Down Expand Up @@ -312,22 +340,32 @@ npm pack --dry-run
```

Real integration tests use `VARIAQ_TEST_PROJECT` and `VARIAQ_TEST_PYTHON` when
set. They default to the local development checkout. Optional CUDA-Q CPU tests
run only with `VARIAQ_TEST_CUDAQ=1`:
set. With neither set, real tests are skipped. `VARIAQ_TEST_VERSION` is an
explicit expected version (default `0.6.0` for tagged CI). Use `0.8.0rc1` for
the candidate. Optional CUDA-Q CPU tests require `VARIAQ_TEST_CUDAQ=1`; GPU
execution separately requires `VARIAQ_TEST_GPU=1`:

```bash
VARIAQ_TEST_PROJECT=/path/to/variaq \
VARIAQ_TEST_PYTHON=/path/to/variaq/.venv/bin/python \
VARIAQ_TEST_VERSION=0.8.0rc1 \
VARIAQ_TEST_CUDAQ=1 \
npm run test:integration
```

The normal GitHub Actions plugin job uses the deterministic fake CLI. A
separate Linux integration job checks out the immutable VariaQ `v0.6.0` tag,
separate Linux integration matrix checks out immutable commits for VariaQ `v0.6.0`
and the reviewed `release/0.8.0rc1` candidate,
installs `.[quantum]`, exercises local classical/Qiskit workflows, and runs a
bounded campaign plan/run, analysis, and report-generation smoke. CUDA-Q, GPU,
and matplotlib verification remain manual or suitable for a future self-hosted
runner.
runner. Candidate integration is pinned to VariaQ commit
`551151a2c2ccfe0301dca1b22fcc8abf5d540f56`; CI asserts the expected version.
Update this reviewed pin explicitly when the VariaQ candidate changes.
The existing public-SDK scanner test remains skipped because its string scanner
reports command strings as imports; typecheck/build and live registration remain
active checks. Linux local integration is verified; Windows plugin execution is
not claimed. The fake executable harness currently uses POSIX executable symlinks.

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution boundaries and
[SECURITY.md](SECURITY.md) for the subprocess security model.
Expand Down
40 changes: 40 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,43 @@ it is enabled. Otherwise contact the repository owner privately through their
published profile contact. Do not include active secrets or sensitive system
data in a public issue. No project-specific private security email is currently
published.

## Candidate execution and reports

Paired analysis uses stored campaigns and VariaQ-derived evidence only; it does
not execute solvers. Reports remain beneath the configured output root with
component-by-component directory symlink rejection and VariaQ's artifact guards.
A subprocess timeout sends termination and escalates to a kill; completed v0.8
attempts remain persisted, but an in-flight native result may be lost. The plugin
never resumes or automatically retries work. Independently running CLI campaigns
are not coordinated by VariaQ's web-worker lock. Keep one execution owner.

Supported versions are a compatibility policy, not permission for physical-QPU
execution. No new credentials, external execution, shell, or arbitrary analytics
code is introduced by candidate compatibility.

## Candidate dependency review

The candidate lockfile audit reports six affected development packages (four
high, two moderate); `npm audit --omit=dev` reports zero affected production
packages. These are real upstream advisories, not a claim that development use
is harmless. The plugin runtime imports Zod and Node built-ins, invokes local
Python with argument arrays, and does not call the affected libraries directly.

| Locked package | Development dependency path | Advisory exposure |
| --- | --- | --- |
| brace-expansion 5.0.9 | bb-app → npm → minimatch | [Stack/CPU exhaustion from hostile brace patterns](https://github.com/advisories/GHSA-qhr7-859c-m2p7) |
| http-cache-semantics 4.2.0 | bb-app → npm → make-fetch-happen | [Cross-user cached response disclosure with max-stale](https://github.com/advisories/GHSA-ch52-4w7c-c8xp) |
| ip-address 10.5.0 | bb-app → npm → proxy/SOCKS tooling | [Incorrect address classifiers/subnet checks](https://github.com/advisories/GHSA-j6r3-76f7-8jcv), plus unbounded diagnostic input |
| postcss-selector-parser 7.1.4 | bb-app → npm → dependency query tooling | [CPU exhaustion from hostile selectors](https://github.com/advisories/GHSA-rj75-hqrm-r3gf) |
| source-map-js 1.2.1 | vitest → vite → postcss | [Event-loop exhaustion from hostile indexed source maps](https://github.com/advisories/GHSA-68fv-2mgg-jv7q) |
Comment thread
aaronphifer marked this conversation as resolved.
Resolved
| undici 6.28.0 | bb-app → npm → download/build tooling | [WebSocket denial of service](https://github.com/advisories/GHSA-rfgv-xxqx-mfg5), plus retry-interceptor response splitting |

The reviewed plugin surfaces expose no user-controlled glob, HTTP cache/proxy,
CSS/source-map parsing or WebSocket path into these packages. Exploitability in
npm/build/test tooling depends on its inputs and configuration; hostile package
metadata, network peers and development assets remain relevant risks. This review
does not audit BB host internals or establish that these advisories are unreachable
in every development invocation. Use isolated CI/cache environments and review
narrow compatible dependency fixes before a broad public release. No forced audit
fix, broad upgrade or suppression was applied.
13 changes: 8 additions & 5 deletions lib/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,14 +616,17 @@ export interface VariaqVersionCompatibility {
}

/**
* bb-plugin-variaq 0.5.0 is verified against VariaQ 0.6.0 / schema_version 1.
* Patch releases in the 0.6 series are accepted. Other series are reported as
* Accept stable VariaQ 0.6.x and 0.8.x series releases and the explicitly
* tested 0.8.0rc1 candidate. Other versions and candidates are reported as
* unsupported so users can still inspect a mismatched environment.
*/
export function checkVariaqVersion(raw: string | null, schemaVersion?: string): VariaqVersionCompatibility {
const match = raw?.match(/(?:^|\s)(\d+)\.(\d+)\.(\d+)(?:\b|$)/);
const version = match ? `${match[1]}.${match[2]}.${match[3]}` : null;
const supported = match?.[1] === "0" && match?.[2] === "6";
const match = raw?.trim().match(/^(?:variaq\s+)?(\d+)\.(\d+)\.(\d+)(rc\d+)?$/);
const version = match ? `${match[1]}.${match[2]}.${match[3]}${match[4] ?? ""}` : null;
const supported =
(match?.[1] === "0" && match?.[2] === "6" && !match?.[4]) ||
(match?.[1] === "0" && match?.[2] === "8" && !match?.[4]) ||
version === "0.8.0rc1";
const schemaVersionSupported = schemaVersion === undefined || schemaVersion === SUPPORTED_SCHEMA_VERSION;

const parts: string[] = [];
Expand Down
22 changes: 17 additions & 5 deletions lib/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,14 @@ export function isProblemFamily(value: string): value is ProblemFamily {

export const campaignSolverOverrideSchema = z.record(
z.string(),
z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number()]))])),
z.object({
seed: z.number().int().min(0).optional(),
parameters: z.record(z.string(), z.union([
z.string(), z.number(), z.boolean(), z.null(),
z.array(z.union([z.string(), z.number(), z.boolean(), z.null()])),
z.array(z.array(z.number())),
])).optional(),
}).catchall(z.union([z.string(), z.number(), z.boolean(), z.array(z.union([z.string(), z.number()]))])),
);

export const campaignDefinitionSchema = z.object({
Expand Down Expand Up @@ -148,6 +155,11 @@ export const campaignListItemSchema = z.object({
created_at: z.string(),
});

export const comparisonTypeSchema = z.enum([
"classical_vs_quantum", "qiskit_vs_cudaq", "gpu_vs_cpu", "paired_solvers",
]);
export type ComparisonType = z.infer<typeof comparisonTypeSchema>;

export const analyzeQuerySchema = z.object({
run_ids: z.array(z.string()).optional(),
campaign_id: z.string().optional(),
Expand All @@ -156,7 +168,7 @@ export const analyzeQuerySchema = z.object({
scaling_x: z.string().optional(),
include_failed: z.boolean().optional(),
include_unavailable: z.boolean().optional(),
compare: z.enum(["classical_vs_quantum", "qiskit_vs_cudaq", "gpu_vs_cpu"]).optional(),
compare: comparisonTypeSchema.optional(),
});

export type AnalyzeQuery = z.infer<typeof analyzeQuerySchema>;
Expand All @@ -176,9 +188,9 @@ export interface ParsedEnvelope {
export const SUPPORTED_SCHEMA_VERSION = "1";

/** Compatibility metadata, mirrored here for the schema module. */
export const BB_PLUGIN_VARIAQ_VERSION = "0.5.1";
export const VERIFIED_VARIAQ_VERSION = "0.6.0";
export const SUPPORTED_VARIAQ_SERIES = "0.6.x";
export const BB_PLUGIN_VARIAQ_VERSION = "0.6.0";
export const VERIFIED_VARIAQ_VERSION = "0.8.0";
export const SUPPORTED_VARIAQ_SERIES = "0.6.x, 0.8.x and 0.8.0rc1";

/**
* Validate a VariaQ JSON envelope.
Expand Down
Loading
Loading