When testing a library, especially your own, it helps to complete the entire circuit board first. I found that:
1. I didn’t run a line from either of the MCP interrupt pins to either of the AVR interrupt pins
2. I didn’t connect ANY of the 8 I/O pins on the MCP port B to the header.
After correcting those I still have some pretty odd behaviours, like interrupts being tripped when connecting a wire to a spare ground pin to test the I/O pins. I checked with the data sheet and it confirmed I’ve set the correct interrupt logic; because I’m using a compare to register it stays tripped until the connection is cleared. I may have to re-think this, because I was expecting the same behavior as interrupt on change, where it wouldn’t keep re-tripping.
Also, so I remember, the reason I chose to not swap out my library for the Adafruit library was that I was storing the port reads directly into the register array.
Anyway, I did discover there is still another wiring fault. A cold solder joint or crack or something. I get random interrupts but I can’t nail it down to a single pin or connection.
That’s what I get for rushing the design and not etching a real PCB.