Here are two more pieces of information. First, the (or) branch of sre->procedure doesn't follow "leftmost, longest":
scheme@(guile-user)> (define (imsis re str) (irregex-match-substring (irregex-search re str)))
scheme@(guile-user)> (imsis '(** 1 1 (or "free" "freedom")) "freedom")
$11 = "free"
The fixed range of 1 is only there to cause irregex to use sre->procedure. A plain 'or' uses a vanilla NFA, the implementation of which seems to work. Second, the 'or' can be forced to use later branches to reach a non-zero lower range limit, but no further, again in violation of "leftmost, longest":
scheme@(guile-user)> (imsis '(** 2 4 (or "a" "ab")) "abababab")
$12 = "aba"
scheme@(guile-user)> (imsis '(** 3 4 (or "a" "ab")) "abababab")
$13 = "ababa"
The way in which the (or) branch is broken seems fairly clear, but for the (**) branch I do not have all the details yet.