One concern I have always had using micro-electronics to run sprinklers is the possibility of a system crash leaving a zone running indefinitely.
Have you considered the addition of any sort of fail-safe or dead-man circuit to your device? Looking at the schematic I would probably implement it as a simple re-settable RC timer (eg 555) that was reset by the clock and/or data signals to the shift register that runs the sprinkler zones, and connecting the output of that timer to the clear on the shift register. I don’t know how often the firmware refreshes the shift register now, but have it refresh every second or so shouldn’t be hard.
That’s a good suggestion. I am planning to use mcu’s watchdog timer for this. The very first version of the firmware actually did use watchdog timer to prevent deadlocks. But I removed it later. The shift register is now refreshed every second.