The first thing I would do would be to take some of the inner forms and turn them into functions (single responsiblity). This isn't even Clojure-specific.
Lots of little, simple functions, composed... You can still use the threading at a higher function, but instead of doing the actual work at each step in the pipeline, you call a well-named function which does what that step was doing. Yes, it may feel redundant, but it absolutely improves human comprehension because it reads like clear human instructions.
Tests become much simpler too.
The only two challenges I face with this approach is 1 - naming things, and 2 - organizing. The function names tend to become quite long, since they ideally describe what the function does.
I haven't done this lately, now that the AI tools have become pretty great; I can imagine that an AI tool would be an excellent knowledge base for these many functions, and it would probably be very successful in providing additions or modifications given the clean, clear function names and brief contents.
>Yes, it may feel redundant, but it absolutely improves human comprehension because it reads like clear human instructions.
That should always be how code is written, including inside of functions, which is the real problem here. Something absent from the original code that is needed in a case like this isn't more functions, it's comments and good names.
Pulling something out into a function that is purely individual application logic without intent for reuse is not the right way to use a function, whose purpose is to be called, ideally somewhere else and not just once. As Ousterhout points out in his book, proper abstractions hide information and implementation, they aren't just scaffolding that increase the surface of an interface without doing anything.