### wai-quantum: pulse and dynamics, simulated, the same bits everywhere, its receipts binding the calibrations

- **OpenPulse read** (`qasm::pulse`): a pulse program's `cal` and `defcal` blocks on physical qubits run in
  order into a schedule on frames: ports (by the names `d0`, `m0`, `a0`, or mapped), frames with times of their
  own, the waveform templates `constant`, `gaussian`, `sech`, `gaussian_square`, `drag` and `sine` and explicit
  samples, `play`, `delay`, `shift_phase`, `set_phase`, `shift_frequency`, `set_frequency`, captures and
  barriers. A gate starts when its qubits and its frames are free, and a frame's carrier runs on across a
  frequency change. Durations are whole samples of `dt`. What the reader does not take is refused with a code and
  its place: `Q453` to `Q462` join the table after `Q452`, renumbering nothing.
- **The pulse simulator** (`quantum_pulse`, in `quantum_engine` and `full`): two or three levels per qubit in its
  rotating frame, the drive its frames' carriers give, anharmonicity, static couplings, and relaxation and
  dephasing from T1 and T2, integrated sample by sample in each tone's frame by a twelfth-order series that uses
  only `+ − × ÷` and `sqrt`, so the final density matrix is the same bits on x86_64, arm64, wasm32-wasip2 and in
  the browser; CI pins its digest on each. The plan states a proved bound on the trace distance from the model's
  exact solution, with an estimate of rounding beside it, and refuses a step longer than 1/λ or a schedule whose
  error would pass its tolerance, naming the steps that would meet it. The tests hold it to closed forms within
  that bound: Rabi turns, a quarter turn of phase, detuned drives, T1 decay and T2 dephasing.
- **Pulse runs as jobs** (`engine::pulse`): the method `pulse` everywhere jobs run (`wai-quantum run --method
  pulse --pulse OPTIONS`, both MCP servers' run tools, the job service's `/v1/jobs` and `/v1/run`, the page's
  `run`). The device comes from a target's calibration snapshot and the options over the defaults, each
  parameter saying where it came from; the counts from the captures' joint reading, into the program's bits;
  the accuracy class is `bounded`. The result's `pulse.calibration` holds the control program's digest, its
  calibrations', the schedule's, the device's and the target snapshot's, `pulse.integrator` the integrator and
  its step, and `pulse.density_hash` the final state; the receipt seals them.
- **Schedules and checks**: `wai-quantum pulse schedule` (each frame's timeline, the gate calls, the waveforms)
  and `wai-quantum pulse check` (a sealed pulse job held to its request by running it again, each differing
  field named); the MCP tools `pulse_schedule` and `pulse_check` on both servers; the service's
  `POST /v1/pulse/schedule` and `/v1/pulse/check`; and `QuantumEngine.pulse` in the page. `J040` and `J041` join
  the job layer's refusals. `schemas/pulse.v1.json` is new, and the job request and result schemas gain the
  pulse options and the pulse result. [The pulse page](wai-quantum/docs/pulse.md) gives the model, the bound
  and the options.
- **The Studio's pulse pane**: a pulse program's schedule drawn as a timeline (a lane per frame, each play its
  waveform's envelope, captures, barriers, phase and frequency changes, and the gate calls above), a program the
  pulse reader refuses answered with its code, an example to load, and a run on the pulse simulator with its
  readings, its bound and what its receipt binds, each answer's seal checked in the page; the desktop app serves
  the same calls (`pulse`).
- **CI:** `wai-quantum-pulse.yml` runs the 26 tests by name on Linux, the pinned digests on arm64 Linux and on
  macOS in debug and release builds, and the tests under wasmtime; `wai-web-wasm.yml`'s pins move to 27 (native)
  and 19 (wasm32).
- **Breaking:** `api:rust:wai_quantum::engine::schema::FILES`: the committed schemas grew from 22 to 23 with
  `pulse.v1.json`. Code that names the array's length iterates over `FILES` instead.

