- hermes-zulip-plugin.prose.md: installs latest zulip-platform plugin from canonical repo, verifies _strip_html fix, sends relay success signal. Distinct from restore — plugin-layer only, no env/gateway/connection checks. - hermes-zulip-restore.prose.md: relocated from /root/ into prose-contracts repo. - Removed duplicate zulip-platform-verification from /root/vault/contracts/.
7.1 KiB
kind, name, description, agent, version, status, runtime_contract
| kind | name | description | agent | version | status | runtime_contract |
|---|---|---|---|---|---|---|
| function | hermes-zulip-plugin | Installs or updates the Zulip platform plugin for any Hermes agent from the canonical zulip-platform-plugins repo. Ensures the agent runs the latest adapter with all Zulip chat fixes (_strip_html, streaming, event recovery). Runs a post-install verification and sends a relay success signal. | abiba | 1.0.0 | active | 2 |
Hermes Zulip Plugin — Install & Repair
Single-shot function that pulls the latest zulip-platform plugin from the canonical git repo, installs it to the correct Hermes bundled plugin path, verifies the installation, and signals completion.
Distinct from hermes-zulip-restore: this contract only touches the plugin
layer. It does NOT verify env credentials, restart the gateway, or validate
the live Zulip connection. Use hermes-zulip-restore for full connectivity
recovery.
Parameters
| Param | Type | Required | Default | Description |
|---|---|---|---|---|
target |
string | yes | — | Agent name: mumuni, tanko, or koby |
branch |
string | no | feat/zulip-streaming |
Git branch to pull (overridable for pinning) |
Maintains
- plugin_installed: bool — Whether all three adapter files exist at the bundled path
- plugin_version: string — Git commit SHA of the installed version
- strip_html_present: bool — Whether
_strip_htmlfix is in the installed adapter - signal_sent: bool — Whether relay success message was dispatched
Postconditions
- All three adapter files (
__init__.py,adapter.py,plugin.yaml) present in<HERMES_HOME>/hermes-agent/plugins/platforms/zulip/ _strip_htmlfunction exists inadapter.py(slash-command fix, commit55ca15d+)- Installed version matches HEAD of the requested branch
- Relay success signal sent to Hermes agent's inbox
Requires
- SSH access to target host (direct or via amdpve for CTs)
- Git repo at
https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git - Python 3 with
httpxinstalled on target
Live-State Fields
| Host | CT | Proxmox | IP (direct) | Hermes Home | User |
|---|---|---|---|---|---|
| Mumuni | CT114 | — | 192.168.68.123 | /root/.hermes | root |
| Tanko | CT112 | amdpve | 192.168.68.122 | /home/jerome/.hermes | jerome |
| Koby | CT111 | amdpve | 192.168.68.129 | /root/.hermes | root |
| Field | Value | Trust |
|---|---|---|
| Git repo | https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git |
✅ Verified |
| Default branch | feat/zulip-streaming |
✅ Verified |
| Bundled adapter path | <HERMES_HOME>/hermes-agent/plugins/platforms/zulip/ |
✅ Verified |
| Adapter files | __init__.py, adapter.py, plugin.yaml |
✅ Verified |
| Strip-html commit | 55ca15d (minimum) |
✅ Verified |
Execution
Step 1: Resolve Target
Map target to host, CT ID, hermes_home, and user from the live-state table.
For CT112 and CT111, route through ssh root@amdpve then pct exec <id>.
Step 2: Pull Latest Plugin Source
On the target host:
# Ensure deploy scratch space
mkdir -p /tmp/zulip-deploy
cd /tmp/zulip-deploy
# Clone or pull
if [ -d zulip-platform-plugins ]; then
cd zulip-platform-plugins
git fetch origin
git checkout {{branch}}
git pull origin {{branch}}
else
git clone --branch {{branch}} \
https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git
cd zulip-platform-plugins
fi
# Capture installed version
INSTALLED_SHA=$(git rev-parse HEAD)
echo "Installed SHA: $INSTALLED_SHA"
# Verify we're at HEAD
HEAD_SHA=$(git rev-parse origin/{{branch}})
if [ "$INSTALLED_SHA" = "$HEAD_SHA" ]; then
echo "At latest commit on {{branch}}"
else
echo "WARNING: not at HEAD — $INSTALLED_SHA vs $HEAD_SHA"
fi
Step 3: Install Plugin Files
# Ensure target directory exists
mkdir -p {{hermes_home}}/hermes-agent/plugins/platforms/zulip
# Copy adapter files
cp plugins/platforms/zulip/adapter.py \
plugins/platforms/zulip/__init__.py \
plugins/platforms/zulip/plugin.yaml \
{{hermes_home}}/hermes-agent/plugins/platforms/zulip/
# Fix ownership (Tanko only — runs as jerome user)
[ "{{target}}" = "tanko" ] && chown -R jerome:jerome \
{{hermes_home}}/hermes-agent/plugins/platforms/zulip/
echo "Plugin files installed"
Step 4: Verify Installation
# Check all three files exist
for f in __init__.py adapter.py plugin.yaml; do
if [ -f "{{hermes_home}}/hermes-agent/plugins/platforms/zulip/$f" ]; then
echo "✅ $f present"
else
echo "❌ $f MISSING"
exit 1
fi
done
# Verify _strip_html fix
grep -q "_strip_html" {{hermes_home}}/hermes-agent/plugins/platforms/zulip/adapter.py \
&& echo "✅ _strip_html fix present" \
|| echo "❌ _strip_html MISSING — plugin may be stale"
# Show installed plugin.yaml version
grep "^version:" {{hermes_home}}/hermes-agent/plugins/platforms/zulip/plugin.yaml || true
Step 5: Send Relay Success Signal
On the Abiba host (local), dispatch a relay message to the target agent:
ra-h-os-createRelayNode:
title: "Zulip plugin updated — {{target}}"
source: |
Plugin installed from {{branch}} @ {{INSTALLED_SHA}}
All 3 adapter files verified at {{hermes_home}}/hermes-agent/plugins/platforms/zulip/
_strip_html fix: PRESENT
Timestamp: {{timestamp}}
description: "hermes-zulip-plugin completed for {{target}} — plugin layer healthy"
Step 6: Report
Compile results into a single status block:
| Field | Value |
|---|---|
| Target | {{target}} |
| Branch | {{branch}} |
| Commit SHA | {{INSTALLED_SHA}} |
| Files installed | __init__.py, adapter.py, plugin.yaml |
_strip_html |
`{{present |
| Signal sent | `{{yes |
Known Failure Modes
| Symptom | Root Cause | Recovery |
|---|---|---|
| Git clone fails | No network or repo unreachable | Check VPN/network, verify repo URL |
| Permission denied on copy | Wrong user for target | Use correct user (jerome for Tanko, root for others) |
_strip_html missing after install |
Branch doesn't include commit 55ca15d |
Switch to feat/zulip-streaming branch |
| Plugin files missing after copy | Target directory doesn't exist | Ensure mkdir -p ran successfully |
| Relay signal fails | MCP bridge unreachable | Signal manually via ra-h-os-createRelayNode |
Edge Differences from hermes-zulip-restore
| Concern | hermes-zulip-restore | hermes-zulip-plugin |
|---|---|---|
| Env credential check | ✅ Full ZULIP_* verification | ❌ Out of scope |
| Gateway restart | ✅ Restarts the gateway process | ❌ Out of scope |
| Live connection test | ✅ Validates zulip.state = connected |
❌ Out of scope |
| Plugin deploy | ✅ Includes deploy as one step | ✅ Primary purpose |
| Version tracking | ❌ Implicit | ✅ Explicit SHA capture |
| Signal dispatch | ❌ None | ✅ Relay message to target |
For full connectivity recovery after a plugin install, chain this contract
with hermes-zulip-restore (skip its Step 2 to avoid redundant deploy).
Last updated: 2026-07-08 — Created to separate plugin lifecycle from restore workflow.