Skip to content

fix(macos): unbreak Re-pair recovery from revoked refresh token#30182

Merged
siddseethepalli merged 1 commit into
mainfrom
do/repair-velissa-recovery-fixes
May 10, 2026
Merged

fix(macos): unbreak Re-pair recovery from revoked refresh token#30182
siddseethepalli merged 1 commit into
mainfrom
do/repair-velissa-recovery-fixes

Conversation

@siddseethepalli
Copy link
Copy Markdown
Contributor

@siddseethepalli siddseethepalli commented May 10, 2026

Summary

  • forceReBootstrap now sweeps guardian-token.json across every VellumEnvironment config dir (not just the active one) and always passes skipFileImport=true, so a server-revoked-but-not-expired token in a sibling env can no longer silently re-arm itself via seedGuardianTokenFromSiblingEnv on the next vellum wake.
  • The HTTP /v1/guardian/init retry loop in performInitialBootstrap no longer waits for connectionManager.isConnected — that flag requires a 200 health-check, which requires the credential we're trying to mint, deadlocking every recovery from a wiped keychain.
  • New VellumPaths.allEnvs(...) factory + VellumEnvironment: CaseIterable enable the multi-env sweep; GuardianTokenFileReader.deleteTokenFileAcrossAllEnvs does the work and is covered by three unit tests.

Original prompt

While debugging an "Authentication failed — use Re-pair" loop on the macOS app, we traced it to a server-side-revoked refresh token that the bundled gateway no longer accepts. Re-pair didn't recover because (1) the CLI's sibling-env token seeder kept restoring the stale token after each cleanup, (2) the HTTP /v1/guardian/init fallback awaited a connection state that itself requires auth, and (3) forceReBootstrap explicitly preserved the stale local token "as the only recovery artifact." Recovery required manually POSTing to /v1/guardian/init and writing the response into UserDefaults. This change makes Re-pair self-sufficient again.

🤖 Generated with Claude Code


Open in Devin Review

Three bugs combine to make the Re-pair menu action unable to recover a
server-side-revoked refresh token, leaving the user stuck in
"Authentication failed" until they manually inject credentials:

1. forceReBootstrap deleted only the active env's guardian-token.json on
   remote hatches and preserved the file on local hatches. The CLI's
   seedGuardianTokenFromSiblingEnv (cli/src/lib/guardian-token.ts) then
   restored a stale token from a sibling env on the next vellum wake —
   refresh-window expiry is a clock check, not a server-validity check,
   so revoked-but-not-expired tokens silently re-armed.

2. performInitialBootstrap's HTTP retry loop awaited
   connectionManager.isConnected before calling /v1/guardian/init.
   isConnected only flips true after a 200 health-check response, which
   requires the credential the loop is trying to mint. No auth →
   no isConnected → no bootstrap → no auth.

3. forceReBootstrap passed skipFileImport=false on local hatches with
   the comment "preserving guardian token file as the only recovery
   artifact" — combined with #1, this re-imported the just-restored
   stale token.

Fixes:
- forceReBootstrap now sweeps guardian-token.json across every
  VellumEnvironment config dir via the new
  GuardianTokenFileReader.deleteTokenFileAcrossAllEnvs helper, and
  always passes skipFileImport=true.
- HTTP retry loop drops the isConnected gate; bootstrapActorToken
  surfaces gateway-down errors via its own return value.
- Adds VellumPaths.allEnvs(...) factory and CaseIterable conformance
  on VellumEnvironment so the sweep can iterate all env config dirs.

Tests cover the new helper across sibling-env layouts and ensure
unrelated assistants are untouched.
@siddseethepalli siddseethepalli merged commit b6204fa into main May 10, 2026
@siddseethepalli siddseethepalli deleted the do/repair-velissa-recovery-fixes branch May 10, 2026 05:14
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

View 3 additional findings in Devin Review.

Open in Devin Review

Comment thread clients/shared/App/Auth/GuardianTokenFileReader.swift
Comment thread clients/shared/App/Auth/GuardianTokenFileReader.swift
siddseethepalli added a commit that referenced this pull request May 10, 2026
guardianTokenPath now requires a paths: VellumPaths argument (added
in #30182), but importIfAvailable was missed during that refactor and
still calls it with the old single-argument signature, breaking the
macOS build.

Co-authored-by: Vellum Assistant <assistant@vellum.ai>
@siddseethepalli
Copy link
Copy Markdown
Contributor Author

Addressed in #30522 (importIfAvailable signature was already fixed by #30183; #30522 removes the now-unused single-env deleteTokenFile helper).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant