feat: add phone-first read-only fleet bridge - #84
Merged
Conversation
Give Bearings a named passive-view mode and in-flight titles, then serve a loopback Tailscale Serve glance so the phone can observe the fleet without approving work or mixing logins with the glasses mailbox. Co-authored-by: Cursor <cursoragent@cursor.com>
Point the new capability at the branch commit that added it so the pre-merge provenance line resolves to this change rather than an unrelated parent. Co-authored-by: Cursor <cursoragent@cursor.com>
A claimed Serve HTTPS proxy reports https:// in funnel status, which blocked the loopback server. Keep refusing when Funnel is actually on. Co-authored-by: Cursor <cursoragent@cursor.com>
KeepAlive would otherwise miss Homebrew python3 and never bind loopback. Co-authored-by: Cursor <cursoragent@cursor.com>
Three new title and away-mode cases landed; the macOS snapshot count was still 42. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Ship slice 1 of the captain's phone-first read-only fleet page (Starship bridge view), exactly as specified in the accepted scout report. Do not reopen the closed forks: passcode not accounts, Tailscale Serve never Funnel never 0.0.0.0, read-only with no tap-to-act.
Required deliverables:
Accepted later constraints that remain in force:
What Changed
Risk Assessment
✅ Low: The three prior issues are resolved with explicit Funnel markers, complete in-flight projection before bucket capping, and cross-process atomic session-store serialization; no additional material defects were found.
Testing
All dedicated bridge, 45-case Bearings, and home-port suites passed; end-to-end checks covered Funnel/Serve handling, loopback and unauthorized access, authentication and session expiry/revocation, secure cookie isolation, security headers, passive away-mode observation, read-only snapshot confinement, mailbox behavior, and the rendered mobile login and four-bucket fleet experience.
/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/no-mistakes-evidence/01M0CPDNKE0R95ZRH81HP76GED/bridge-login-mobile.png)/var/folders/1g/hctp3vpn27b1zrlsn4nsfg680000gn/T/no-mistakes-evidence/01M0CPDNKE0R95ZRH81HP76GED/bridge-authenticated-mobile.png)Evidence: Interactive login surface
Evidence: Interactive authenticated fleet surface
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 3 issues found → auto-fixed ✅
bin/fm-bridge-view.py:443- The required constraint says “do not treat a claimed Serve config as Funnel merely because funnel status prints https://,” but this fallback returns Funnel-on for any successful status containinghttps://. If JSON status is unavailable or unsupported, a valid tailnet-only Serve configuration without the literal words “tailnet only” is incorrectly refused. Classify Funnel only from explicit Funnel evidence while continuing to fail closed on genuinely unverifiable output.bin/fm-bridge-view.py:340- The required “caps with honest N more” contract is not met when Bearings truncates in-flight rows.extra_in_flightis assigned entirely to Under way, although omitted rows may be blocked, parked, or paused and therefore belong in Needs you or Waiting. Fetch all in-flight rows for the bounded subprocess projection, or expose per-state omitted counts before displaying bucket totals.bin/fm-bridge-view.py:974- Session revocation races with the running server because the CLI and server use separate process-local locks around non-atomic read/modify/write operations. An in-flight login can load sessions,revoke-sessionscan write an empty store, and that login can then save its stale copy plus a valid new session, defeating the lost-phone revoke guarantee. Use cross-process serialization and atomic replacement for session updates.🔧 Fix: Fix bridge view review findings
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-bridge-view.test.shbash tests/fm-bearings-snapshot.test.shbash tests/fm-home-port.test.shRenderedlogin_html()andglance_html()frombin/fm-bridge-view.pywith a representative four-bucket observation, then inspected both at a 390×844 phone viewport usingchrome-devtools-axi.Captured 390×844 PNG evidence with headless Chrome and visually inspected both screenshots.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.