English | 繁體中文
A reference control and verification platform for trapped-ion experiments — built so that software green cannot pass for physical evidence.
TISL is a trapped-ion experiment control and verification reference platform. It does not claim to be a high-fidelity quantum computer. Its claim is narrower and testable: every result carries an explicit evidence level and an explicit statement of what it does not prove.
Version boundary: This README describes the current working tree, including unreleased post-v0.3.0 functionality.
shipped/currentmeans that code and its corresponding check exist; it does not mean the feature shipped in v0.3.0 or passed physical-hardware validation.
Public history: This repository preserves an audited, sanitized history of the
maindevelopment line. Retained development commits preserve their authors, dates, and messages; personal author emails are normalized to GitHub noreply. Publication-forbidden commits and paths are omitted; private branches, backup tags, GitHub pull-request records, and Actions logs are not included. Release artifacts still pass a separate fresh-snapshot gate.
| Area | Current capability | Explicit boundary |
|---|---|---|
| Control input | Strict OpenQASM subset and typed N-D scan requests | Unsupported syntax, measurement, or mapping is rejected instead of ignored and reported as successful |
| Compilation and execution | Circuit IR, native lowering, pulse schedules, sequence blocks, and multiple adapter lanes | Bundled lanes are synthetic/reference software, not RTIO, vendor compiler, or hardware-timing validation |
| Analysis and telemetry | Typed joint counts, marginals, photon histograms, fitting, and HTTP/SSE lifecycle events | Synthetic statistics do not prove PMT/camera behavior, coherence, tomography, or fidelity |
| Evidence and replay | Claim levels, limitations, source hashes, raw artifacts, traces, and deterministic replay | Dirty or incomplete provenance is reported as not fully traceable |
| Operator interfaces | Headless CLI/API plus an optional PyQt6 desktop | The bundled service is a loopback reference server, not a production control plane |
| Extension | Versioned execution plugins, a trusted subprocess seam, a remote bridge, and reference profiles | Real hardware still needs a deployment-owned gateway, TLS/Auth, interlocks, commissioning, and approvals |
Laboratory control devices integrated and verified onsite: 0;
capabilities at physical_ion_verified: 0.
The current evidence validates control-software behavior, not physical trapped-ion performance.
Producing a result without an explicit evidence level is impossible by construction.
EvidenceBundle.claim_level and EvidenceBundle.does_not_prove are required. Construction
fails if either is missing; there is no path that fills them in later. The invariant is enforced
by tests/architecture/test_dependency_rules.py::test_a6_*.
For the full architecture, clean-room ARTIQ-like compatibility, device-database schema, extension model, safety boundaries, and known limitations, read the Control Stack Guide. For usage, hardware status, and functional/non-functional requirements, read System Usage & Requirements. To add a simulator, reviewed Python worker, or remote ARTIQ/vendor runtime, start with the Plugin Platform (Markdown). Before physical wiring or power-up, use Pre-Hardware Readiness and Operations & Recovery.
- CPython 3.11–3.14.
- Ubuntu 24.04 x64 has full-suite CI; macOS 15 arm64 has targeted smoke gates on Python 3.11 and 3.14.
- Windows, PyPy, Python pre-releases, and unlisted platform combinations are currently unsupported.
- Core, CLI, HTTP/SSE, and demo runtime paths have zero third-party dependencies; PyQt6, tests, and SSOT tooling are optional extras.
git clone https://github.com/Yueh-H/trapped-ion-control-stack && cd trapped-ion-control-stack
python demos/d01_live_point/run.py # live point plus four injected failures
python demos/d02_software_sim/run.py # deterministic replay and calibration isolationThe zero-runtime-dependency statement is an executable property, not an installation shortcut. HTTP/SSE uses the Python standard library, so the commands above run without installing the package.
The legacy names artiq_sim, artiq_program, and the D13/D14 paths are retained for migration
compatibility. They are independent clean-room ARTIQ-like compatibility lanes aligned only
to public experiment/device API shapes and migration workflows. They do not import ARTIQ/DAX or
claim binary, compiler, gateware, or vendor-private protocol compatibility.
python demos/d13_artiq_daxsim/run.py # clean-room API-shape compatibility lane
python demos/d14_laser_free_compiler/run.py # Raman vs MAGIC-inspired reference compilerBoth demos run deterministic synthetic reference runtimes on vanilla Python. Their outputs can
support only software_simulated, not ARTIQ compiler or hardware verification.
python -m pip install -e .
tisl devices
tisl profiles
tisl run --backend sim --profile raman-reference --points 25 --shots 200 --seed 7Run one QASM program:
tisl-qasm --adapter artiq_program --shots 100 --output-format result \
src/tisl/circuit_catalog/qasm/2q/bell.qasmSave this minimal tisl.scan-run/v1 request as scan.json:
{
"schema": "tisl.scan-run/v1",
"profile_id": "raman-reference",
"adapter": "artiq_sim",
"program": {"kind": "none"},
"axes": [
{
"block": "raman",
"param": "time",
"linear": {"start": 0.0, "stop": 12.0, "points": 5}
}
],
"shots": 100,
"qubits": [0],
"seed": 7,
"analysis": "rabi",
"label": "rabi-scan",
"extras": {}
}tisl-scan --output-format result scan.jsonSee System Usage & Requirements and Control Scripts & Backends for a complete request, result fields, JSONL lifecycle events, and large-run artifact rules.
| Field | Meaning |
|---|---|
terminal_state |
completed, failed, interrupted, or rejected |
points / counts / per_qubit |
Bounded inline telemetry, joint outcomes, and per-qubit marginals |
preflight / delivery |
Pre-execution checks and transport acknowledgement/gap state |
evidence |
Claim level, provenance, acceptance, limitations, and artifact references |
traceable / missing_links |
Whether the provenance chain is complete; missing or dirty source state is explicit |
record_path |
Auditable run record created when --output-dir is used |
--output-format jsonl emits before/during/after lifecycle events; result emits one canonical
result. For more than 16 points, use --output-dir to preserve the complete raw-point artifact.
python -m pip install -e '.[gui]'
./start_pyqt.shstart_pyqt.sh uses the repository's own .venv. On first run it creates the environment,
installs PyQt6, and starts a loopback API when needed. Use tisl serve and tisl gui when you
want to run the backend and desktop separately.
Every value below is measured by tools/render_ssot.py; none is a hand-maintained badge.
| Item | Count | Measurement |
|---|---|---|
| Execution lanes | 6 | len(registry.all_descriptors()) |
| Gate modalities | 2 | len(compiler.modality_ids()) |
| Built-in device profiles | 3 | len(profile_store.builtin()) |
| Application-owned HTTP routes | 45 | len(service.ROUTES); 45 are API routes |
| Failure-catalog entries | 9 | len(FAILURE_CATALOG) |
| Fit models | 7 | len(analysis.names()) |
| Circuit-catalog scenarios | 28 | len(gui.defaults.CATALOG_PRESETS) |
| GUI circuit choices | 33 | len(gui.defaults.CIRCUIT_PRESETS) |
| Evidence levels | 8 | len(ClaimLevel) |
| Test functions | 1216 | AST parse of tests/**/*.py |
| Collected test cases | 1697 | pytest --collect-only -q |
| Catalogued capabilities | 56 | capabilities.yaml |
| Planned demos | 14 | demos.yaml |
| Non-functional requirements | 20 | quality_attributes.yaml |
Four details matter when reading those numbers:
- HTTP routes count only handlers implemented by this project. Framework-generated documentation
pages are excluded. The count comes from
len(ROUTES), not from a duplicated constant. - Test functions and collected cases are different quantities. The first counts authored test functions; the second includes parameterized expansion. Both are reported so neither can be used alone to exaggerate the suite.
- Circuit-catalog scenarios and GUI choices are different sets. The first is the package-data manifest of 28 QASM resources. The selector adds 5 dedicated reference scenarios for 33 total choices.
- Built-in profiles are reference values, not machine calibrations. Copy
profiles/*.jsonand setTISL_PROFILE_DIRfor your deployment.software-reference-8qis a software-only synthetic extrapolation; it is not evidence of eight-ion hardware capability.
GET /api/v1 API self-description reads the same table as the router
src/tisl/service/api.py one contract table drives routing, documentation, and counts
src/tisl/gui/ optional PyQt6 desktop; communicates only through /api/v1
The backend is a pure HTTP/SSE API: it mounts no HTML/CSS/JavaScript and does not import Qt.
Only gui/api_client.py may open network connections from the PyQt client; screens cannot bypass
it. Architecture tests start the API while PyQt imports are blocked and launch the Scan and Quantum
Fullstack workspaces under offscreen Qt.
Quantum Fullstack opens directly in the Circuit editor. Its profile selector exposes 33 exact QASM choices and updates Abstract Circuit, Primitive Circuit, and Pulse Schedule views on the same page. Expected outcomes describe ideal computational-basis support only; they are not full quantum-state reconstruction.
The examples include fixed-inverse 1Q RB-style counts and Bell even/odd 2Q computational-basis
parity. They are not a complete RB campaign, Bell coherence measurement, tomography, or hardware
fidelity evidence. Open 33-point parity phase scan loads a server-owned Scan profile that prepares
the Bell state |Φ+⟩, scans gate:rz.phase_turns from 0 to 1 turn, reads two qubits in the analysis
basis, and computes
parity from typed joint counts. The view retains 33 points (32 intervals plus a closure endpoint);
the fit uses 32 unique phases and reports closure_error so phase zero is not double-weighted.
This entire path remains software_simulated.
Compile preview updates compilation views only. Circuit has its own 1–10,000,000 Shots input,
separate from Scan Shots. Run circuit → show results performs execution and expands the results
panel. If the server catalog provides an approval-gated non-synthetic QASM lane, the action changes
to PREPARE HARDWARE: Prepare returns an immutable plan, and the separate START action remains
disabled until the complete plan SHA, human-review checkbox, and external one-time approval all
match. This is still not an E-stop, safety interlock, or onsite hardware acceptance.
The quick-start start_pyqt.sh command packages the local desktop startup flow; the headless backend
can still run independently. Remote clients accept only HTTPS or a loopback tunnel. Set the endpoint
with TISL_API_URL and supply the operator credential through TISL_API_BEARER_TOKEN. The client
rejects remote plaintext HTTP before sending a request.
src/tisl/contracts/ typed cross-module contracts and evidence levels
src/tisl/core/ backend-neutral pipeline, lifecycle, and fault policy
src/tisl/adapters/ synthetic/reference adapters and external execution seams
src/tisl/compiler/ QASM, IR, native lowering, schedules, and verification
src/tisl/service/ stdlib HTTP/SSE API, run manager, and persistence
src/tisl/gui/ optional PyQt6 API client and operator workspaces
src/tisl/analysis/ fitter registry and typed readout analysis
src/tisl/simulation/ ideal statevector and synthetic experiment models
demos/ executable production-API vertical slices
profiles/ copyable synthetic reference device profiles
tests/ unit, contract, integration, failure, and architecture gates
docs/ architecture, requirements, operations, safety, and extension guides
tools/ SSOT, CI, publication, and release tooling
The central dependency rule is that contracts do not depend on execution layers, core does not know specific backends, service and GUI orchestrate only through public contracts, and GUI never imports an adapter directly. See Repository Blueprint for the complete ownership and dependency model.
| Level | Meaning |
|---|---|
planned_only |
Design exists; implementation is not claimed |
implemented |
Code exists |
unit_tested |
Focused tests cover the behavior |
integration_tested |
Cross-module behavior is verified |
software_simulated |
A host-side simulation path executes |
photon_simulated |
Real photon counts without ions |
electrically_verified |
Real electrical signals were measured |
physical_ion_verified |
A physical-ion result was measured |
Capabilities currently at physical_ion_verified: 0.
That is a deliberate fact, not an omission. Any gate/state fidelity claim requires physical-ion evidence; without it, the project makes no such claim. See Evidence Model.
| ID | Title | Non-functional properties demonstrated | Status |
|---|---|---|---|
| D1 | Live Point End-to-End | observability, correctness, reliability, traceability | ✅ shipped |
| D2 | Software Simulation — Complete Path Without Laboratory Hardware | reproducibility, testability, fail_closed, safety | ✅ shipped |
| D3 | Compiler Round-trip Regression — NativeProgram ↔ PulseSchedule | correctness, testability, ci_cd, reproducibility | ✅ shipped |
| D4 | Scan to AutoCal — From Scan to Preview and Fail-Closed Writeback | automation, reliability, traceability, reproducibility | ✅ shipped |
| D5 | Extensible Synthetic Adapter — Add a Backend Without Changing the Orchestration Core | extensibility, maintainability, fail_closed, testability | ✅ shipped |
| D6 | Synthetic Photon Telemetry — Typed Outcomes and Photon Histograms | fail_closed, correctness, observability | ✅ shipped |
| D7 | Oscilloscope Evidence Replay — Electrical Evidence Replay and Acceptance | traceability, reproducibility, fail_closed | planned |
| D8 | Fail-Closed Failure Lab | fail_closed, reliability, observability, operability | ✅ shipped |
| D9 | Benchmark Campaign — Publicly Implementable Scope | correctness, reproducibility, traceability | planned |
| D10 | Traceable Evidence — Trace a Persisted Run Record to Its Sources | traceability, reproducibility, fail_closed, observability | ✅ shipped |
| D11 | Maintainability — Schema Evolution Impact Surface | maintainability, extensibility, correctness, documentation_quality | ✅ shipped |
| D12 | Background Automation Agent | automation, safety, security, operability | planned |
| D13 | Clean-room ARTIQ-like Compatibility Lane — Deterministic Reference Execution | correctness, testability, fail_closed, reproducibility | ✅ shipped |
| D14 | Laser-Free Compiler — One Circuit, Two Physical Modalities | extensibility, correctness, fail_closed, documentation_quality | ✅ shipped |
Every row has a mechanism, an automated-check specification, a metric, and acceptance criteria.
Check status is explicitly current or planned. Only current with an existing path means the
automated check is implemented; planned is an acceptance specification, not passing evidence.
| Attribute | Check status | Automated check | Metric | Acceptance |
|---|---|---|---|---|
| Maintainability | current | render_ssot --check prevents generated drift; architecture/focused tests lock facade size, single method/route ownership, helper dependency direction, and delegated execution/admission behavior |
Generated-file drift; facade identity/import-cycle regressions after decomposition | Both = 0 |
| Extensibility | current | External entry points work through the API, PyQt, and runtime without core edits; the conformance kit runs the production Pipeline; exporters receive existing emitter events by injecting only an ObservationSink | Existing core/GUI/API files changed for one execution plugin; existing emitters changed for one exporter | Both = 0 (new files and composition wiring are allowed) |
| Automation | current | tests/unit/test_calibration_runner.py asserts the maintain loop converges on the sim lane (second plan empty, stale = 0), that quality_low is never retried while infra faults retry within the bound, that loops stop at max_iterations, that cancellation converges, that the budget refuses before execution and that a dry run neither submits nor stages; tests/unit/test_calibration_cli.py asserts non-interactive maintain refuses without --yes and accept refuses without a trusted-real provider |
Human interventions per maintain run, excluding the intentional approval point | <= 1 (the --yes / interactive confirmation only) |
| Reliability | planned | tests/test_failure_lab.py will assert terminal state and evidence completeness for all nine failures |
Share of injected failures converging to a terminal or explicit indeterminate/unsafe state | 100%; silent clean success without uncertainty = 0 |
| Correctness | planned | tests/test_compiler_equivalence.py, including a negative test with an intentionally injected half-angle bug |
Equivalence pass rate; worst-case TV/BH for dual-path comparison | 100% equivalence; TV <= 0.02 and BH >= 0.999 |
| Testability | planned | The full suite runs without any laboratory network; CI will enforce this with a network-block fixture | Share of tests requiring real hardware | Core package = 0% |
| Observability | current | Submit over a real socket and consume SSE; assert one trace across HTTP/Pipeline/Adapter/SQLite/run/SSE and the hardware watchdog; also verify access coverage, worker caps, single-owner reservations, global/plugin capacity, bounded LivePoint/fit/readout work, and bounded subprocess/bridge timeout, cancellation, protocol-fault, and cleanup paths | Critical execution hops without correlation; unbounded queues/histories; server requests without structured access events | Missing correlation = 0; unbounded growth points = 0; HTTP access-event coverage = 100% |
| Traceability | planned | tests/test_trace_completeness.py will trace every demo output and assert that no link is MISSING |
Share of results with complete provenance | 100% |
| Reproducibility | planned | tests/test_replay_determinism.py will require equal evidence-bundle hashes for two runs with the same seed |
Replay hash match rate | 100% for simulation lanes |
| Safety | planned | tests/test_admission.py will require rejection whenever any of four admission layers is absent |
Known paths that bypass admission to trigger a restricted action | = 0 |
| Fail-closed behavior | planned | tests/test_failure_lab.py across nine failure modes |
Failures that silently degrade or partially succeed without being marked | = 0 |
| Portability | current | Architecture gates forbid hard-coded non-loopback addresses; the publication scanner also rejects absolute home paths and private provenance | Hard-coded hosts/paths | = 0 |
| Scalability | current | Reject global/plugin work and concurrency overages before execution; verify bounded LivePoint, histogram, subprocess, bridge, and queue resources | Unbounded-growth structures on execution paths; declared limits missing admission enforcement | Both = 0 |
| Configuration management | current | Fail closed on schema defaults/types/bounds/steps/unknown fields and encoded size; GUI submits canonical plugin_parameters; hardware plans reject identity/config drift | Configuration fields entering execution without schema validation | = 0 |
| Security | current | CI builds a fresh-history allowlisted snapshot and runs an adversarial scanner over the tree and every Git blob; it also tests physical RBAC, server-owned script/bridge configuration, and credential redaction | Sensitive findings in the public snapshot tree and complete one-root history | = 0 |
| CI/CD | current | Ubuntu CPython 3.11–3.14 full suite; 3.14 lint/type/coverage; macOS 3.11/3.14 smoke; wheel/plugin conformance; SSOT; strict fresh-history publication gate; deterministic double-build comparison | Silently skipped tests | = 0 (every skip must be visible and justified) |
| Deployment | current | CI builds the wheel, installs into a clean virtual environment, runs pip check and plugin discovery/conformance, and executes every demo entry point | Commands from clone to first demo result | <= 3 |
| Operability | planned | tests/test_error_messages.py will require every error category to provide non-empty user_message and suggested_action fields |
Failure paths exposing only a stack trace without a readable message | = 0 |
| Documentation quality | planned | python tools/render_ssot.py --check plus tests/unit/test_evidence_contract.py, requiring non-empty does_not_prove for every evidence item |
Claims without a claim level; evidence with empty does_not_prove | Both = 0 |
| Team onboarding | planned | Planned: after formal OWNERS/CODEOWNERS are added, CI will require an owner for every platform submodule; no such gate exists yet | Time from clone to a first meaningful PR | <= 1 working day, using D5 (add one adapter) as the standard onboarding task |
Install the development and GUI extras:
python -m pip install -e '.[dev,gui]'Run the common gates:
python -m pytest -ra
ruff check src tests tools plugins demos benchmarks
mypy
python tools/render_ssot.py --check
python tools/check_publication.py --tree-onlyThe complete local matrix is exposed through tools/local_ci.sh; for example, run
tools/local_ci.sh test all. See Quality Gates,
Local CI, and Support Matrix for the release gates,
coverage floor, platform matrix, and zero-skip policy.
- Custom profiles: Copy
profiles/*.json, preserve schema and unit boundaries, and setTISL_PROFILE_DIR. Never treat reference values as machine calibrations. - Execution plugins: Publish a versioned
tisl.execution_adaptersentry point and run the conformance kit. Adding one plugin should not modify existing core, GUI, or API behavior. - Reviewed Python/vendor runtimes: Use the bounded subprocess or remote-bridge seam. Connections, credentials, executables, device maps, and interlocks belong to the deployment.
- Before real hardware: Supply an inventory, logical-to-physical mapping, pinned SDK/firmware, range/rate limits, safe state, E-stop, independent interlock, commissioning evidence, and an accountable operator owner.
See Plugin Platform for the full onboarding contract and Pre-Hardware Readiness plus Operations & Recovery for minimum pre-power gates.
- New features use production contracts and the production Pipeline; demos must not create a parallel hard-coded success path.
- Every result retains a
claim_leveland non-emptydoes_not_proveboundary. - Planned acceptance criteria are not described as passed, and synthetic results are never promoted to physical claims.
- After changing an SSOT, run the renderer and relevant tests. Install the versioned hook with
sh tools/install_git_hooks.shand follow the repository publication gate before committing. - See Team Building Playbook for module ownership, the definition of done, and the review workflow.
| File | Purpose |
|---|---|
| ARCHITECTURE_OPTIONS.md | Three architecture options and the selection rationale |
| AUTOCAL_DESIGN.html | Formal AutoCal design (draft): three state machines, SQLite persistence, extensible procedure registry |
| CAPABILITY_MAP.html | Generated map of all 56 capabilities |
| CONTROL_SCRIPTS_AND_BACKENDS.md | QASM/scan entry points, event/result contracts, and backend onboarding |
| CONTROL_STACK.html | Full architecture, clean-room compatibility, safety boundaries, and limitations |
| DEMO_CATALOG.md | Complete specifications for all 14 demos |
| EVIDENCE_MODEL.md | Evidence levels and the ten-link traceability chain |
| IMPLEMENTATION_ROADMAP.md | Milestones and acceptance criteria |
| LOCAL_CI.md | Local CI matrix and release gates when hosted runners are unavailable |
| OBSERVABILITY_AND_CAPACITY.md | Cross-layer trace correlation, metrics, and capacity contracts |
| PLUGIN_PLATFORM.html | Execution plugins, custom scripts, remote bridges, and multi-qubit expansion |
| PLUGIN_PLATFORM.md | Markdown edition of the plugin platform guide |
| PRE_HARDWARE_OPERATIONS.md | Pre-power operations and recovery rehearsal runbook |
| PRE_HARDWARE_READINESS.md | Software/deployment boundary and commissioning gates before wiring hardware |
| PUBLICATION_BOUNDARY.md | What the project may and may not claim |
| QUALITY_ATTRIBUTES.md | All 20 non-functional quality attributes |
| QUALITY_GATES.md | Executable lint, typing, coverage, test, publication, and packaging baseline |
| REPOSITORY_BLUEPRINT.md | Module ownership and dependency boundaries |
| SCALABILITY_AND_MULTI_QUBIT_EXPANSION.html | Extensibility/scalability audit and multi-qubit roadmap |
| SUPPORT_MATRIX.md | Explicit Python, OS, GUI, persistence, and deployment support |
| SYSTEM_USAGE_AND_REQUIREMENTS.md | Usage, hardware status, and functional/non-functional requirements |
| TEAM_BUILDING_PLAYBOOK.md | Module ownership, definition of done, and contribution workflow |
The package version is 0.3.0 (Synthetic Reference Release); the current working tree also contains
unreleased functionality. See CHANGELOG.md for version history. The published Git
history is not itself a release artifact: any externally distributed source or wheel must come from an
artifact that passed the fresh-history publication scanner and deterministic build gate. Those gates
reduce sensitive-data and claim-inflation risk; they are not hardware-safety certification.
Apache-2.0. This repository is an independent implementation. It contains no source code, configuration, calibration values, or measurement evidence from non-public repositories; all demo data is synthetic. See NOTICE.