lein repl does no such thing. You can test this yourself:
# stop our individual writes from overlapping
with_lock() { exec {lock_fd}>>./tty_write_lock; flock "$lock_fd"; "$@"; exec {lock_fd}>&-; }
lein repl 3>&2 \
> >(while IFS= read -r line; do with_lock printf 'O:<%q>\n' "$line" >&3; done) \
2> >(while IFS= read -r line; do with_lock printf 'E:[%q]\n' "$line" >&3; done) \
3>&- <<'EOF'
(.println System/err "something on stderr")
(.println System/out "something on stdout")
EOF
...which contains, among other output:
O:<$'user=> (.println System/err "something on stderr")\E[50G\E[8G\E[51G'>
E:[something\ on\ stderr]
O:<nil>
O:<$'user=> (.println System/out "something on stdout")\E[50G\E[8G\E[51G'>
O:<something\ on\ stdout>
O:<nil>
As you can see, something on stdout is inside O:<...>, as created by the process substitution handling stdout; whereas something on stderr is inside E:[...], as created by the process substitution handling stderr.
To look at it a different way:
{ strace -f -e write lein repl 2>&1 | egrep 'write[(][12],'; } <<'EOF'
(.println System/err "something on stderr")
(.println System/out "something on stdout")
EOF
...includes among its output the following syscalls:
[pid 10467] write(2, "something on stderr", 19) = 19
[pid 10467] write(1, "something on stdout", 19) = 19
...as you can see, the stderr one is correctly written to FD 2, whereas the stdout one is correctly written to FD 1.