I found the issue. Paragon Chat is sending the discovery iq without a 'to' attribute. The original XMPP Core spec (RFC 3920) states that the server should take the appropriate action if it recognizes the request namespace, implying that this iq is 'to' the server itself.
RFC 6120 adds some explicit rules for this scenario -- an iq without a 'to' attribute is assumed to be to the
user's entity (username@server.tld). This has important consequences for disco#items, because it means that the server responds to this request with the items that belong to the user, not to the server.
Openfire 4.1.0 and later changes its behavior from the old spec to the newer one. I suspect Prosody's behavior is derived from RFC6120 also.
Specifically, it's this commit:
https://github.com/igniterealtime/Openfire/commit/95f40ab7a64f7d90481476598c6a4d69c601515awhich references these issues:
https://issues.igniterealtime.org/browse/OF-872https://issues.igniterealtime.org/browse/OF-462I've reproduced the issue by updating my local test openfire instance to 4.1.5, and tested a fix that explicitly addresses the discovery 'to' the server itself. That will ensure it works properly with either version of the spec. It'll be in the pipeline for release soonish.