resumeSession always forces a token refresh, and atproto refresh tokens are single-use: the server rotates the refresh token and invalidates the old one. Rotated tokens weren't getting persisted, so the keychain kept the original refresh token. Once the server stopped accepting the consumed token, every command failed until re-authenticating
This saves the agent's session after resumeSession so the rotated tokens are durably stored for the next invocation, and adds an integration test that drives the real CredentialSession through a stubbed fetch to prove the rotated refresh token reaches the keychain.
Co-authored-by: Claude (claude-opus-4-8) noreply@anthropic.com