Thanks David,
The values I'm using all come from gpsd through the gpsmm library, and not directly from the device itself. I'm opening the gpsd socket with 'WATCH_ENABLE|WATCH_TIMING', and reading the fix.time property (as well as the fix.ept and dop.tdop properties which don't help). The fix.time property is approximately UTC + 3s before a correction, and exactly UTC after a correction. It's not a caching issue, when a correction comes, successive messages wind back the time. As far as I can tell the uncompensated GPS time is not available through gpsd? Do I need to step around gpsd and read the raw messages to get GPS time?
Because the corrections usually come within 7 minutes of boot, sometimes within 1 minute, I don't think the device is waiting for a full almanac download before issuing a correction as this can take 12 or so minutes (I believe)? One possibility is that the device is applying an offset pre-programmed in its firmware until it can somehow determine the correct one, and a +3s figure would put the date of the firmware between 2009 and 2011. I guess I'll have to follow up with uBlox on this theory.
Simon.