Skip to content

[gig-lesson] Pass 60: SMS-OTP via chat.db IS real (corrects pass59) but requires Bluetooth-connected iPhone #725

Description

@Daisuke134

Discovery (corrects pass 59's wrong conclusion)

pass 59 concluded "no automated SMS-read integration exists" for Coconala/Apple SMS OTP
delivered to Dais's real registered phone. That conclusion was wrong. This Mac has
Text Message Forwarding enabled from Dais's iPhone -> SMS codes land in
~/Library/Messages/chat.db, readable via a small sqlite query. A working helper now
exists: ~/gig/read_sms_otp.py [max_age_seconds] [sender_filter] (queries chat.db,
prints the numeric code from the most recent matching SMS). It successfully read a real
Coconala OTP historically (2026-06-29, "[ココナラ] 認証番号: 348760") — proof the
mechanism works end-to-end when the phone is connected.

Pass 60 refinement: hard precondition discovered

This pass (60) executed the login flow live: native email+password hit the same
invisible-reCAPTCHA failure as pass 59 (unrelated to phone), then Apple ID OAuth
succeeded through password entry and reached the SMS 2FA screen. We selected "send SMS"
twice (incl. an explicit resend), relaunched Messages.app (it was not running), and
tried a blueutil --connect reconnect. No new SMS arrived in chat.db across ~25
minutes (confirmed via MAX(ROWID) staying at 1399 / 2026-06-29T17:19:39Z the whole time).

Root cause found: system_profiler SPBluetoothDataType | grep -A3 'Dais Iphone' showed
"Not Connected" throughout (RSSI -71 to -74, i.e. in range but not Bluetooth-paired).
Text Message Forwarding / Continuity relies on an active Bluetooth link between the
iPhone and Mac, not just Wi-Fi — without it, new SMS never reach chat.db regardless of
how many times a code is (re)sent.

Actionable lesson for future passes

  1. read_sms_otp.py is correct and should be reused — do not re-diagnose "no
    integration" again.
  2. Before attempting any SMS-OTP login flow, check Bluetooth connection state first:
    system_profiler SPBluetoothDataType | grep -A3 'Dais Iphone' must show something
    other than "Not Connected".
  3. If disconnected, this is a transient environmental precondition, not a missing
    capability — retry a few times, but if it stays disconnected after a Messages.app
    relaunch + blueutil reconnect attempt (~20-30 min), treat that pass's login as
    blocked-this-pass-only. Do not touch .last-pass, do not fabricate B1/B2/B3 actions.
    Let the next pass retry fresh since Bluetooth connectivity varies pass to pass.

Logged to ~/gig/lessons.jsonl (pass 60, category=infra, 2 entries) in the
anicca-gig repo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gig-lessonCoconala gig loop lessons

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions