feat(#160): Pasqal device path — per-solve device selection + mandatory non-free confirm gate - #187
Merged
Merged
Conversation
Port the pulse contract, its hermetic test suite, and the demos from the kate/pasqal-cloud-connectivity spike onto the product connector dir (packages/extension/scripts/pasqal-connector), beside the #164 validator. - pulse_contract.py: the single source of truth for pulse.toml → validated Pulser Sequence — device limits read from the Device at call time, real constraint violations RAISE, sub-DUST_TOL optimizer dust clipped silently. - translate_and_simulate.py: local QuTiP re-simulation (the physics oracle). - tests/test_pulse_contract.py + tests/fixtures/pulse_golden.toml: the AC2 contract gate — schema/device/atoms rejections + golden-fixture simulation. - demos/: the spike's solve_*.jl + *_demos.py (demos stay demos; scope Out). Gate: `python3 -m unittest discover -s tests -p test_pulse_contract.py` → 27 pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… AC5) The device-path submission connector, adapted from the spike's submit_optimized.py. Whereas the spike authenticated with username/password on env, this connector takes the runtime credential as a TOKEN only (PASQAL_TOKEN + PASQAL_PROJECT_ID via the amico-pasqal launcher's env injection) and authenticates through the SDK's token-provider mechanism (a TokenProvider subclass whose get_token() returns the stored token). No password/username exists anywhere in the flow (AC3). - Per-submission device selection (--device); the default only ever picks the FREE emulator (EMU_FREE), never a paid target — no auto-fallback. - Paid-submission gate, defense in depth (AC5): a non-free device is refused BEFORE any auth/network unless the caller passes --yes; unknown devices rejected (real-QPU job management is out of scope). - Secret hygiene: fixed failure strings only; exception text (which can echo a bearer token) is never printed — proven by a poison-token leak test. - --dry-run builds + validates the sequence with no credentials or network. TDD: tests/test_submit_cli.py written first (12 tests, red → green). Full connector suite `python3 -m unittest discover -s tests` → 55 pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…te (AC1/AC3/AC4/AC5)
The agent-driven device path, wired behind the Pasqal Connection. Two
subcommands on the `amico` CLI:
amico pasqal devices
lists the devices the connection exposes (each tagged free/non-free),
read ONLY from the non-secret connections status cache
($AMICODE_CONNECTIONS_FILE — exactly what the fork's connections route
writes). Never opens the token file, never spawns the validator.
amico pasqal submit --device <id> --artifact <pulse.toml> [--confirm <h>] [--dry-run]
routes ONE solve's pulse to ONE explicitly chosen Device.
AC1: pick a device from the persisted device metadata + submit (through the
amico-pasqal launcher). --device is mandatory; nothing auto-selects.
AC3: token safety — the verb spawns the amico-pasqal launcher as a SUBPROCESS,
so its own process never reads ~/.amico/pasqal.json; the launcher is the
one place the token is read + env-injected. No token appears in the
digest, JSON output, or launcher argv (proven by a poison-token test that
also plants a poison "token" key in the cache — scrubbed by whitelist read).
AC4: a disconnected connection, an expired token, and an empty-or-stale device
list each disable the path with a distinct, actionable block (reconnect /
revalidate), non-zero exit — never a silent failure.
AC5: the MANDATORY paid-confirm gate — a NON-FREE (paid emulator / real QPU)
target is REFUSED unless --confirm matches the secret-free submission
digest (bound to device + pulse content + project). Checked BEFORE
--dry-run and BEFORE any spawn; a wrong/absent confirm never spawns; there
is no auto-fallback to a paid target. Default-deny: only EMU_FREE is free.
Flag is --artifact (not --pulse) to respect the S31 physics-flag guard, matching
catalog_verb's pulse-artifact idiom.
TDD: test/pasqal_verb.test.ts written first (23 tests incl. adversarial
gate-bypass + token-leak), red → green. Gates: amico-run vitest 337 pass,
tsc --noEmit clean, prettier clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #160. The agent-driven Pasqal device path: pick a device exposed by an existing Pasqal Connection and route one solve's pulse to it, with a mandatory confirm gate before any non-free (paid emulator / real QPU) run. Two
amicosubcommands:amico pasqal devices— lists the devices the connection exposes, each tagged free / non-free. Read only from the non-secret connections status cache ($AMICODE_CONNECTIONS_FILE— exactly what the fork's connections route writes). Never opens the token file, never spawns the validator.amico pasqal submit --device <id> --artifact <pulse.toml> [--confirm <h>] [--dry-run]— routes one solve to one explicitly chosen device.Acceptance criteria
--deviceis mandatory; nothing auto-selects. Device metadata comes from the persisted cache.amico-pasqallauncher as a subprocess, so its own process never reads~/.amico/pasqal.json; the launcher is the sole token reader + env-injector. No token appears in the digest, JSON output, or launcher argv. Auth is via the SDK token-provider (token only — no username/password anywhere). Proven by poison-token leak tests on both the TS verb and the Python connector.--confirmmatches the secret-free submission digest (bound to device + pulse content + project), checked before--dry-runand before any spawn. Default-deny: onlyEMU_FREEis free; no auto-fallback to a paid target. Defense-in-depth: the Python connector independently re-guards paid submissions (--yes).Testing
tsc --noEmitclean · prettier cleanpython3 -m unittest discover -s tests; +12 submit-CLI, pulse-contract golden)Notes
--artifact(not--pulse) to respect the S31 physics-flag guard, matchingcatalog_verb's pulse-artifact idiom.🤖 Generated with Claude Code