That bug is signed overflow, and yes, the sign bit is exactly where it lives. When -100 + -100 happens, the true answer -200 needs 9 bits in two's complement, so the extra bit gets chopped off and your 8-bit result wraps around to +56. The trick with flags: overflow is detected just by looking at the top three sign bits. If both operands have the same sign bit and the result has a diferent one, you overflowed. In Verilog that's one line: assign overflow = (a[7] == b[7]) && (sum[7] != a[7]);. For subtraction, flip it around since a - b is a + (-b), so the operand signs differ. Add that as an output flag on your ALU and your testbench can assert on it directly.
As for a ninth bit, you can absolutely do it. Sign-extend both inputs to 9 bits before the adder, take the result from bits 7:0, and if bit 8 doesn't match the sign extension of bit 7, that's your overflow flag for free. Doing both approaches in simulation and checking they agree is a nice sanity check on the whole design. For the testbench, two negatives is only one of four sign combinations, so test all of them. Better yet, loop a through 0 to 255, loop b the same, and compare against a 9-bit or wider reference computation using $signed casts. That's only 65k cases, runs in a blink, and catches every boundary: -128 + -1, 127 + 1, -128 - 1. Those edge values are where hand-picked test vectors always seem to miss something.
On the ugly operand routing: you usually don't need a case statement at all. Compute the two's complement of b as ~b + 1, feed the adder either b or that inverted version, and drive the carry-in with the subtract signal (1 for subtract, 0 for add). That collapses the whole thing to a mux, an XOR layer, and one adder. Same hardware idea the classic 74181 used.