After a lengthy email discussion with @peternlewis we managed to track down the root cause. I've been meaning to do a write-up of the resolution a couple of weeks now, so here it is for future reference:
As already mentioned, iTerm worked fine when it was sent Unicode keystrokes by Hammerspoon, so it's not as if iTerm was incapable of it. Keyboard Maestro however, does something more elaborate: it will attempt to find each Unicode character in the currently active Input Source (ie the keyboard layout), and will replay the actual combination of modifier keys and letter required to produce that character.
As Peter puts it:
The difference between Keyboard Maestro’s processing and Hammerspoon is that for keys that can be typed in the current keyboard layout, Keyboard Maestro types them that way, and only for characters that cannot be typed that way does it resort to sending a Unicode character.
Keyboard Maestro it typing the characters as they would be typed on the keyboard, and iTerm is, for reasons of its own choosing, converting them to other behaviours.
For example, the middle dot (·) is typed with option-shift-9 under my current keyboard layout. Instead of sending a simple key event with just the middle dot, KM sends a full blown option-shift-9 to iTerm, which (in my current setup) treats the option key as Esc+:
(Switching this to Normal would fix the issue but is not an option)
At the moment I'm finding it hard to find any practical use for this behavior, but I respect Peter's judgement, and he was even cool enough to include a new preference in the next update addressing this issue:
I have added an undocumented and unsupported hidden preference for the next version, which you can enable with the command:
defaults write com.stairways.keyboardmaestro.engine ForceInsertTextByTypingToUseUnicode -bool YES
For the time being I'm working around the issue by having KM call a hammerspoon://paste-by-typing?text=... URL, and HS will subsequently do the typing.
PS - In case you're wondering why I'm choosing to use the keystroke method instead of paste (which works flawlessly btw), the answer is to avoid littering my clipboard history.