- Added stream_subscription_check, dm_response_time_offline_verifiable, known_issues_tracked postconditions - Added 'Status' section clarifying active for Hermes agents only (not retired with pi Zulip) - Added 'State Persistence' section with KG node schema for build-zulip-plugin:state - Execution step 4: always run offline tests (simulate_dm_latency, selftest) - Execution step 5: update KG state node after each generation
5.8 KiB
kind, name, description
| kind | name | description |
|---|---|---|
| responsibility | build-zulip-plugin | Generates and iteratively improves a Hermes Zulip platform plugin. Each run can produce a new version of the plugin, learning from previous runs and incrementally improving the adapter code. The contract itself can be updated to capture new patterns. |
Maintains
-
plugin_version: string — Current version of the generated plugin
-
generation_count: number — How many generations have been produced
-
last_generation: timestamp — When the last generation was created
-
known_issues: array — Issues discovered in the current version
Postconditions (the plugin is GOOD when ALL pass):
Connectivity
- connected == true — Establishes and maintains Zulip event queue
- reconnect_on_failure == true — Reconnects after queue expiry
- recovers_from_network_loss == true — Handles temporary network drops
- stream_subscription_check == true — Bot is subscribed to primary streams (Gen 5+)
Message Flow
- dm_response_time_ms < 10000 — DMs get a response within 10 seconds
- dm_response_time_offline_verifiable == true — simulate_dm_latency() passes without live Zulip (Gen 6+)
- stream_mention_detection == true — @mentions in streams are detected and routed
- all_bots_detection == true — @all-bots mentions are detected
- echo_loop_prevention == true — Never replies to its own messages
Code Quality
- syntax_check == "pass" — All Python files are valid
- has_register_function == true — Exposes
register(ctx)entry point - plugin_yaml_valid == true — plugin.yaml parses correctly
- follows_base_adapter_pattern == true — Extends BasePlatformAdapter
Reliability
- graceful_disconnect == true — shutdown doesn't crash
- handles_malformed_messages == true — Bad JSON doesn't kill the poll loop
- typing_indicators_work == true — Sends typing notifications
- known_issues_tracked == true — add_known_issue() persists problems across generations (Gen 6+)
Status
Active — for Hermes agents only. This plugin is NOT retired. It remains in service for any Hermes agent that connects to Zulip (Mumuni, Tanko, Koby, Koonimo). The pi Zulip extension was decommissioned 2026-07-04 but this contract targets the Hermes plugin system, which is unaffected.
Parameters
- zulip_site: string — Zulip server URL (default: "https://chat.sysloggh.net")
- bot_email_prefix: string — Prefix for bot emails (default: "abiba-bot")
- output_dir: string — Where to write the plugin (default: "plugins/platforms/zulip")
- generation_goal: string — What to improve this generation (default: "fix bugs and improve reliability")
Continuity
The improvement cycle is event-driven, not just cron-based:
- On check failure: If any postcondition fails, wake immediately to fix
- On user request:
prose run build-zulip-plugin— explicit upgrade - On new pattern: If another plugin or agent reports a better pattern, wake to assimilate
- Retrospective: Every 24 hours if no other trigger fired — scan for subtle degradation
- On first deploy: Always run Generation 1 when no plugin exists yet
Remembers
Each generation stores:
- What worked well (success patterns)
- What broke (failure modes)
- What the user complained about (pain points)
- Which postconditions passed and failed
Generation Rules
Rule 1: First Generation
- Generate complete plugin.yaml, adapter.py, __init__.py
- Follow Hermes BasePlatformAdapter pattern
- Include: connect, disconnect, send, edit_message, send_typing
- Include: DM-first routing, @mention detection, @all-bots support
Rule 2: Subsequent Generations
- Read the previous generation's output and known issues
- Apply improvements based on generation_goal
- Fix any issues from the previous generation
- Add new capabilities if needed
Rule 3: Testing
- After generating, run syntax check on the Python code
- Verify plugin.yaml is valid YAML
- Log the generation result to knowledge graph
Rule 4: Self-Improvement
- After N generations, review the contract itself
- If new patterns emerged, update the Generation Rules
- If old rules are no longer relevant, remove them
Execution
- Read state — Check previous generations from knowledge graph node
build-zulip-plugin:state - Generate or improve — Based on generation count:
- Generation 1: Scaffold full plugin from scratch
- Generation N: Read previous code, apply improvements
- Validate — Syntax check, structure check, dependency check
- Run offline tests — Always run
simulate_dm_latency()and selftest() if no live Zulip - Log — Save generation result to knowledge graph as [LEARN] node. Update the
build-zulip-plugin:statenode with current generation_count, plugin_version, and known_issues. - Report — Output what was generated, what changed, what needs review
State Persistence (Gen 6+)
All generation state is stored in a knowledge graph node titled build-zulip-plugin:state:
generation_count— incremented on each verified runplugin_version— current version stringlast_generation— ISO timestamp of most recent runknown_issues— array of unresolved issues carried forwardlast_postcondition_results— pass/fail map from most recent verification
Agents executing this contract MUST read this node on startup and update it after validation. If the node does not exist, create it with generation_count=1.
Example Output
{
"generation": 1,
"version": "1.0.0",
"files_written": [
"plugins/platforms/zulip/plugin.yaml",
"plugins/platforms/zulip/__init__.py",
"plugins/platforms/zulip/adapter.py"
],
"syntax_check": "pass",
"known_issues": [],
"next_generation_goal": "add streaming responses via placeholder->edit pattern"
}