ESP32-S3 reset/flashing problems

I am using one of these ESP32-S3 boards: https://www.amazon.co.uk/dp/B0CPYJ19NM
… with this configuration: https://git.infradead.org/?p=users/dwmw2/esp32-pool.git;a=blob;f=paper.yaml;hb=HEAD

I chose adafruit_feather_esp32s3 as the board because that has the right amount of flash.

Once it’s running, it appears as the following USB device:

[847848.171187] usb 1-1: New USB device found, idVendor=239a, idProduct=811b, bcdDevice= 1.00
[847848.171196] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[847848.171200] usb 1-1: Product: Feather ESP32-S3
[847848.171203] usb 1-1: Manufacturer: Adafruit

Flashing it in this state doesn’t work. ‘esphome run’ tells me to try running esptool.py instead, but they both behave the same way.

Found multiple options for uploading, please choose one:
  [1] /dev/ttyACM0 (Feather ESP32-S3 - TinyUSB CDC)
  [2] Over The Air (paper.local)
(number): 1
esptool.py v4.6.2
Serial port /dev/ttyACM0
Connecting.............
ERROR Running command failed: write failed: [Errno 19] No such device
ERROR Please try running esptool.py --before default_reset --after hard_reset --baud 460800 --port /dev/ttyACM0 --chip esp32s3 write_flash -z --flash_size detect 0x10000 /home/dwmw/esphome/.esphome/build/paper/.pioenvs/paper/firmware.bin 0x0000 /home/dwmw/esphome/.esphome/build/paper/.pioenvs/paper/bootloader.bin 0x8000 /home/dwmw/esphome/.esphome/build/paper/.pioenvs/paper/partitions.bin 0xe000 /home/dwmw/.platformio/packages/framework-arduinoespressif32/tools/partitions/boot_app0.bin locally.

Running that command at this point will work, because the device has disconnected from USB and reconnected as:

[847857.353276] usb 1-1: New USB device found, idVendor=303a, idProduct=1001, bcdDevice= 1.01
[847857.353285] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[847857.353288] usb 1-1: Product: USB JTAG/serial debug unit
[847857.353291] usb 1-1: Manufacturer: Espressif
[847857.353293] usb 1-1: SerialNumber: F4:12:FA:97:BE:EC

So at this point either ‘esphome run’ or the manual esptool.py command work for flashing the device…

esptool.py v4.6.2
Serial port /dev/ttyACM0
Connecting...
Chip is ESP32-S3 (revision v0.1)
Features: WiFi, BLE
Crystal is 40MHz
MAC: f4:12:fa:97:be:ec
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash will be erased from 0x00010000 to 0x000e0fff...
Flash will be erased from 0x00000000 to 0x00003fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Compressed 853952 bytes to 563044...
Wrote 853952 bytes (563044 compressed) at 0x00010000 in 8.3 seconds (effective 821.6 kbit/s)...
Hash of data verified.
Compressed 15040 bytes to 10364...
Wrote 15040 bytes (10364 compressed) at 0x00000000 in 0.3 seconds (effective 446.0 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 136...
Wrote 3072 bytes (136 compressed) at 0x00008000 in 0.0 seconds (effective 509.3 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.1 seconds (effective 648.6 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

Except that at the end, the hard reset doesn’t work, so the board doesn’t actually start running until I power cycle it.

Is there a way to fix these and make the programming work cleanly over serial?