Skip to content

Wire ntfy push notifications for captain-input escalations (laptop/phone) #3

Description

@Quidge

Problem

Firstmate runs terminal-first — SSH/tmux from a MacBook and from Termux on a phone, over tailscale. Unlike the Claude apps, there's no built-in push when firstmate needs the captain, so the captain has to watch the terminal to catch decisions, review-ready PRs, blockers, and credential prompts. We want push notifications to the captain's laptop and phone when firstmate escalates.

Goal

When firstmate reaches a "must reach the captain" point (see AGENTS.md section 9), fire a push notification to the captain's devices via ntfy (has Android, iOS, web, and desktop clients), so they can respond from wherever they are.

When to notify (the escalation set — section 9; NOT routine progress)

Notify on:

  • Work ready for review, with the PR URL.
  • Finished investigation findings.
  • A gate/decision that needs the captain's call.
  • A real blocker or failure after the relevant playbook is exhausted.
  • Anything destructive, irreversible, or security-sensitive.
  • A needed credential or login.

Explicitly do NOT notify on routine progress, empty polls, automatic fixes/retries, or no-change heartbeats — notification fatigue would kill the signal. This mirrors section 9's "reach immediately" vs "do not surface" split.

Proposed shape (design, not final)

  • A small bin/fm-notify.sh "<title>" "<body>" [--url <link>] helper that publishes to ntfy, fired at escalation points. shellcheck-clean per repo rules.
  • Config is LOCAL and gitignored (never committed), following the config/ + .env convention: ntfy server URL, topic, and any auth token. Presence-gated — absent config means the feature is inert (same pattern as X mode).
  • Integration: firstmate (the agent) calls it when it escalates; optionally the supervision watcher / away-mode daemon fires it for wake events that need attention. Compose with the existing away-mode wedge-alarm (config/wedge-alarm, docs/wedge-alarm.md) rather than duplicating it — ntfy is the cross-device/remote backend that macOS Notification Center can't reach on the phone.

Security / privacy (load-bearing, given the secret-free contract)

ntfy.sh public topics are obscure, not private — anyone who knows the topic name can read it. So decide a posture before shipping:

  • (a) self-host ntfy on the box, reachable over tailscale, or
  • (b) use an access-token-protected topic, or
  • (c) keep notification bodies minimal ("Firstmate needs your input — check the terminal") with no sensitive detail, and keep specifics in the terminal only.

Do not publish PR titles, decision text, or repo details to a public topic. Any token/topic secret stays in local gitignored config, never in the repo.

Acceptance criteria

  • Gitignored local config for ntfy (server, topic, optional token); absent = feature off.
  • bin/fm-notify.sh publishes a notification (title, body, optional click-through URL) to the configured target; shellcheck-clean; fails closed if config is absent.
  • Firstmate fires it on the section-9 escalation cases, and never on routine progress.
  • Privacy posture chosen and documented (self-hosted / token / minimal-body).
  • Verified reaching the captain's MacBook and Termux/phone from this box.
  • Short setup note (subscribe on the ntfy client, set local config) in the audience-classified doc surface.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions