Skip to content

Build the Signal (signal-cli) transport into Simard as a supervised dependency (no hand-created systemd unit) #5015

Description

@rysweet

Summary

Simard's Signal channel currently depends on a hand-created, host-specific systemd unit to run the signal-cli JSON-RPC daemon out-of-band. This is manual setup that must be recreated on every host and is not part of Simard itself. Simard should build in management/supervision of the signal-cli daemon so a fresh install brings the Signal channel up with no manual systemd surgery.

Current state (the problem)

During the ia2 → deva3 migration, the Signal channel only worked after manually:

  1. Installing signal-cli 0.14.5 (which needs Java 25) at /opt/signal-cli-0.14.5/.
  2. Hand-authoring a user systemd unit ~/.config/systemd/user/signal-cli.service that runs:
    signal-cli -a <account> daemon --tcp 127.0.0.1:7583
  3. Enabling linger + starting that unit separately from simard-ooda.

Simard's daemon then connects to 127.0.0.1:7583 as a JSON-RPC client. If that separate unit is missing or down, Simard's Signal send/receive silently fails (Connection refused) with no self-recovery.

This is fragile:

  • Not reproducible: nothing in the Simard install creates or supervises the signal-cli daemon; it is tribal per-host knowledge.
  • No lifecycle coupling: simard-ooda does not know whether its Signal transport is up; the two units are independent.
  • No self-healing: if signal-cli dies, Simard does not restart it or surface the outage as a health signal.
  • Host-specific paths/versions (/opt/signal-cli-0.14.5, Java 25) are baked into a manual unit, not managed by Simard.

Desired outcome

Signal transport is a built-in, supervised dependency of Simard, provisioned and lifecycle-managed by Simard itself. Concretely:

  • Simard's install/setup provisions the signal-cli daemon (or an equivalent transport) — no hand-authored systemd unit required.
  • Simard supervises the transport: starts it, monitors liveness on the JSON-RPC endpoint, restarts on failure, and surfaces a Signal-transport-down condition to its health/observability path instead of silently failing.
  • Transport endpoint/account/version are Simard configuration (e.g. in config.toml), not a separate hand-written unit.
  • A fresh host install brings the Signal channel up end-to-end with no manual steps beyond the one-time device link (QR approval).

Acceptance criteria

  • A clean Simard install on a new host establishes a working Signal channel with no manually-created signal-cli.service.
  • Simard detects and recovers from a signal-cli daemon outage (restart + health surfacing), rather than silently dropping sends.
  • signal-cli account, endpoint, and binary/version are driven by Simard config, not an out-of-band unit.
  • The one-time device-link (QR) flow is documented and is the only manual step.

Context / evidence

  • Manual unit created during migration: deva3 ~/.config/systemd/user/signal-cli.servicesignal-cli -a +12062591306 daemon --tcp 127.0.0.1:7583.
  • Simard connects as a JSON-RPC client over TCP 7583 (send method → {"type":"SUCCESS"}).
  • signal-cli 0.14.5 requires Java 25 (class file 69) — a version dependency currently pinned only inside the hand-written unit.
  • Related config: SIMARD_SIGNAL_RPC_ACCOUNT / SIMARD_SIGNAL_RPC_RECIPIENT env in the simard-ooda unit; [signal] block in config.toml.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions