# Sub-plan 1 — Foundation (Tasks 1–3) > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development or superpowers:executing-plans. **Goal:** Cargo bootstrap + error types + domain newtypes + Backend trait hierarchy. Produces a compiling skeleton with all dependencies resolved. **Starting state:** Greenfield — only `CLAUDE.md`, `.gitignore`, and `docs/` exist. No `src/`, no `Cargo.toml`. **Deliverable:** `cargo test` exits 0. Three commits in git history. **Tech Stack:** Rust 2021, `rmcp` (git), `oq3_semantics 0.7`, `spinoza 0.5`, `tokio`, `serde`, `thiserror 2`, `tracing`. **Main plan reference:** `docs/superpowers/plans/2026-04-28-quantum-bridge-mcp-v1.md` Tasks 1–3. --- ## Task 1: Bootstrap **Files:** - Create: `Cargo.toml` - Create: `src/main.rs` (via `cargo new`) - [ ] **Step 1: Initialise project** ```bash cd /home/vincent/src/misc/quantum-bridge-mcp cargo new --name quantum-bridge-mcp . ``` Expected: `src/main.rs` and `Cargo.toml` created. - [ ] **Step 2: Write Cargo.toml** > Run `cargo search spinoza` and `cargo search oq3_semantics` to confirm latest patch versions before pinning. ```toml [package] name = "quantum-bridge-mcp" version = "0.1.0" edition = "2021" description = "Zero-dependency MCP server for local OpenQASM 3.0 quantum circuit simulation" license = "MIT" [dependencies] rmcp = { git = "https://github.com/modelcontextprotocol/rust-sdk", features = ["server", "transport-io", "macros"] } oq3_semantics = "0.7" spinoza = "0.5" tokio = { version = "1", features = ["full"] } serde = { version = "1", features = ["derive"] } serde_json = "1" schemars = "0.8" thiserror = "2" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } anyhow = "1" [dev-dependencies] proptest = "1" criterion = { version = "0.5", features = ["html_reports"] } [[bench]] name = "simulation" harness = false ``` - [ ] **Step 3: Write minimal src/main.rs** ```rust fn main() { println!("quantum-bridge-mcp"); } ``` - [ ] **Step 4: Verify dependencies compile** ```bash cargo build ``` Expected: success (first run ~200 MB). If a version constraint fails, run `cargo search ` and adjust. - [ ] **Step 5: Commit** ```bash git add Cargo.toml Cargo.lock src/main.rs git commit -m "chore: bootstrap project with all V1 dependencies" ``` --- ## Task 2: Foundation — Error types and domain newtypes **Files:** - Create: `src/error.rs` - Create: `src/types.rs` - Modify: `src/main.rs` - [ ] **Step 1: Write src/error.rs** ```rust use thiserror::Error; #[derive(Debug, Error)] pub enum BridgeError { #[error("parse error at line {line}, col {col}: {message}")] Parse { line: usize, col: usize, message: String }, #[error("gate '{gate}' is not supported at line {line} — supported: {supported}")] UnsupportedGate { gate: String, line: usize, supported: String }, #[error("qubit index {index} is out of range (circuit declares {declared} qubits)")] QubitOutOfRange { index: usize, declared: usize }, #[error("circuit requires {requested} qubits, exceeds the local simulator limit of {limit}")] QubitLimitExceeded { requested: usize, limit: usize }, #[error("simulation failed: {0}")] Simulation(String), #[error("measure at line {line} maps to an undeclared classical bit")] MeasurementMapping { line: usize }, } ``` - [ ] **Step 2: Write src/types.rs** ```rust use std::collections::HashMap; /// Newtype for qubit indices — prevents mixing with plain usizes. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct QubitIndex(pub usize); /// Newtype for shot count — enforces range and intent at type level. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct ShotCount(pub u32); impl ShotCount { pub const DEFAULT: ShotCount = ShotCount(1024); pub const MAX: ShotCount = ShotCount(100_000); } /// Wraps an OpenQASM 3.0 source string. #[derive(Debug, Clone)] pub struct CircuitSource(pub String); #[derive(Debug, Clone)] pub enum DiagnosticSeverity { Error, Warning, } #[derive(Debug, Clone)] pub struct ValidationDiagnostic { pub line: usize, pub column: usize, pub message: String, pub severity: DiagnosticSeverity, } #[derive(Debug, Clone)] pub struct ValidationResult { pub is_valid: bool, pub diagnostics: Vec, pub num_qubits: Option, pub num_gates: Option, } #[derive(Debug, Clone)] pub struct SimulationResult { /// Bitstring → count, e.g. `{"00": 512, "11": 512}`. pub counts: HashMap, pub shots: u32, pub execution_time_ms: f64, /// Optional full statevector as (real, imag) pairs per basis state. pub statevector: Option>, } ``` - [ ] **Step 3: Update src/main.rs** ```rust mod error; mod types; fn main() { println!("quantum-bridge-mcp"); } ``` - [ ] **Step 4: Verify** ```bash cargo build ``` Expected: no warnings. - [ ] **Step 5: Commit** ```bash git add src/error.rs src/types.rs src/main.rs git commit -m "feat: add error types and domain newtypes" ``` --- ## Task 3: Backend Traits **Files:** - Create: `src/executor.rs` (traits + constants only — `LocalSimulator` comes in sub-plan 3) - [ ] **Step 1: Write src/executor.rs** ```rust use crate::error::BridgeError; use crate::types::{CircuitSource, ShotCount, SimulationResult, ValidationResult}; pub const MAX_LOCAL_QUBITS: usize = 28; pub const SUPPORTED_GATES: &[&str] = &[ "h", "x", "y", "z", "s", "t", "sdg", "tdg", "rx", "ry", "rz", "cx", "cz", "swap", "ccx", "measure", ]; pub trait CanIntrospect { fn name(&self) -> &str; fn max_qubits(&self) -> usize; fn supported_gates(&self) -> &[&str]; } pub trait CanValidate { fn validate(&self, circuit: &CircuitSource) -> Result; } pub trait CanExecute { fn run( &self, circuit: &CircuitSource, shots: ShotCount, return_statevector: bool, ) -> Result; } /// Marker trait combining all three capabilities. V1.5 IBM backend will impl this too. pub trait Backend: CanIntrospect + CanValidate + CanExecute + Send + Sync {} #[cfg(test)] mod tests { use super::*; struct MockBackend; impl CanIntrospect for MockBackend { fn name(&self) -> &str { "mock" } fn max_qubits(&self) -> usize { 4 } fn supported_gates(&self) -> &[&str] { SUPPORTED_GATES } } impl CanValidate for MockBackend { fn validate(&self, _: &CircuitSource) -> Result { Ok(ValidationResult { is_valid: true, diagnostics: vec![], num_qubits: None, num_gates: None }) } } impl CanExecute for MockBackend { fn run(&self, _: &CircuitSource, _: ShotCount, _: bool) -> Result { Ok(SimulationResult { counts: Default::default(), shots: 0, execution_time_ms: 0.0, statevector: None }) } } impl Backend for MockBackend {} #[test] fn mock_backend_satisfies_trait_bounds() { let b = MockBackend; assert_eq!(b.name(), "mock"); assert_eq!(b.max_qubits(), 4); } } ``` - [ ] **Step 2: Declare module and run tests** Add to `src/main.rs`: ```rust mod executor; ``` ```bash cargo test ``` Expected: 1 test passes (`mock_backend_satisfies_trait_bounds`). - [ ] **Step 3: Commit** ```bash git add src/executor.rs src/main.rs git commit -m "feat: define Backend trait hierarchy (CanIntrospect/CanValidate/CanExecute)" ``` --- ## Final verification ```bash cargo fmt --check && cargo clippy -- -D warnings && cargo test ``` Expected: all green. Sub-plan 1 complete — hand off to sub-plan 2.