Skip to content

[FEATURE] Mobile-first passwordless phone login (Builder merged+live; blocked on core#8529 send-otp 500) #944

Closed

Description

@developer-ainative

Feature

Mobile-first, passwordless phone-number login: on a mobile device, detect that and serve a phone-number-first signup/login experience instead of email/password — founder enters their phone, gets a real texted code (Twilio, already live via #938/#939), enters it, and is signed in. No password, no email, on that path.

Full design: docs/superpowers/specs/2026-10-05-mobile-phone-login-design.md (this PR).

Real blocker, confirmed against core's actual code (2026-10-05)

core's /api/v1/auth/register and /api/v1/auth/login are hard-required email+password contracts (UserCreate.email: EmailStr, no default; password_hash verified at login) — and the real production users table has zero phone column. This is genuinely new identity infrastructure, not a gap in an existing field.

This is a two-repo feature, sequenced:

  • Part 1 (blocks everything else) — needs its own issue on AINative-Studio/core: native users.phone column, POST /register-phone + POST /login-phone endpoints, core's own OTP send/verify (not a reuse of Builder's lib/build/otp.ts, which is Builder-local state), and an audit of every place core currently assumes email IS NOT NULL (password reset, verification emails, Stripe receipts).
  • Part 2 (this repo, gated on Part 1 shipping): mobile detection in Auth.tsx (CSS-media-query-driven, to avoid SSR hydration mismatch — NOT a navigator.userAgent client check), phone-only signup/login markup, new app/api/build/register-phone/login routes mirroring the existing /api/build/register pattern (same Turnstile-first, fail-closed shape, same signup_source: 'builder' attribution), and a real next-auth integration decision (a phone-login session has no password to hand the existing credentials provider).

Unified with the shared Text-Cody number feature (#936/PR #937)

Per explicit product direction: a founder's phone-login number becomes their one number of record for BOTH login and all Cody SMS communication (feature requests, status, the shared-937-number conversation) — not two independently-tracked numbers. PR #937 was updated to reflect this (its findFounderByPhone() checks core's new users.phone first, falling back to the existing builder_founder_phones table for email/password founders with an optional verified phone).

This issue's scope

File the core-side issue first (this feature cannot start on Builder's side until Part 1 exists), then track Part 2 here once that's filed and its timeline is known.

Fibonacci estimate

Unknown until Part 1's core-side scope is sized by that team — Part 2 alone (mobile UI + Builder API routes + next-auth integration) is likely an 8, assuming Part 1's contract is stable by the time Part 2 starts.

Activity

  1. developer-ainative commented on Oct 5, 2026

    @developer-ainative
    ContributorAuthor

    Blocking core-side issue filed: AINative-Studio/core#8459 — Part 1 of this feature (native phone-identity schema + endpoints) cannot start on Builder's side until that's shipped.

  2. developer-ainative commented on Oct 6, 2026

    @developer-ainative
    ContributorAuthor

    Status update (2026-10-06): core#8459 (the real blocker this issue names) is now CLOSED — its PR, core#8463, merged to core's main at 2026-10-06T04:44:03Z, delivering users.phone/phone_verified_at, a phone_otp_codes table, and send-phone-otp/register-phone/login-phone endpoints, plus making users.email nullable.

    However, verified directly just now that these endpoints are NOT yet live in core's production API — GET https://api.ainative.studio/openapi.json does not list /api/v1/auth/register-phone, /api/v1/auth/login-phone, or /api/v1/auth/send-phone-otp (a direct POST to register-phone also did not behave as a real implemented route would). The code is merged to core's main but core's production deploy does not appear to include it yet.

    This issue stays open and blocked until that's confirmed live — will re-check core's production OpenAPI before starting any Builder-side work against these endpoints, consistent with this repo's own precedent of verifying external claims rather than relaying them (see builder's own feedback_verify_before_relaying_external_status practice).

  3. developer-ainative commented on Oct 6, 2026

    @developer-ainative
    ContributorAuthor

    The core-side blocker is resolved: core#8459 (phone-identity register/login, OTP-based) merged and shipped tonight via core PR #8463. Backend endpoints for phone registration/login are live. This should be unblocked on builder's side now — the frontend passwordless-login UI work can proceed against the real backend.

  4. developer-ainative commented on Oct 6, 2026

    @developer-ainative
    ContributorAuthor

    Update (2026-10-06): core's Part 1 blocker (#8459) is closed — users.phone, /auth/register-phone, /auth/login-phone are merged to core main via core#8463 (2026-10-06T04:44 UTC) and the code is correctly implemented and wired.

    However, verified live against production (api.ainative.studio) as of 2026-10-06T19:20 UTC: /api/v1/auth/register-phone still 404s — the merged code is not actually serving traffic yet, despite a deploy firing after the merge. Filed core#8512 to track that gap specifically.

    Re-titling this issue's blocker framing: no longer "needs core-side feature work" — now "needs core#8512 (deploy gap) resolved, then Part 2 can integrate against a stable, live contract." Part 2 scoping (mobile detection in Auth.tsx, app/api/build/register-phone/login-phone routes, next-auth credential-less session integration) can start in parallel since the code contract itself looks stable, but don't wire real calls against prod until core#8512 is closed.

  5. changed the title [-][FEATURE] Mobile-first passwordless phone login (design spec ready; blocked on core phone-identity work)[/-] [+][FEATURE] Mobile-first passwordless phone login (core code merged, blocked on core#8512 prod deploy gap)[/+] on Oct 6, 2026
  6. developer-ainative commented on Oct 7, 2026

    @developer-ainative
    ContributorAuthor

    Update (2026-10-07): Builder-side Part 2 merged and deployed — builder#1005, live in production as of commit 236a18e. Verified: /api/build/register-phone and /api/build/login-phone are live and correctly proxy core.

    core#8512 (the original deploy-gap blocker) is genuinely resolved — independently verified via POST (not GET, which is misleading on these POST-only routes) that core's three phone-identity endpoints return real 422 validation responses in production, not 404.

    However, a NEW core-side bug blocks the actual end-to-end flow: POST /auth/send-phone-otp 500s with a raw ValueError for every phone number tested, including invalid ones that should cleanly 400. This is the first step of the real signup/login flow (send the code before register/login can proceed), so no real founder can complete phone sign-in yet despite all the routes being individually reachable. Filed core#8529 with what I found reading the code (ruled out the purpose field as the cause; the crash is in or before PhoneOtpService.send_code's Twilio verification call).

    Leaving this issue open — Builder's work is done and live, but the feature isn't usable by a founder until core#8529 resolves.

  7. changed the title [-][FEATURE] Mobile-first passwordless phone login (core code merged, blocked on core#8512 prod deploy gap)[/-] [+][FEATURE] Mobile-first passwordless phone login (Builder merged+live; blocked on core#8529 send-otp 500)[/+] on Oct 7, 2026
  8. developer-ainative commented on Oct 12, 2026

    @developer-ainative
    ContributorAuthor

    Verified live (2026-10-12): Builder's side of this feature has been fully shipped since PRs #1005/#1006/#1007/#1010 (merged to main) — phone-first mobile signup/login UI, register-phone/login-phone API routes, next-auth phone-login credentials provider, and SMS opt-in disclosure all in place.

    This issue's title referenced core#8529 (/auth/send-phone-otp 500ing in production) as the blocker. That issue is now closed, and I've confirmed live against production:

    POST https://api.ainative.studio/api/v1/auth/send-phone-otp
    → {"detail":"SMS verification is temporarily unavailable","error_code":"SMS_NOT_CONFIGURED","next_action":"fallback_model"}
    

    No more 500 crash — the endpoint now degrades honestly. The only remaining real-world blocker is the same upstream Twilio A2P 10DLC carrier-review campaign tracked in core#8533 (also the subject of #1047, just merged) — not a core or Builder bug. Once that campaign clears, this feature works end-to-end with zero further changes needed on either side.

    Closing — there's no remaining implementation work in this repo.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions