fix(deploy): let --reconnect refresh a revoked harness LLM credential

Merged
KH
4mo ago
+186-20

Problem

The pr-reviewer cloud persona (and any oauth-harness persona) was failing every fire across every repo with The review harness exited with code 1. Root cause traced via Daytona: the baked codex/ChatGPT OAuth token was revoked server-side (401 token_invalidated / refresh_token_invalidated). Each codex session ended in ~3.6s with last_agent_message: null — the harness never authenticated.

This happens whenever you re-run codex login locally on the same ChatGPT account: OpenAI rotates the refresh token and revokes the copy cloud baked into each fire.

The gap that made it unrecoverable from the CLI:

  • Cloud reports a credential row as status: connected even when its stored token is revoked (it never re-validates the token).
  • ensureHarnessOauth / ensureSubscriptionOauth short-circuit on that connected status, so a plain redeploy can never refresh a dead harness credential.
  • --reconnect <provider> only flowed to the integrations connect path (connect.ts), never the LLM harness credential.

The only recovery was manually disconnecting the credential in the dashboard.

Fix

Thread reconnectProviders into ModeLaunchInput and both harness-oauth paths. When --reconnect <provider> matches the persona's model provider (openai/anthropic) or harness name (codex/claude), force a fresh connectProvider flow that overwrites the stored token even when cloud reports it connected. connectProvider blocks until cloud stores the fresh credential, so the new token is live when deploy proceeds. Under --no-prompt it fails with actionable guidance (the connect flow needs a TTY).

Recovery is now one flag instead of a dashboard round-trip:

agentworkforce deploy ./review/persona.ts --on-exists update --reconnect codex …

Changes

  • types.ts — reconnectProviders on ModeLaunchInput
  • deploy.ts — thread it into the launch input + ensureCloudSubscriptionReady
  • modes/cloud/index.ts — ensureHarnessOauth + ensureSubscriptionOauth honor reconnect; new harnessReconnectRequested() (matches provider key or harness name)
  • cli/src/deploy-command.ts — clarify --reconnect help to cover the harness LLM credential
  • modes/cloud.test.ts — 2 new tests

Testing

  • @agentworkforce/deploy: 202/202 pass (incl. the 2 new reconnect tests); typecheck clean
  • @agentworkforce/cli: deploy-command 12/12; typecheck clean

🤖 Generated with Claude Code