Skip to content

Commit 89a07f4

Browse files
committed
1
1 parent 1bfc86f commit 89a07f4

File tree

2 files changed

+251
-0
lines changed

2 files changed

+251
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Multi-Field Ramp Arg-Fields Design
2+
3+
## Goal
4+
Extend `nqctl ramp` from scalar positional inputs to structured multi-field ramping aligned with `arg_fields` usage.
5+
6+
## Approved CLI Contract
7+
8+
```powershell
9+
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
10+
```
11+
12+
## Design Summary
13+
14+
`ramp` accepts repeatable `--arg key=value` where each value may be:
15+
- **Ramp tuple:** `start:end:step` or `start:end:step:interval`
16+
- **Fixed value:** `value` (held constant at each ramp step)
17+
18+
Global `--interval-s` remains required and acts as default interval for tuple values without an explicit per-field interval.
19+
20+
## Data Model
21+
22+
Each parsed `--arg` entry becomes one of:
23+
- `RampFieldSpec(name, start, end, step, interval_s)`
24+
- `FixedFieldSpec(name, value)`
25+
26+
Execution builds a merged step schedule over all ramp fields and applies each step using structured `set` with all required fields:
27+
- ramped fields -> current step value
28+
- fixed fields -> fixed value
29+
- unspecified set fields -> autofilled from latest `get` snapshot (existing behavior in `set_parameter_fields`)
30+
31+
## Timeline and Step Semantics
32+
33+
- Every ramp field yields its own value sequence from `start/end/step`.
34+
- At each execution tick, all active fields update.
35+
- If one field reaches `end` earlier, it remains at end value while others continue.
36+
- Per-field interval (4th tuple value) overrides global `--interval-s` for that field cadence.
37+
- Tick scheduler advances by the nearest pending field interval and updates any field due at that time.
38+
39+
## Validation Rules
40+
41+
- At least one `--arg` must be a ramp tuple.
42+
- Ramp tuple must contain exactly 3 or 4 numeric parts.
43+
- `step` must be positive.
44+
- `interval` (if present) must be positive.
45+
- `--interval-s` must be non-negative and required.
46+
- Unknown set arg names are rejected.
47+
- If parameter is non-writable or ramp-disabled by safety, reject.
48+
- If missing required set fields cannot be autofilled (no matching snapshot field), reject with explicit missing field list.
49+
50+
## Backward Compatibility
51+
52+
- Existing positional ramp form (`<start> <end> <step>`) will be deprecated in CLI help and can be retained for one transition release or removed immediately (project accepts breaking changes).
53+
- Runtime write semantics remain policy-guarded.
54+
55+
## Output Contract
56+
57+
Ramp result payload remains structured and gains multi-field metadata:
58+
- `ramp_fields`: parsed per-field ramp definitions
59+
- `fixed_fields`: explicit fixed args
60+
- `timeline`: optional condensed schedule summary (tick count, duration)
61+
- existing `plan`, `report`, `applied`, `timestamp_utc`
62+
63+
## Test Strategy
64+
65+
- CLI parsing tests for 3-part and 4-part tuples.
66+
- Mixed fixed+ramp args tests.
67+
- Per-field interval override tests.
68+
- Autofill preservation tests for unspecified fields (scan-buffer-style regression coverage).
69+
- Error tests for malformed tuples and missing required fields.
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
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

Comments
 (0)