Thanks to everyone who watched the test stream / gave helpful advice.
Here is a repo of the input timestamp files I used, I'll be adding more as I get more organized:
https://github.com/alyosha-tas/GBI_timestamps
I'll link this in the opening post too.
Also I did some more research on oracle of ages / seasons. Seasons was randomly syncing occasionally despite not properly clearing RAM, so I went back to Ages to see if maybe I missed something.
It turns out that when I was verifying ages I was writing 0 to SRAM before playing the game, not 0xFF. Desptie this fact, I played the run on console several times this way and it always synced. In emulator though, 0xFF was written. If I tried writing 0xFF to the game, it now desyncs on console. How can that be?
Ages reads several areas of unintialized RAM in order to set start up values. So, it must be that the initial state in GBA mode is different then in a CGB, so that the error in the time spent clearing WRAM cancels out the error in the time spent clearing SRAM when it is 0xFF. As unlikely as this sounds, it's basically the only variable that can change.
I tried a few different possible initial RAM states, and indeed there are some possibilities where the difference in cycles executed after initial startup is only a few hundred cycles.
So I think we really need a dump of WRAM from a GBP to see what it actually is.