Initial import

This commit is contained in:
Vincent Bourdon
2026-06-09 16:14:55 +02:00
commit 9af114e391
87 changed files with 20848 additions and 0 deletions
@@ -0,0 +1,236 @@
# quantum-bridge-mcp — Design Spec
**Date:** 2026-04-28
**Status:** Approved (revised after competitive analysis)
**Author:** Vincent Bourdon
---
## 1. Problème et positionnement
Les développeurs sans expertise quantique ne peuvent pas intégrer du calcul quantique dans leurs projets sans quitter leur workflow et apprendre Qiskit. L'écosystème MCP quantique existant (Qiskit/mcp-servers officiel IBM, plusieurs forks communautaires) est **100% Python**, dépend de l'installation lourde de Qiskit (~200 Mo + venv + résolution pip), et requiert souvent un compte IBM même pour de la simulation locale.
**Cible :** développeurs qui veulent intégrer ou prototyper du calcul quantique simulé sans installer l'écosystème Python/Qiskit.
**Positionnement :** *« Le simulateur quantique le plus léger et le plus performant pour Claude — un binaire, zéro setup, zéro réseau, zéro compte »*.
Trois angles défendables face au MCP officiel IBM :
- **Léger** : binaire unique ~10 Mo vs ~200 Mo de Qiskit + dépendances Python
- **Rapide à démarrer** : pas de cold start Python, pas de pip resolve
- **Performant** : moteur Spinoza (pure Rust), top tier single-thread sur 525 qubits
- **Privacy / air-gapped** : aucune télémétrie, aucun appel réseau, fonctionne hors-ligne et en CI minimal
---
## 2. Scope V1 vs V1.5
| Phase | Périmètre | Cible |
|-------|-----------|-------|
| **V1** | Simulateur local uniquement, mode synchrone, OpenQASM 3.0 | livrable rapide, valeur immédiate |
| **V1.5** | Ajout backend IBM Quantum (token utilisateur), mode asynchrone avec persistence des job_ids pour reprise de session | après validation V1 |
V1 ne couvre **pas** : IBM Quantum, autres providers (AWS Braket, Azure, IonQ), simulation avec bruit, monétisation/tiers, gestion de licence.
---
## 3. Outils MCP exposés (V1)
| Outil | Description |
|-------|-------------|
| `list_backends` | Liste les backends disponibles (en V1 : seulement le simulateur local + ses capacités : qubits max, gates supportées) |
| `validate_circuit` | Parse un programme OpenQASM 3.0, vérifie sémantique (qubits déclarés, gates supportées, mesures bien formées). Retourne diagnostics structurés. |
| `run_circuit` | Exécute un circuit OpenQASM 3.0 sur le simulateur local (synchrone). Retourne counts + statevector optionnel + métadonnées. |
Trois outils en V1, contre six initialement prévus. La compression vient du mode synchrone (pas de cycle submit/status/results pour le local) et du retrait du `select_backend` (un seul backend en V1) et de `estimate_cost` (gratuit en local).
V1.5 réintroduira : `submit_circuit`, `get_job_status`, `get_results` (cycle async pour IBM), `select_backend`, `estimate_cost`.
Claude se charge de générer le circuit OpenQASM **et** d'interpréter les counts en langage clair. Le MCP fait exclusivement parsing, validation et exécution.
---
## 4. Architecture (V1)
```
Claude (génère le circuit OpenQASM 3.0)
MCP Server (JSON-RPC sur stdio via rmcp)
┌─────────────────────┐
│ validate_circuit │ → oq3_semantics
│ │ (AST + analyse sémantique)
└─────────────────────┘
┌─────────────────────┐
│ run_circuit │ → AST → mapping vers gates Spinoza
│ │ → spinoza::simulate
│ │ → counts (sampling N shots)
└─────────────────────┘
Retour à Claude
(counts + métadonnées brutes — Claude interprète)
```
### Composants internes
1. **MCP layer** — utilise le SDK officiel `rmcp` (modelcontextprotocol/rust-sdk) plutôt qu'une implémentation JSON-RPC manuelle. Réduit dette de maintenance et risque de divergence avec le protocole.
2. **CircuitValidator** — wrappe `oq3_semantics` (parser officiel Qiskit en Rust). Produit des diagnostics structurés (ligne, colonne, message) que Claude peut afficher tel quel à l'utilisateur. Vérifie :
- syntaxe OpenQASM 3.0 valide
- tous les qubits référencés sont déclarés
- toutes les gates utilisées sont supportées par le moteur
- nombre de qubits ≤ limite configurable (défaut 28, ajustable selon RAM)
- mesures correctement mappées sur des classical bits
3. **CircuitExecutor** — convertit l'AST OpenQASM 3 en séquence de gates Spinoza, lance la simulation, échantillonne N shots à partir des probabilités du statevector final.
4. **Pas de JobTracker, pas de persistence** en V1 — l'exécution est synchrone, retour direct. Ces composants reviennent en V1.5 pour les jobs IBM.
5. **Pas de ResultInterpreter en Rust** — l'interprétation langage naturel des counts (« état de Bell », « superposition », etc.) est laissée à Claude qui le fait nativement bien mieux qu'une table de patterns figée.
### Gates supportées (V1)
Pauli (X, Y, Z), Hadamard (H), phase (S, T, Sdg, Tdg), rotations (RX, RY, RZ), CNOT, CZ, SWAP, Toffoli (CCX), mesures.
Toute gate non listée doit produire une erreur explicite via `validate_circuit` avec la liste des gates supportées.
---
## 5. Stack technique
| Composant | Choix | Justification |
|-----------|-------|---------------|
| Langage | Rust (édition 2021) | Cohérence positionnement, perf, binaire unique |
| MCP SDK | `rmcp` (officiel) | Évite réimplémenter JSON-RPC stdio à la main |
| Parser OpenQASM 3 | `oq3_semantics` (Qiskit/openqasm3_parser) | Officiel, AST + analyse sémantique, bons diagnostics |
| Moteur simulation | `spinoza` (QuState/Wells Fargo) | Pure Rust, top tier 525 qubits, mode f32 optionnel |
| Async runtime | `tokio` | Nécessaire pour rmcp |
| Sérialisation | `serde` + `serde_json` | Standard |
| Logs | `tracing` | Standard observabilité Rust |
Aucune dépendance Python en runtime. Distribution : binaires précompilés via `cargo-dist` (Linux/macOS/Windows × x86_64/arm64) + `cargo install` pour les utilisateurs Rust.
---
## 6. Performances cibles
Cibles basées sur Spinoza single-thread sur laptop moderne (M-series ou Ryzen équivalent) :
| Circuit | Cible |
|---------|-------|
| Bell (2 qubits, 2 gates, 1024 shots) | **< 5 ms** |
| 10 qubits / 50 gates / 10k shots | **< 50 ms** |
| 20 qubits / 100 gates / 10k shots | **< 500 ms** |
| 25 qubits / 100 gates / 1k shots | **< 5 s** |
| Limite pratique RAM 16 Go | **28 qubits** |
Mode `--f32` optionnel pour +30% de vitesse et +1 qubit à RAM égale (perte de précision négligeable pour les counts en pratique).
---
## 7. Structure de fichiers
```
quantum-bridge-mcp/
├── src/
│ ├── main.rs # Point d'entrée, MCP server stdio (rmcp)
│ ├── tools/
│ │ ├── mod.rs
│ │ ├── list_backends.rs
│ │ ├── validate_circuit.rs
│ │ └── run_circuit.rs
│ ├── validator.rs # Wrapper oq3_semantics
│ ├── executor.rs # AST → Spinoza
│ └── error.rs # Diagnostics structurés
├── tests/
│ ├── integration/ # Tests intégration MCP
│ ├── reference/ # Circuits QASM3 + résultats Qiskit attendus
│ └── proptest/ # Property-based tests
├── benches/ # Benchmarks Criterion
├── scripts/
│ └── gen_reference.py # Génère counts/statevectors via Qiskit Aer
├── Cargo.toml
├── .github/workflows/
│ ├── ci.yml # Tests Rust + cross-validation Qiskit
│ └── release.yml # cargo-dist
└── README.md
```
---
## 8. Stratégie de tests
Sept couches, du plus déterministe au plus statistique :
1. **Unit tests gates** — chaque gate appliquée à un état initial connu produit le statevector exact attendu (tolérance 1e-10).
2. **Tests statistiques counts** — circuits canoniques (Bell, GHZ, superposition uniforme) exécutés en N=10k shots, comparaison aux distributions attendues via test du chi² (α=0.01).
3. **Cross-validation Qiskit** *(critique)* — un dossier `tests/reference/` contient ~30 circuits QASM3 avec leurs statevectors et counts pré-calculés via Qiskit Aer (script Python séparé, exécuté en CI). Comparaison bit-à-bit du statevector (tolérance 1e-10) et statistique des counts. **Indispensable** pour rattraper les bugs d'endianness / ordre de qubits.
4. **Property-based tests** (`proptest`) — invariants : `U·U† = I`, `Σ|amplitudes|² = 1`, idempotence des mesures pures.
5. **Tests de validation** — golden tests : dossier de fichiers QASM3 invalides + messages d'erreur exacts attendus. Couvre : qubit hors range, gate non supportée, mesure mal mappée, syntaxe invalide.
6. **Tests protocole MCP** — roundtrip JSON-RPC sur mock stdio, conformité schéma tools, format erreurs MCP.
7. **Smoke perf** (Criterion) — Bell < 5 ms, 20 qubits / 100 gates < 500 ms, alarmes si régression > 20%.
CI : Rust toolchain + Python 3.11 + Qiskit Aer pour la couche 3 (Python utilisé **uniquement** en CI, jamais runtime).
---
## 9. Distribution
| Cible | Méthode | Audience |
|-------|---------|----------|
| `cargo install quantum-bridge-mcp` | crates.io | Utilisateurs Rust |
| Binaires précompilés | GitHub Releases via `cargo-dist` | Cible principale (devs sans Rust) |
| Installer one-liner | `curl ... \| sh` | Setup rapide depuis README Claude |
| Homebrew tap | `brew install vbourdon/tap/quantum-bridge-mcp` | macOS power users (post-V1) |
Targets de build : `x86_64-unknown-linux-gnu`, `aarch64-unknown-linux-gnu`, `x86_64-apple-darwin`, `aarch64-apple-darwin`, `x86_64-pc-windows-msvc`.
---
## 10. Critères de succès V1
- [ ] Binaire installable sans Rust toolchain sur Linux/macOS/Windows
- [ ] Bell state < 5 ms sur laptop moderne
- [ ] 20 qubits / 100 gates / 10k shots < 500 ms
- [ ] Les 3 outils MCP sont opérationnels et conformes au protocole
- [ ] Validation produit des messages d'erreur actionnables (ligne, colonne, suggestion)
- [ ] Cross-validation Qiskit passe sur les 30 circuits de référence
- [ ] README avec exemple d'usage Claude Code end-to-end
- [ ] CI verte (lint, tests Rust, cross-validation Qiskit)
---
## 11. Hors scope V1 (pour mémoire)
Repoussé en V1.5 :
- Backend IBM Quantum (token utilisateur, REST API ou Qiskit Runtime)
- Mode asynchrone (`submit_circuit` / `get_job_status` / `get_results`)
- Persistence des job_ids (sled ou JSON file dans `~/.local/share/quantum-bridge-mcp/`)
- `select_backend` / `estimate_cost`
- Gestion d'erreurs réseau, retry, backoff
Repoussé en V2+ :
- Simulation avec bruit (decoherence, gate errors, readout errors)
- Simulation par densité matricielle
- Autres providers quantiques (AWS Braket, Azure Quantum, IonQ)
- Monétisation / système de licences
- Dashboard web d'usage
- Support OpenQASM 2.0 (le standard a basculé sur 3.0)
---
## 12. Risques identifiés
| Risque | Mitigation |
|--------|------------|
| `oq3_semantics` mal documenté ou incomplet sur certaines features QASM3 | POC parsing dès la 1ère semaine, fallback sur `jlapeyre/openqasm-rust` si bloquant |
| Spinoza API instable ou licence ambiguë | Vérifier licence (Apache 2.0 attendu) avant intégration ; alternative roqoqo identifiée |
| MCP officiel IBM cannibalise le projet | Le positionnement « binaire léger » reste défendable ; surveiller leur roadmap |
| Bugs d'endianness silencieux | Cross-validation Qiskit obligatoire en CI dès le début |
| RAM saturée à 28+ qubits chez user | Limite configurable, message d'erreur clair suggérant V1.5/IBM |
@@ -0,0 +1,264 @@
# Quantum Tutor — Design Spec
**Date:** 2026-04-29
**Status:** Approved
**Scope:** Extension pédagogique de quantum-bridge-mcp — 4 nouveaux outils MCP + curriculum JSON + suivi de progression
---
## 1. Contexte et objectif
quantum-bridge-mcp est un serveur MCP Rust qui expose 3 outils de simulation de circuits OpenQASM 3.0. Ce module ajoute une **couche pédagogique** au-dessus des outils existants : un tuteur quantique qui guide l'utilisateur à travers un curriculum structuré, vérifie ses exercices, et suit sa progression.
**Utilisateur cible :** débutant en informatique quantique avec des notions vagues de superposition/intrication. Objectif : aller des bases jusqu'aux algorithmes (Grover).
**Style d'apprentissage :** explication courte → exercice guidé → exploration libre. Maths introduites progressivement quand elles deviennent nécessaires.
---
## 2. Nouveaux outils MCP
### 2.1 `get_lesson`
```
get_lesson(module_id: u32, lesson_id?: u32) → JSON
```
Retourne le contenu d'une leçon : explication du concept, circuit(s) d'illustration à exécuter, et exercice(s) à résoudre.
**Paramètres :**
- `module_id` : 17 (voir curriculum §4)
- `lesson_id` : optionnel ; si absent, retourne la première leçon non complétée du module
**Réponse :**
```json
{
"module_id": 2,
"lesson_id": 1,
"title": "La porte H et la superposition",
"concept": "...",
"example_circuit": "OPENQASM 3.0;\n...",
"what_to_observe": "Lance run_circuit avec 1000 shots. Tu devrais voir ~500 '0' et ~500 '1'.",
"exercise": {
"id": "2-1-a",
"prompt": "Écris un circuit qui met un qubit en superposition parfaite et le mesure.",
"hint": "Une seule porte suffit avant la mesure."
}
}
```
**Comportement :** si `lesson_id` est absent et que `get_progress()` indique que le module est déjà complété, retourne un résumé du module avec suggestion d'avancer.
---
### 2.2 `check_exercise`
```
check_exercise(exercise_id: str, circuit: str) → JSON
```
Vérifie si le circuit soumis résout l'exercice identifié par `exercise_id`. Exécute le circuit en interne (1024 shots), compare les résultats aux critères définis dans `curriculum.json`, met à jour la progression.
**Paramètres :**
- `exercise_id` : identifiant de l'exercice (ex: `"2-1-a"`)
- `circuit` : source OpenQASM 3.0
**Réponse (succès) :**
```json
{
"passed": true,
"exercise_id": "2-1-a",
"feedback": "Parfait ! Ta porte H crée bien une superposition équilibrée. Tu observes ~50% de '0' et ~50% de '1'.",
"counts": {"0": 512, "1": 512},
"progress_updated": true
}
```
**Réponse (échec) :**
```json
{
"passed": false,
"exercise_id": "2-1-a",
"feedback": "Ton circuit produit toujours '0'. Le qubit n'est pas en superposition. Essaie d'ajouter une porte avant la mesure.",
"counts": {"0": 1024},
"hint": "La porte H transforme |0⟩ en (|0⟩ + |1⟩)/√2."
}
```
**Critères de vérification (définis par exercice dans curriculum.json) :**
- `required_outcomes` : liste de bitstrings qui doivent apparaître (avec proportion min/max optionnelle)
- `forbidden_outcomes` : bitstrings qui ne doivent pas apparaître
- `statevector_check` : optionnel — amplitudes attendues avec tolérance ε=1e-6
**Erreurs :** si le circuit est invalide, retourne l'erreur de validation avec position (réutilise `CircuitValidator`).
---
### 2.3 `explain_result`
```
explain_result(circuit: str, counts: object, statevector?: array) → JSON
```
Génère une explication pédagogique de ce qui s'est passé dans le circuit : quelles portes ont fait quoi, pourquoi on observe cette distribution, ce que ça signifie quantiquement.
**Paramètres :**
- `circuit` : source OpenQASM 3.0 (le circuit qui vient d'être exécuté)
- `counts` : résultat de `run_circuit` (bitstring → count)
- `statevector` : optionnel — amplitudes complexes de `run_circuit` avec `return_statevector: true`
**Réponse :**
```json
{
"gate_breakdown": [
{"gate": "h q[0]", "qubit": 0, "description": "Hadamard — crée une superposition égale", "effect_on_zero": "Transforme |0⟩ en (|0⟩+|1⟩)/√2"},
{"gate": "cx q[0], q[1]", "control": 0, "target": 1, "description": "CNOT — flip la cible si le contrôle est |1⟩"}
],
"num_qubits": 2,
"key_concept": "intrication",
"dominant_outcomes": ["00", "11"],
"missing_outcomes": ["01", "10"],
"statevector_summary": {"non_zero_amplitudes": [0, 3], "zero_amplitudes": [1, 2]}
}
```
**Implémentation :** le serveur Rust analyse le circuit via `CircuitValidator` et retourne des **données structurées** (liste de gates avec descriptions depuis `curriculum.json`, statistiques des counts, concept clé). C'est Claude (le client MCP) qui synthétise l'explication en langage naturel à partir de ces données — cette séparation exploite les capacités respectives du simulateur (analyse structurelle) et du LLM (narration pédagogique).
---
### 2.4 `get_progress`
```
get_progress() → JSON
```
Retourne l'état de progression de l'utilisateur dans le curriculum.
**Réponse :**
```json
{
"current_module": 2,
"current_lesson": 1,
"modules": [
{"id": 1, "title": "Le qubit", "status": "completed", "exercises_solved": 3},
{"id": 2, "title": "Superposition", "status": "in_progress", "exercises_solved": 0},
{"id": 3, "title": "Interférence", "status": "locked", "exercises_solved": 0}
],
"total_exercises_solved": 3,
"total_exercises": 18,
"percent_complete": 17
}
```
**Persistence :** fichier JSON à `~/.config/quantum-bridge-mcp/progress.json`. Créé automatiquement au premier appel avec progression à zéro.
---
## 3. Architecture interne
### Nouveaux fichiers
```
curriculum/
curriculum.json — leçons, exercices, critères de vérification, descriptions de gates
src/
tutor.rs — CurriculumLoader + ExerciseChecker (logique de vérification)
progress.rs — ProgressStore (lecture/écriture progress.json)
tools/
tutor_tools.rs — handlers MCP des 4 nouveaux outils
```
### Réutilisation des composants existants
| Composant existant | Réutilisé par |
|---|---|
| `CircuitValidator` (`src/validator.rs`) | `check_exercise` (validation avant exécution), `explain_result` (analyse des gates) |
| `LocalSimulator` via `CanExecute` | `check_exercise` (exécution interne des circuits) |
| `CircuitSource`, `ShotCount`, `SimulationResult` (`src/types.rs`) | `check_exercise`, `explain_result` |
| Trait `Backend` | `check_exercise` — dépend de `&dyn Backend`, compatible IBM V1.5 |
### Contraintes d'architecture
- Les outils tutor dépendent de `&dyn Backend`, jamais de `LocalSimulator` directement (même règle que les outils existants).
- `check_exercise` utilise `ShotCount(1024)` fixe pour la vérification (reproductibilité statistique).
- `ExerciseChecker` compare avec tolérance : un résultat passe si chaque outcome requis représente au moins `min_ratio - 2σ` des shots (σ calculé pour N=1024 shots, distribution binomiale).
---
## 4. Curriculum — structure des 7 modules
| Module | Titre | Concepts clés | Nb exercices |
|--------|-------|--------------|--------------|
| 1 | Le qubit | États \|0⟩/\|1⟩, gate X, mesure | 2 |
| 2 | Superposition | Gate H, état \|+⟩, distribution 50/50 | 3 |
| 3 | Interférence et phase | H·H=I, phase relative, gates Z/S/T/RZ | 3 |
| 4 | 2 qubits et intrication | Bell state, CNOT, mesure corrélée | 3 |
| 5 | Circuits multi-qubits | GHZ, Toffoli, statevecteur complet | 3 |
| 6 | Premiers algorithmes | Deutsch-Jozsa, Bernstein-Vazirani, téléportation | 2 |
| 7 | Algorithme de Grover | Oracle de phase, opérateur de diffusion | 2 |
**Total : 18 exercices** sur 7 modules.
Les modules 27 sont verrouillés jusqu'à complétion du module précédent. Exception : le module suivant se déverrouille dès qu'au moins 2/3 des exercices du module courant sont résolus.
---
## 5. Format curriculum.json (schéma)
```json
{
"version": "1.0",
"gate_descriptions": {
"h": {
"short": "Hadamard — crée une superposition égale",
"effect_on_zero": "Transforme |0⟩ en (|0⟩+|1⟩)/√2",
"effect_on_one": "Transforme |1⟩ en (|0⟩-|1⟩)/√2"
}
},
"modules": [
{
"id": 1,
"title": "Le qubit",
"lessons": [
{
"id": 1,
"title": "États |0⟩ et |1⟩",
"concept": "...",
"example_circuit": "OPENQASM 3.0;\n...",
"what_to_observe": "...",
"exercises": [
{
"id": "1-1-a",
"prompt": "...",
"hint": "...",
"criteria": {
"required_outcomes": [{"bitstring": "1", "min_ratio": 0.95}],
"forbidden_outcomes": ["0"]
}
}
]
}
]
}
]
}
```
---
## 6. Tests
- **Unitaires** : `ExerciseChecker` avec critères simples (gate X → bitstring "1" avec ratio 1.0)
- **Intégration** : `check_exercise` roundtrip via MCP JSON-RPC pour 3 exercices représentatifs (un par module difficile)
- **Golden files** : `tests/tutor/` — circuits d'exercices + résultats attendus (pass/fail)
- **Progress** : `ProgressStore` — création, mise à jour, lecture, reset
---
## 7. Hors scope (V1)
- Visualisation sphère de Bloch (V2)
- Dessin de circuits en ASCII/SVG (V2)
- Explications générées par LLM (V2)
- Support multi-utilisateurs (V2)
- Gamification / badges (V2)