Rather than using keys, an alternative approach might be to use tail-recursive templates to implement a kind of "while loop":
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" />
<!-- normal case - identity transform -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<!-- for elements that contain adjacent child elements with the same name -->
<xsl:template match="*[*[name() = name(preceding-sibling::*[1])]]">
<xsl:copy>
<!-- wrap contents in an s -->
<s>
<!-- wrap each "run" of consecutive elements with the same name in
another s. We do this by applying "seq" mode templates to
the _first_ element in each run. -->
<xsl:for-each select="*[name() != name(preceding-sibling::*[1])]">
<s><xsl:apply-templates select="." mode="seq" /></s>
</xsl:for-each>
</s>
</xsl:copy>
</xsl:template>
<!-- tail recursion - process self with normal mode templates, then recurse
with this template for next sibling if its name matches mine -->
<xsl:template match="*" mode="seq">
<xsl:apply-templates select="." />
<xsl:apply-templates mode="seq"
select="following-sibling::*[1][name() = name(current())]" />
</xsl:template>
</xsl:stylesheet>
The tail recursive seq
mode template is effectively a loop saying keep processing elements (using the default mode templates) until you reach one with a different name.