I think found my problem. in OpenCat.ino, line 632 you have:
if (strcmp(newCmd, "") && strcmp(newCmd, lastCmd) ) {
but the treatment is inconsistent for skills. Balance, specifically, writes something else in lastCmd even though it's a skill. Check out line 711:
strcpy(lastCmd, "balance");
So that strips the "k", meaning you can send "kbalance" in a row, whereas if you send other skills like crawl forward, etc. it gets ignored. Makes sense I guess if you're on a remote that keeps sending the same command over and over again, you don't want to restart the sequence.
Somehow - haven't finished tracing all the code (like around line 650), if you have a sequence over serial like "kcrF" -> "kbalance" -> "kcrF", the second "kcrF" will get eaten.
Would be nice to document the state machine explicitly, clean it up a bit and break up the code into more functions - but I can't complain, it works and wouldn't have wrote it myself, so here we are.