--- name: operator-monitor-debug description: Use when the operator monitoring pipeline appears broken: EventBus has no events, PatternDetector is not firing, elicitation dialog never appears, or OperatorMonitor is silent. Guides systematic diagnosis of the full pipeline. --- # Debugging the Operator Monitor Pipeline ## Checklist ### 1. Is the remote runner running and reachable? ```bash curl http://:8787/health # Expected: {"ok": true, "uptime_s": N} ``` ### 2. Is OperatorMonitor running? `OperatorMonitor` auto-starts when a runner is configured (`runner-map.json` has at least one entry) **OR** when `EMERGE_OPERATOR_MONITOR=1` is set in the daemon environment. Check which condition applies: ```bash python3 "${CLAUDE_PLUGIN_ROOT}/scripts/repl_admin.py" runner-status --pretty # If runners are listed → OperatorMonitor should have auto-started. # If no runners are listed and EMERGE_OPERATOR_MONITOR=1 is absent → it won't start. ``` ### 3. Are events reaching the EventBus? ```bash # On the runner machine (or via icc_exec targeting that profile): cat ~/.emerge/operator-events//events.jsonl | tail -20 ``` If the file is empty or missing: the event producer is not firing events. - Check that the relevant producer path is active (`POST /operator-event`, pipeline `start()` hook with `event_bus.emit_event`, or `_write_operator_event` from `icc_exec`) - On macOS, verify the process has Accessibility permission (`System Preferences → Privacy → Accessibility`) - On Windows, check that the process has UIAutomation access and is not running in a low-integrity context ### 4. Is PatternDetector seeing the events? Replay events manually via `icc_exec`: ```python import json from pathlib import Path from scripts.pattern_detector import PatternDetector events_path = Path.home() / ".emerge/operator-events//events.jsonl" events = [json.loads(l) for l in events_path.read_text().splitlines() if l.strip()] summaries = PatternDetector().ingest(events[-50:]) print(f"Summaries: {summaries}") ``` If `summaries` is empty but events exist: thresholds not met yet. - Frequency detector fires at ≥3 same-type events in a 20-minute window - Check that `session_role` is `"operator"`, not `"monitor_sub"` — monitor_sub events are filtered ### 5. Is OperatorMonitor polling? Set `EMERGE_MONITOR_POLL_S=5` to ensure polling is active. Check `EMERGE_MONITOR_MACHINES` matches the profile names configured in the runner map. ### 6. Is the pattern observation reaching CC? Pattern observations are delivered via `watch_emerge.py --runner-profile ` (Monitor tool, persistent). When a pattern fires, `DaemonHTTPServer._on_runner_event` writes a `pattern_observed` entry directly to `events-{profile}.jsonl`. The Monitor script tails this file and prints formatted observations to stdout; CC streams stdout into the conversation. Check: 1. Is `watch_emerge.py --runner-profile ` running as a persistent Monitor? (launched by `/emerge:cockpit` step 4 via `watch_emerge.py --runner-profile`) 2. Does `~/.emerge/state/events/events-{profile}.jsonl` contain recent `pattern_observed` entries? ```bash grep '"type": "pattern_observed"' ~/.emerge/state/events/events-.jsonl | tail -5 ``` 3. If entries exist but CC didn't see them: the Monitor may have stopped — restart it. ### 7. Common fixes | Symptom | Fix | |---------|-----| | EventBus empty | Verify event producer path (`/operator-event`, pipeline `start()`, or `icc_exec`) and OS accessibility permissions | | PatternDetector never fires | Lower `FREQ_THRESHOLD` or check event `session_role` field | | Elicitation never appears | Verify daemon has elicitation capability in MCP handshake; check thread is non-main | | Pattern observation not delivered | Verify `watch_emerge.py --runner-profile

` Monitor is running; check `events-{profile}.jsonl` for `pattern_observed` entries | | OperatorMonitor not starting | Confirm runner is configured (`runner-status --pretty`) OR `EMERGE_OPERATOR_MONITOR=1` in daemon env |