Really amazing, other controls like @observablehq/Inputs support being set programatically, I would expect ui.first = 5 would update the ui but not raise an event and I could ui.dispatchEvent(new Event('input')) to initiate dataflow propogation.
Some of these idioms are covered in https://observablehq.com/@tomlarkworthy/ui-linter
@Tom,
I'm afraid that "ui.first = 5" is not possible without upsetting the structure.
I added the set function "ui.set ('first', 5)", it seems to work and all the synchronization mechanisms seem correct.
Attention, if a field (for example "first") has the specified step attribute, the value entered with set will be rounded to the step.