Skip to content

feat(familiars): Add pluggable OS-level notification system#37

Open
Rynaro wants to merge 2 commits intomainfrom
feature/familiars-notification-system
Open

feat(familiars): Add pluggable OS-level notification system#37
Rynaro wants to merge 2 commits intomainfrom
feature/familiars-notification-system

Conversation

@Rynaro
Copy link
Copy Markdown
Owner

@Rynaro Rynaro commented Mar 18, 2026

Implement Familiars — a pluggable notification subsystem enabling the agent to send OS-level notifications via ntfy.sh (HTTP pub-sub) without mounting D-Bus or X11 sockets. Supports cross-platform PWA + mobile app delivery while maintaining full container isolation.

Core Components

  • Familiars::Channel (abstract base class) + Registry (channel management)
  • Familiars::Dispatcher (fan-out with per-channel error isolation)
  • Familiars::Channels::Log (always-on, SemanticLogger integration)
  • Familiars::Channels::Ntfy (HTTP POST, Bearer auth, priority mapping)
  • Tools::SendNotification (elevated, agent-callable, requires confirmation)

Integration Points

  • All 3 interfaces (CLI, TUI, Telegram): /familiars commands (status, test)
  • Agent loop: auto-triggers on session_complete, confirmation_needed, error
  • Config: [familiars] + [familiars.ntfy] sections with env var overrides
  • Docker: ntfy sidecar service with --with-ntfy profile

Security & Architecture

  • Zero D-Bus/X11 mounting (full container isolation)
  • Auth-hardened ntfy config (deny-all default, per-topic tokens)
  • Tokens in .env only (never hardcoded in config)
  • Non-blocking (failures logged, never block agent loop)
  • Graceful degradation (unreachable ntfy → logged, continues)

Testing & Coverage

  • 1314 examples, 0 failures, 80.15% overall coverage
  • All HTTP stubbed via WebMock (no real network in tests)
  • Error isolation verified (one channel fails, others deliver)
  • Priority mapping tested (:low→2, :normal→3, :high→5)
  • Auth headers tested, graceful degradation tested

Files

New (13):

  • lib/homunculus/familiars/* (5 files: channel, registry, dispatcher, 2 channels)
  • lib/homunculus/tools/send_notification.rb
  • lib/homunculus/interfaces/familiars_setup.rb
  • lib/homunculus/interfaces/telegram/familiars_integration.rb
  • config/ntfy/server.yml
  • spec/familiars/* + spec/tools/send_notification_spec.rb
  • plans/2026-03-18-familiars-notification-system.md

Modified (11):

  • config/boot.rb: +send_notification, +5 Familiars module requires
  • config/default.toml: +[familiars] section
  • lib/homunculus/config.rb: FamiliarsConfig structs + ntfy env var overrides
  • docker-compose.yml: +ntfy service (profile ntfy), +ntfy-egress network
  • All 3 interfaces: Familiars init + /familiars commands
  • lib/homunculus/agent/loop.rb: event notifications
  • CLAUDE.md: architecture, tool count 19→20, Risk Gate
  • .rubocop.yml: telegram.rb added to ClassLength exclusion
  • spec/spec_helper.rb: Familiars spec requires

Usage

Enable in .env:
FAMILIARS_ENABLED=true FAMILIARS_NTFY_ENABLED=true FAMILIARS_NTFY_TOKEN=

Start: bin/assistant up --with-ntfy

Test: bin/assistant cli → familiars status / familiars test

Subscribe: http://localhost:2586 → add topic homunculus

Status

Disabled by default. Production-ready with security-first auth model. Log channel always works (fallback). ntfy channel requires token setup.

Rynaro and others added 2 commits March 18, 2026 20:25
Implement Familiars — a pluggable notification subsystem enabling the
agent to send OS-level notifications via ntfy.sh (HTTP pub-sub) without
mounting D-Bus or X11 sockets. Supports cross-platform PWA + mobile app
delivery while maintaining full container isolation.

## Core Components

- Familiars::Channel (abstract base class) + Registry (channel management)
- Familiars::Dispatcher (fan-out with per-channel error isolation)
- Familiars::Channels::Log (always-on, SemanticLogger integration)
- Familiars::Channels::Ntfy (HTTP POST, Bearer auth, priority mapping)
- Tools::SendNotification (elevated, agent-callable, requires confirmation)

## Integration Points

- All 3 interfaces (CLI, TUI, Telegram): /familiars commands (status, test)
- Agent loop: auto-triggers on session_complete, confirmation_needed, error
- Config: [familiars] + [familiars.ntfy] sections with env var overrides
- Docker: ntfy sidecar service with --with-ntfy profile

## Security & Architecture

- Zero D-Bus/X11 mounting (full container isolation)
- Auth-hardened ntfy config (deny-all default, per-topic tokens)
- Tokens in .env only (never hardcoded in config)
- Non-blocking (failures logged, never block agent loop)
- Graceful degradation (unreachable ntfy → logged, continues)

## Testing & Coverage

- 1314 examples, 0 failures, 80.15% overall coverage
- All HTTP stubbed via WebMock (no real network in tests)
- Error isolation verified (one channel fails, others deliver)
- Priority mapping tested (:low→2, :normal→3, :high→5)
- Auth headers tested, graceful degradation tested

## Files

New (13):
- lib/homunculus/familiars/* (5 files: channel, registry, dispatcher, 2 channels)
- lib/homunculus/tools/send_notification.rb
- lib/homunculus/interfaces/familiars_setup.rb
- lib/homunculus/interfaces/telegram/familiars_integration.rb
- config/ntfy/server.yml
- spec/familiars/* + spec/tools/send_notification_spec.rb
- plans/2026-03-18-familiars-notification-system.md

Modified (11):
- config/boot.rb: +send_notification, +5 Familiars module requires
- config/default.toml: +[familiars] section
- lib/homunculus/config.rb: FamiliarsConfig structs + ntfy env var overrides
- docker-compose.yml: +ntfy service (profile ntfy), +ntfy-egress network
- All 3 interfaces: Familiars init + /familiars commands
- lib/homunculus/agent/loop.rb: event notifications
- CLAUDE.md: architecture, tool count 19→20, Risk Gate
- .rubocop.yml: telegram.rb added to ClassLength exclusion
- spec/spec_helper.rb: Familiars spec requires

## Usage

Enable in .env:
  FAMILIARS_ENABLED=true
  FAMILIARS_NTFY_ENABLED=true
  FAMILIARS_NTFY_TOKEN=<secret>

Start: bin/assistant up --with-ntfy

Test: bin/assistant cli → familiars status / familiars test

Subscribe: http://localhost:2586 → add topic homunculus

## Status

Disabled by default. Production-ready with security-first auth model.
Log channel always works (fallback). ntfy channel requires token setup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…otification-system

Merge the complete TUI redesign (EventLoop, ActivityIndicator, enhanced message rendering) with the OS-level notification system. Resolves conflicts in config, session management, and test specs.

- TUI: EventLoop-based event handling, ActivityIndicator for progress
- TUI: Enhanced markdown/code block rendering
- Config: Integrated familiars notification configuration
- Tests: Updated specs for merged architecture

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant