feat: hard-fail on unrecognized OAuth client, add rekey flow
Gardens with stored credentials that fail reauthentication no longer
silently re-register as new gardens. Instead they attempt a rekey via
the new POST /api/v1/gardens/:sid/rekey endpoint, which creates a new
OAuth client for the existing garden identity.
Server-side changes:
- Add rekey_garden/2 to Sower.Orchestration.Garden
- Add rekey action to GardenController with garden:register permission
- Rescue ArgumentError in GardenSocket when Boruta token references a
deleted OAuth client
Client-side changes:
- Add SowerClient.Registration.rekey/3
- Add try_http_rekey path in resolve_connect_token when garden has a
stored garden_sid but no usable credentials
- Fresh registration only happens for truly new gardens (no garden_sid)
sow-157
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>