--- kind: contract name: zulip-platform-verification version: 1.0.0 description: > Cross-platform Zulip agent verification contract. Validates both pi (TypeScript extension) and Hermes (Python BasePlatformAdapter) plugins can connect to Zulip, receive DMs, filter own messages, resolve @all-bots, and relay LLM responses. Designed to run on schedule (daily) or on-demand by any Syslog agent. author: Abiba (pi agent) --- # Zulip Platform Verification Contract ## Platforms Under Contract | Platform | Agent | Bot Email | Plugin Path | Health Port | |----------|-------|-----------|-------------|-------------| | pi | Abiba | abiba-bot@chat.sysloggh.net | `~/.pi/agent/extensions/zulip/` | :9200 | | Hermes | Tanko | tanko-bot@chat.sysloggh.net | `~/.hermes/plugins/platforms/zulip/` | :9201 | | Hermes | Mumuni | mumuni-bot@chat.sysloggh.net | `~/.hermes/plugins/platforms/zulip/` | :9202 | | Hermes | Koonimo | koonimo-bot@chat.sysloggh.net | `~/.hermes/plugins/platforms/zulip/` | :9203 | | Hermes | Koby | koby-bot@chat.sysloggh.net | `~/.hermes/plugins/platforms/zulip/` | :9204 | ## Parameters - zulip_site: string — Zulip server URL (default: "https://chat.sysloggh.net") - agents: array — List of agent configs to verify (default: all) - test_message: string — Content to send in loopback DM (default: "🔬 Contract self-test") ## Checks (per agent) ### Check 1: Health Endpoint - GET {{health_port}}/health → expect 200, `{ status: "ok", connected: true }` ### Check 2: Queue Registered - Health response must include `queue_id` (non-null string) ### Check 3: Bot Identity Resolved - Health response must include `bot_user_id` (positive integer, not null) ### Check 4: @all-bots Resolved - Health response must include `all_bots_user_id` (positive integer, not null) - Must match the actual Zulip @all-bots user (resolve from `/api/v1/users`) ### Check 5: Poll Loop Active - `idle_seconds` < 300 (5 min) OR `stuck` = false - `silence_seconds` < 600 (10 min) for Hermes adapter ### Check 6: Event Reception (Loopback) - Send test DM via Zulip API from external account - Verify `idle_seconds` resets to <10s within 5s of DM - OR verify `messages_processed` increments (for external-source DMs) ### Check 7: Self-Test (if available) - Hermes: POST to adapter's `selftest()` method → expect verdict "healthy" - pi: Run `/zulip-test` command via RPC → expect "All checks passed" ### Check 8: Echo-Loop Prevention - Health endpoint must include mechanism to identify bot email - Own-sent messages must not trigger processing ## Returns ```json { "verdict": "healthy" | "degraded" | "critical", "timestamp": "ISO-8601", "agents": { "abiba": { "platform": "pi", "verdict": "healthy", "checks": { ... }, "details": { ... } }, "tanko": { "platform": "hermes", "verdict": "degraded", "checks": { ... }, "details": { ... } } }, "summary": { "total": 5, "healthy": 4, "degraded": 1, "critical": 0 } } ``` ## Ensures - Each agent is independently verified; one failure doesn't block others - @all-bots user_id is cross-validated against Zulip API (catches config drift) - Report is saved to vault at `/root/vault/contract-reports/zulip-verification-{date}.md` - Alert sent to owner if any agent is critical or >2 are degraded - Contract is self-documenting — results include raw health snapshots