Problem #
computeScopeForDid (lib/auth/client.ts:58-67) picks the sign-in OAuth scope from the legacy automations.actions column:
const allActions = rows.flatMap((r) => r.actions);
if (allActions.length === 0) return OAUTH_SCOPE_BASIC;
Since the steps-model engine (1715718), new automations write only steps (app/routes/api/automations/index.ts:202-219). The actions column stays at its [] default (lib/db/schema.ts:357, 361-365).
So a user whose automations were created or edited under the steps model always signs in with OAUTH_SCOPE_BASIC, even if those automations write records and need OAUTH_SCOPE_FULL.
The create/update path already computes the scope correctly from steps: scopeCoversActions(user.scope, actionsForScope(steps)) in app/routes/api/automations/index.ts:160. That check returns SCOPE_INSUFFICIENT, and the form then redirects to a scope upgrade.
Impact #
- After every fresh sign-in, the first create or edit of a record-writing automation sends the user back through OAuth. This covers Create a record, Bluesky post, follow, etc.
- Users read this as being "logged out for doing nothing".
- The form doesn't save a draft before the redirect (separate issue), so the user loses everything they entered. This happened twice in one recorded user session, at 0:44 and 1:31 in https://www.youtube.com/watch?v=5MnT-ZgbBIc
Fix direction #
- Derive the scope from
stepsby reusingactionsForScope(move it out of the route intolib/if needed). Fall back toactionsfor rows that haven't been migrated. - Add a test: a user whose only automation is a steps-model record action gets
OAUTH_SCOPE_FULLfromcomputeScopeForDid.
Details: docs/brainstorms/2026-10-17-graze-conference-automation-feedback.md (B1).
Fixed in f13d049: the sign-in scope is now derived from the steps tree.