|
| 1 | +# Multi-Field Ramp Arg-Fields Implementation Plan |
| 2 | + |
| 3 | +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. |
| 4 | +
|
| 5 | +**Goal:** Implement `nqctl ramp` multi-field structured args using `--arg key=start:end:step[:interval]` plus fixed `--arg key=value` support. |
| 6 | + |
| 7 | +**Architecture:** Replace positional ramp parsing in CLI with an arg-fields parser that classifies ramp tuples and fixed fields. Add a multi-field ramp execution path in the instrument driver that schedules per-field updates and sends structured `set` calls while preserving unspecified fields through existing autofill behavior. Keep safety/policy checks enforced through the existing write pipeline. |
| 8 | + |
| 9 | +**Tech Stack:** Python, argparse CLI, QCodes driver (`instrument.py`), pytest. |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +### Task 1: Add failing CLI parser tests for multi-field ramp args |
| 14 | + |
| 15 | +**Files:** |
| 16 | +- Modify: `tests/test_cli.py` |
| 17 | +- Modify: `nanonis_qcodes_controller/cli.py` |
| 18 | + |
| 19 | +**Step 1: Write failing test for 3-part tuple parsing** |
| 20 | + |
| 21 | +Add test asserting: |
| 22 | +- input `--arg Width=10e-9:20e-9:1e-9 --interval-s 0.1` |
| 23 | +- parser classifies `Width` as ramp tuple with interval defaulted to global. |
| 24 | + |
| 25 | +**Step 2: Write failing test for 4-part tuple parsing** |
| 26 | + |
| 27 | +Add test asserting: |
| 28 | +- input `--arg Height=8e-9:16e-9:1e-9:0.14 --interval-s 0.1` |
| 29 | +- parser classifies interval override as `0.14`. |
| 30 | + |
| 31 | +**Step 3: Write failing test for mixed fixed + ramp args** |
| 32 | + |
| 33 | +Add test asserting: |
| 34 | +- `--arg Width=... --arg Angle=0` |
| 35 | +- `Angle` is fixed field, `Width` is ramp field. |
| 36 | + |
| 37 | +**Step 4: Run focused test file to capture failures** |
| 38 | + |
| 39 | +Run: `python -m pytest tests/test_cli.py -q` |
| 40 | + |
| 41 | +### Task 2: Implement ramp arg parsing contract in CLI |
| 42 | + |
| 43 | +**Files:** |
| 44 | +- Modify: `nanonis_qcodes_controller/cli.py` |
| 45 | + |
| 46 | +**Step 1: Add ramp arg parser helper** |
| 47 | + |
| 48 | +Implement helper that converts repeatable `--arg` into: |
| 49 | +- `ramp_fields` map (`start`, `end`, `step`, `interval_s`) |
| 50 | +- `fixed_fields` map |
| 51 | + |
| 52 | +Rules: |
| 53 | +- tuple supports only 3 or 4 parts |
| 54 | +- all numeric values parsed via existing float helpers |
| 55 | +- step positive, interval positive when provided |
| 56 | + |
| 57 | +**Step 2: Update ramp argparse surface** |
| 58 | + |
| 59 | +Change `ramp` command arguments: |
| 60 | +- remove positional `start/end/step` |
| 61 | +- add repeatable `--arg key=value` |
| 62 | +- keep required `--interval-s` |
| 63 | + |
| 64 | +**Step 3: Update ramp handler `_cmd_ramp`** |
| 65 | + |
| 66 | +Build parsed spec from `--arg` values and pass to driver multi-field planning/execution API. |
| 67 | + |
| 68 | +**Step 4: Update help text and examples** |
| 69 | + |
| 70 | +Use approved contract example: |
| 71 | +- `nqctl ramp scan_frame --arg Width=10e-9:20e-9:1e-9 --arg Height=8e-9:16e-9:1e-9:0.14 --interval-s 0.1` |
| 72 | + |
| 73 | +**Step 5: Run focused CLI tests** |
| 74 | + |
| 75 | +Run: `python -m pytest tests/test_cli.py -q` |
| 76 | + |
| 77 | +### Task 3: Add failing driver tests for multi-field ramp scheduling and autofill preservation |
| 78 | + |
| 79 | +**Files:** |
| 80 | +- Modify: `tests/test_qcodes_driver.py` |
| 81 | +- Modify: `nanonis_qcodes_controller/qcodes_driver/instrument.py` |
| 82 | + |
| 83 | +**Step 1: Add failing test for multi-field ramp plan generation** |
| 84 | + |
| 85 | +Assert plan captures: |
| 86 | +- multiple ramp fields |
| 87 | +- per-field interval override behavior |
| 88 | +- merged tick schedule |
| 89 | + |
| 90 | +**Step 2: Add failing test for execution with fixed fields** |
| 91 | + |
| 92 | +Assert each `set` call includes: |
| 93 | +- current ramp values for active fields |
| 94 | +- fixed field values unchanged |
| 95 | + |
| 96 | +**Step 3: Add failing regression test for unspecified set fields unchanged** |
| 97 | + |
| 98 | +Use scan-buffer-style parameter and assert fields not in ramp args are autofilled and preserved. |
| 99 | + |
| 100 | +**Step 4: Run focused driver tests (expected fail)** |
| 101 | + |
| 102 | +Run: `python -m pytest tests/test_qcodes_driver.py -q` |
| 103 | + |
| 104 | +### Task 4: Implement multi-field ramp execution in driver |
| 105 | + |
| 106 | +**Files:** |
| 107 | +- Modify: `nanonis_qcodes_controller/qcodes_driver/instrument.py` |
| 108 | + |
| 109 | +**Step 1: Add internal data structures** |
| 110 | + |
| 111 | +Introduce typed structures for: |
| 112 | +- ramp field definition |
| 113 | +- fixed field definition |
| 114 | +- merged timeline steps |
| 115 | + |
| 116 | +**Step 2: Add multi-field planning API** |
| 117 | + |
| 118 | +Implement `plan_parameter_ramp_fields(...)` that: |
| 119 | +- validates writable spec and safety |
| 120 | +- builds per-field targets from start/end/step |
| 121 | +- merges by per-field intervals with global fallback |
| 122 | + |
| 123 | +**Step 3: Add multi-field execution API** |
| 124 | + |
| 125 | +Implement `ramp_parameter_fields(...)` that: |
| 126 | +- executes timeline via repeated `set_parameter_fields` |
| 127 | +- honors `plan_only`/policy mode |
| 128 | +- records write audit entries |
| 129 | + |
| 130 | +**Step 4: Preserve existing scalar ramp compatibility** |
| 131 | + |
| 132 | +Retain `plan_parameter_ramp` / `ramp_parameter` behavior by delegating to the new engine for single-field ramps. |
| 133 | + |
| 134 | +**Step 5: Run focused driver tests** |
| 135 | + |
| 136 | +Run: `python -m pytest tests/test_qcodes_driver.py -q` |
| 137 | + |
| 138 | +### Task 5: Update capabilities/docs output and user docs |
| 139 | + |
| 140 | +**Files:** |
| 141 | +- Modify: `README.md` |
| 142 | +- Modify: `docs/cli_contract.md` |
| 143 | +- Modify: `nanonis_qcodes_controller/cli.py` (payload/help text if needed) |
| 144 | + |
| 145 | +**Step 1: Update README ramp examples** |
| 146 | + |
| 147 | +Replace scalar positional example with approved `--arg` contract. |
| 148 | + |
| 149 | +**Step 2: Update CLI contract command description** |
| 150 | + |
| 151 | +Document `ramp` as arg-fields driven with tuple syntax. |
| 152 | + |
| 153 | +**Step 3: Ensure output payload includes ramp fields/fixed fields metadata** |
| 154 | + |
| 155 | +If added in handler, document briefly and keep payload deterministic. |
| 156 | + |
| 157 | +**Step 4: Run doc-focused tests** |
| 158 | + |
| 159 | +Run: `python -m pytest tests/test_docs_parameters_manifest.py tests/test_release_docs.py -q` |
| 160 | + |
| 161 | +### Task 6: Full verification and release readiness |
| 162 | + |
| 163 | +**Files:** |
| 164 | +- Verify all modified files |
| 165 | + |
| 166 | +**Step 1: Run quality checks** |
| 167 | + |
| 168 | +Run: |
| 169 | +- `ruff check .` |
| 170 | +- `black --check .` |
| 171 | +- `mypy nanonis_qcodes_controller` |
| 172 | + |
| 173 | +**Step 2: Run full test suite** |
| 174 | + |
| 175 | +Run: `python -m pytest` |
| 176 | + |
| 177 | +**Step 3: Summarize contract changes** |
| 178 | + |
| 179 | +Prepare release-note bullets for: |
| 180 | +- new ramp arg tuple contract |
| 181 | +- per-field interval override behavior |
| 182 | +- unspecified field preservation behavior |
0 commit comments