Files
Kao/SPEC.md
Spencer a074a42d40 Bump to v2.0.0: daily emote rotation + expanded sound library
- Emote face is now stable all day; /wake picks a fresh random face each
  morning instead of rotating every 5 minutes. Removes EMOTE_ROTATION_INTERVAL
  and last_emote_change entirely.
- Added 10 new synthesized sounds for /notify: doorbell, knock, ding, blip,
  siren, tada, ping, bubble, fanfare, and alarm (loops until tapped or TTL
  expires). stopAlarm() wired into tap handler and handleStateChange().
- openapi.yaml: new sound names added to enum.
- CLAUDE.md / README.md updated to reflect both changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-20 16:36:23 -06:00

3.3 KiB

SPEC.md: Project "Sentry-Emote"

1. Overview

Purpose: Repurpose an old Pixel phone (OLED screen) as an ambient, glanceable system status monitor for a home server. Design Philosophy: Minimalist, binary-state, and high-signal. Use an "Emote" (ASCII/Emoji) to represent system health instead of complex graphs. Target Device: Android Pixel (accessed via Fully Kiosk Browser).

2. System Architecture

The system follows a decoupled Publisher/Subscriber model to ensure extensibility.

  • Aggregator (The Broker): A central Python service running on the server. It manages the event queue and generates the state.
  • Detectors (The Publishers): Independent scripts (Python, Bash, etc.) that monitor specific system metrics and "hook" into the Aggregator.
  • Emote-UI (The Subscriber): A mobile-optimized web frontend that displays the current highest-priority emote.

3. Data Specification

3.1 status.json (State Registry)

The Aggregator outputs this file every time the state changes.

{
	"current_state": "optimal",
	"active_emote": "( ^_^)",
	"color": "#00FF00",
	"animation": "breathing",
	"message": "All systems nominal",
	"active_events": [
		{
			"id": "disk_check",
			"priority": 4,
			"message": "Disk 40% full"
		}
	],
	"last_updated": "2026-02-02T17:30:00"
}

3.2 Priority Hierarchy

Level Name Priority Emote Color Logic
1 Critical Emergency ( x_x) Red Overrules all. Manual clear required.
2 Warning Caution ( o_o) Yellow Overrules Optimal. Auto-clears if fixed.
3 Notify Event ( 'o') Blue Transient. TTL (Time To Live) of 10s.
4 Optimal Default ( ^_^) Green Active when no other events exist.

4. Component Requirements

4.1 Aggregator (aggregator.py)

  • Event Bus: Accept HTTP POST requests or watch a specific file/directory for new event signals.
  • State Management: Maintain a list of "Active Events."
  • TTL Logic: Automatically remove Priority 3 events after 10 seconds.
  • Deduplication: If multiple events exist, always select the one with the lowest priority number for the active_emote field.

4.2 Emote-UI (index.html)

  • OLED Optimization: Pure black background (#000000).

  • Glanceability: Massive centered text for the emote.

  • Animations: - breathing: Slow opacity/scale pulse.

  • shaking: Rapid X-axis jitter for Critical.

  • popping: Scale-up effect for Notifications.

  • Refresh: Long-polling or setInterval every 2 seconds.

4.3 Extensibility (The Hook System)

  • New detectors must be able to send an event to the Aggregator without modifying the core code.
  • Example Detector Hook: curl -X POST -d '{"id":"ssh","priority":1}' http://localhost:5000/event

5. Implementation Roadmap

  1. Phase 1: Build the aggregator.py with basic JSON output.
  2. Phase 2: Build the OLED-friendly index.html frontend.
  3. Phase 3: Create the first "Detector" (e.g., a simple disk space checker).
  4. Phase 4: Implement TTL for transient notifications.