Sadly, even the most basic of code, with even log levels of logging enabled can easily hit a 1M code space limit. So I decided to make a new partition table.
Just two OTA spacesThe first thing I confirmed is that if I just have two OTA areas, and no "factory" area, it works fine. It can alternate the OTA flashing, and make flash just flashes the first OTA area.
Oddly, it looks to me like you can have two OTA areas of 0x1F8000 but the make system said it would not fit. I ended up going for 0x1F0000 which is close to 2M.
On the fly updateThe real trick was changing the partition table on the fly. The key issue here was ensuring the original factory build was in the same place as the first new OTA block. I changed from factory+ota_0+ota_1 to just ota_0+ota_1 at 0x10000. This meant, whichever image I was running, by changing the partition table a reboot would find the factory release (in ota_0) and run it.
I simply had to erase and re-flash the partition block. I obtained the signed binary partition from the build directory and embedded. Then I just reboot, and sorted. Obviously you then need an OTA upgrade to move off the original factory code.
The simplest check was to compare the current partition table with the one I want, and if different, re-flash and reboot.
You do need to tell the SPI flash component to allow you to erase/write to dangerous areas of flash, but otherwise the code was pretty simple.
End result, I have nearly twice the code space.