Callers had to read back the side-effected status ref to know why a pull failed, which also broke TS narrowing on the freshness badge handler. Return { raw, failureStatus } so the reason flows through the return value.