Files
prose-contracts/hermes-zulip-plugin.prose.md
root 1dc4155d9a
PR Pipeline — Authorize → Validate → Review → Merge / auth (push) Successful in 1s
PR Pipeline — Authorize → Validate → Review → Merge / validate (push) Successful in 2s
PR Pipeline — Authorize → Validate → Review → Merge / lint (push) Successful in 3s
PR Pipeline — Authorize → Validate → Review → Merge / ai-review (push) Successful in 2s
PR Pipeline — Authorize → Validate → Review → Merge / gate (push) Successful in 0s
fix(hermes-zulip-plugin): default to master branch, add gateway restart
- Switched default branch from feat/zulip-streaming to master
- Added Step 5: gateway restart with smoke check after plugin install
- Plugin changes require restart to take effect for a valid test
- Outstanding feature branch merges should be addressed post-install
2026-07-08 17:51:19 +00:00

8.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 (master branch). Ensures the agent runs the latest adapter with all Zulip chat fixes (_strip_html, streaming, event recovery). Verifies the installation, restarts the gateway, 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 is focused on the plugin layer and a targeted gateway restart. It does NOT verify env credentials or run a live Zulip connection test. Use hermes-zulip-restore for full connectivity recovery including end-to-end DM validation.

Parameters

Param Type Required Default Description
target string yes Agent name: mumuni, tanko, or koby
branch string no master 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_html fix 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_html function exists in adapter.py (slash-command fix, commit 55ca15d+)
  • 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 httpx installed 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 master (contains all merged fixes including 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: Restart Gateway

Plugin changes require a gateway restart to take effect:

cd {{hermes_home}}/hermes-agent
# Use venv if available
python3 -m hermes_cli.main gateway restart 2>&1 || \
  venv/bin/python -m hermes_cli.main gateway restart 2>&1

Wait for restart to complete (up to 45s), then confirm:

grep "Gateway running" {{hermes_home}}/logs/gateway.log | tail -1

Expected: Gateway running with N platform(s) where N > 1 (includes zulip).

Quick smoke check — confirm zulip platform loaded:

grep -E "zulip.*loaded|zulip.*registered" {{hermes_home}}/logs/gateway.log | tail -3

If gateway fails to restart, check logs for the crash cause before proceeding.

Step 6: 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 7: 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
Gateway restarted `{{yes
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 Full restart + state validation Targeted restart + smoke check
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 — Switched default branch to master; added gateway restart step. If outstanding unmerged feature branches exist, address them in a follow-up merge after this contract completes.