69 Commits
Author SHA1 Message Date
mumuni-bot 4f5954a5ac Merge pull request 'fix: reconcile main with master-only security/truncate fixes; repair never-running CI' (#35) from fix/main-security-and-truncate into main
CI / validate (push) Successful in 10s
2026-09-25 19:47:40 +00:00
Mumuni 52c41ca8fb fix(ci): install python3 via apk — act job container is alpine, not debian
CI / validate (pull_request) Successful in 14s
Run 467 log (job 1985): 'python3 missing — installing on alpine' then
'apt-get: command not found' → exit 127. The act_runner container is
node:20-alpine-ish; the provisioning step now detects apk first, apt
second, and fails loudly with a diagnostic if neither exists.
2026-09-25 19:39:36 +00:00
MumuniandClaude Opus 5 f477a6a252 fix(ci): install python3+PyYAML in the job when the runner image lacks them
CI / validate (pull_request) Failing after 5s
Runner probe on PR #35 (run 461, log job 1979): checkout@v4 succeeds (network
fine) but the act container has node:20 + git 2.52 and NO python3 — 'python3
--version' exited 127, which was the failing check. Every validation step is
python3-based, so make step 2 self-provisioning via apt when missing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-25 19:20:23 +00:00
Mumuni 9edc258245 fix(ci): make the validate job actually able to run — it never had
CI / validate (pull_request) Failing after 14s
ci.yml has been invalid YAML since introduction: the 'Config validation'
and old inline checks dedented out of their run:| block scalar, so Gitea
could never parse the workflow — CI never ran on any PR despite
CI_STATUS.md claiming 'Active'. The old 'No secrets check' also always
passed (|| echo swallows the grep hit) and never scanned *.yml — where
six embedded credentials were living.

- validation logic moved to ci_check.py (testable locally: python3 ci_check.py all)
- secrets check now FAILS on embedded http-basic URLs and long api_keys,
  across .py/.ts/.yaml/.yml/.cjs/.sh, with placeholder allowlist
- added workflow-YAML parse gate so this class of breakage can't recur
- py_compile steps no longer swallow errors with '|| echo skipped'
- removed ci.yml's duplicate deploy job: deploy.yml is the sole deploy
  pipeline (rc tags → Tanko canary only; stable → all agents). The ci.yml
  copy would have deployed Mumuni on rc tags too, breaking canary policy,
  and never ran anyway.
- CI_STATUS.md rewritten with the real state + caveats (history still
  contains the old creds — rotation is a server-side task)
2026-09-25 15:50:16 +00:00
Mumuni fb752be8c9 fix(zulip): @all-bots fallback default was user_id=1 — never valid in SyslogGH realm
Dynamic resolution (ADR-006) overrides this on connect, but when the
/api/v1/users call fails the adapter fell back to 1, silently dropping
every @all-bots mention. The realm's all-bots user is 20 (verified
2026-09-25: 'Resolved @all-bots user_id=20 from all-bots@chat.sysloggh.net';
CONTRACT_VERIFICATION_2026-06-29 fixed the Pi config to 20 for the same
reason). Align the Hermes-side fallback with the verified realm value.
2026-09-25 15:31:28 +00:00
Mumuni f0f82d904b security: remove hardcoded abiba-bot credentials from deploy workflow
Completes aeb79c6 (main): four more clone steps in deploy.yml still
embedded abiba-bot HTTP Basic credentials in plaintext. Runner already
auto-checkouts the repo, so the manual clone was redundant — replaced
with actions/checkout@v4, same pattern as ci.yml.

No secrets remain in tracked workflow files after this change.
2026-09-25 15:28:58 +00:00
Abiba (pi) 2c4136daf8 fix(zulip): account for TRUNCATION_NOTICE overhead in _truncate
The truncation notice '[...truncated at Zulip limit]' was appended AFTER
slicing at MAX_ZULIP_MESSAGE (10000), causing the final message to exceed
Zulip's API limit. This fix subtracts the notice length from the slice so
the total stays within bounds.

(cherry picked from commit 19c52a9425)
2026-09-25 15:25:54 +00:00
Abiba (pi) 3db0d74620 security: remove hardcoded abiba-bot credentials from CI workflow
Replaced manual 'git clone' with password in URL with actions/checkout@v4.
Runner already auto-checkouts the repo - manual clone was redundant.
Also fixed YAML syntax issues in Config validation and No secrets check steps.
Credentials were exposed in git history since initial commit.

(cherry picked from commit aeb79c6286)
2026-09-25 15:25:54 +00:00
abiba-bot 9f72da5b8d Merge pull request 'feat: Zulip Gateway v3 — Production Resilience Rewrite' (#34) from feat/zulip-v3-resilience into main 2026-07-15 16:09:55 +00:00
Abiba (pi) 33453b8204 feat(zulip): v3 resilience rewrite — circuit breaker, retry, watchdog, model fix
Root cause: Workers hung because default model was DeepSeek v4-pro (reasoning
model that produces empty content with normal token limits). pi RPC workers
waited forever for content that never arrived.

Changes:
- Circuit breaker (CLOSED→OPEN→HALF_OPEN) around Zulip API calls
- Retry with exponential backoff + jitter for transient errors
- Queue lifecycle management (idle_queue_timeout, auto re-register on BAD_EVENT_QUEUE_ID)
- External supervisor watchdog (restarts router after 3 health check failures)
- Busy worker timeout (SIGKILL after 5 min + error DM)
- PM2 hardening (max_restarts=100, max_memory_restart=500M)
- Crash handlers (uncaughtException + unhandledRejection → reconnect, not die)
- Fixed default model: deepseek-v4-pro → syslog-harness/syslog-auto
- Enhanced health endpoint with circuit breaker stats

Architecture: Research-backed from Zulip event system docs + Node.js resilience
patterns. Inline circuit breaker (no dependency). Separate watchdog process (Hermes pattern).

Verified: Circuit breaker trips on outage, recovers gracefully. End-to-end DM
processed in 4 seconds. Watchdog monitoring every 30s.
2026-07-13 21:29:25 +00:00
abiba-bot 441255a07c feat: add edit_message + streaming support to Zulip adapter (#33) 2026-07-13 06:49:55 +00:00
jerome 5d9e36f657 fix(zulip): add _strip_html for slash command matching
Zulip delivers message content as HTML (<p>/approve</p>).
The gateway slash command parser expects plain text, so HTML
tags prevent command matching. This helper strips HTML tags
and decodes common entities (&amp;, &lt;, etc.).

Per contract: zulip-approval-fix.prose.md

Applied to: Mumuni (CT114), Tanko (CT112), Koby (CT111)
2026-07-13 06:49:43 +00:00
Abiba bfc6e1877d feat: add edit_message + streaming support to Zulip adapter
Implements edit_message() using Zulip's PATCH /api/v1/messages/{id} API.
Enables the Hermes GatewayStreamConsumer to progressively update Zulip
messages during agent generation, giving users real-time visibility into
agent thinking via progressive edits.

Adds _api_patch() helper for PATCH HTTP method.
2026-07-13 06:49:43 +00:00
jerome e1b76376b1 Merge pull request 'test: final CI verification' (#31) from feat/ci-test-final into main
Reviewed-on: #31
2026-07-06 04:05:38 +00:00
abiba-bot aaaa11a912 Merge pull request 'fix: Zulip attachment handling — event attachments + all file types' (#32) from fix/zulip-attachment-handling into main 2026-07-05 16:06:31 +00:00
Abiba b6fa3da540 fix: Zulip attachment handling — event attachments + all file types
hermes-zulip-plugin (Tanko/Mumuni):
  - Add _extract_event_attachments() to handle message.attachments from
    Zulip UI file uploads (previously only inline markdown links worked)
  - Add shared _cache_attachment() method for images/audio/documents
  - Refactor _extract_inline_media() to use _cache_attachment()
  - Fix connect() signature for hermes-agent 0.18.0 compat (add is_reconnect)

pi-zulip-extension (Abiba):
  - Extend attachment handling beyond images only: text files (decoded
    inline), PDFs (pdftotext extraction), binary files (metadata)
  - 50K char cap on text/PDF extraction to prevent context flooding
  - Classify attachments by extension (image/text/pdf/binary)

pi-mcp-extension (Abiba):
  - Detect bridge-side text truncation (… ellipsis marker)
  - Rebuild relay message display from structuredContent when truncated
  - Add rebuildRelayTextFromStructuredContent() helper

Config:
  - Add ZULIP_ROLE=router to ecosystem.abiba.config.cjs (was missing)
2026-07-05 16:03:32 +00:00
Abiba (pi) 40ce413fd8 contract: add host + Health URL columns, use health_url param
- Added Host column (Abiba: 192.168.68.24, Hermes agents: 192.168.68.123)
- Changed Health Port → Health URL with full http://host:port/health URLs
- Updated Check 1 to reference {{health_url}} instead of {{health_port}}
- Added .gitignore for .agents/ (OpenProse run state)
2026-07-02 17:18:40 +00:00
Abiba (pi) 15f94e3bcb feat: Gen 5 improvements — stream subscription check + auto-subscribe
Adds two improvements from pi Zulip extension lessons:

1. _ensure_stream_subscriptions() — checks at connect time if the bot
   is subscribed to the primary stream and general-chat; auto-subscribes
   if missing. Without this, bots with 0 subscriptions can't receive
   stream events (DMs only).

2. selftest check #9 — verifies stream subscriptions and reports
   count + names. Catches the 'zero subscriptions' failure mode that
   was a major debugging bottleneck in the pi extension.
2026-06-29 22:28:21 +00:00
Abiba (pi) 3bb7698f88 fix: clear stale errors on successful poll — prevents phantom error alerts
Same fix as applied to the pi Zulip extension: last_error_msg and
last_error_at are now cleared on every successful poll cycle, not
just on reconnect. Health monitors no longer show stale errors.
2026-06-29 22:22:59 +00:00
Abiba (pi) 0112c5bba7 feat: /zulip-test command + standardized health schema v1
- Added /zulip-test self-test command (7 checks: queue, identity,
  @all-bots, health, poll loop, echo prevention, API send)
- Standardized health endpoint to zulip-health/v1 schema
  (nested zulip{} object, checks{} map, platform/agent metadata)
- Saved pi extension source to pi-zulip-extension/extension-src/
  (with all fixes: dynamic @all-bots, health sync, logging)
- Added extension src to repo for deployment tracking
- Updated vault with final contract status report
2026-06-29 03:45:34 +00:00
Abiba (pi) 1a6098f7fd contract: Zulip extension verification report + cross-platform contract
- Full contract verification for pi (TypeScript) and Hermes (Python) Zulip plugins
- Fixed @all-bots user_id (1→20) — now dynamically resolved from Zulip API
- Fixed last_event_id stale display in health endpoint (B2)
- Fixed display_recipient logging (B3)
- Added bot_user_id and all_bots_user_id to health endpoint
- Created OpenProse cross-platform verification contract (docs/contracts/)
- Created Hermes plugin deployment script (scripts/deploy-hermes-zulip.py)

Pi extension: 8/9 checks pass (LLM relay untested — no external DMs)
Hermes adapter: 9/10 checks pass (deployment pending)
2026-06-29 03:40:52 +00:00
Abiba (pi) 15adb30bc7 fix: raise MAX_CONSECUTIVE_EMPTY_POLLS 20→500 to prevent idle reconnection cycling
Bots with no incoming messages were reconnecting every ~60 seconds
(20 polls × 3s interval). Raised to 500 polls (~25min) so idle bots
don't cycle. Connection recovers immediately on BAD_EVENT_QUEUE_ID
regardless of this counter.
2026-06-28 11:28:57 +00:00
Abiba (pi) faf9566332 test: final CI verification 2026-06-28 00:52:21 +00:00
Abiba (pi) b0aeb81caf chore: add CI status doc 2026-06-28 00:51:44 +00:00
abiba-bot 04f78f3f01 Merge pull request 'ci: simplify workflow + cleanup' (#30) from feat/ci-fix into main 2026-06-28 00:49:55 +00:00
Abiba (pi) 3fbd31fbff chore: cleanup test workflows 2026-06-28 00:48:01 +00:00
Abiba (pi) a5dc880af1 ci: simplify workflow 2026-06-28 00:47:23 +00:00
abiba-bot 9b9845fd14 Merge pull request 'ci: replace actions/checkout with native git clone' (#29) from feat/ci-fix into main
ci: replace actions/checkout with native git clone (#29)
2026-06-28 00:45:51 +00:00
Abiba (pi) 106048999f test: minimal workflow 2026-06-28 00:45:02 +00:00
Abiba (pi) 6afc46734a ci: debug checkout step 2026-06-28 00:43:43 +00:00
Abiba (pi) 9ee1919985 ci: add auth to git clone in workflows 2026-06-28 00:42:41 +00:00
Abiba (pi) c2f91f6e58 ci: replace actions/checkout with native git clone
CI / validate (pull_request) Failing after 4s
CI / deploy (pull_request) Has been skipped
2026-06-28 00:41:49 +00:00
Abiba (pi) 67b6f64a93 test: simple runner test without actions
CI / validate (pull_request) Failing after 1s
CI / deploy (pull_request) Has been skipped
2026-06-28 00:40:22 +00:00
Abiba (pi) 45e206019c chore: trigger CI debug test
CI / validate (pull_request) Failing after 14m26s
CI / deploy (pull_request) Has been skipped
2026-06-28 00:38:11 +00:00
Abiba (pi) 78c2d967ff chore: trigger CI test
CI / validate (pull_request) Failing after 4s
CI / deploy (pull_request) Has been skipped
2026-06-28 00:37:10 +00:00
Abiba (pi) 2d467ef02c ci: Gitea Actions runner + real deploy workflows + git hooks
CI / validate (push) Failing after 7s
CI / deploy (push) Has been skipped
2026-06-28 00:31:32 +00:00
Abiba (pi) d21c565ea5 feat(agent-zero): session memory + homelab project context
CI / validate (push) Failing after 1s
CI / deploy (push) Has been skipped
A2A server v2:
- Persistent conversation history per sender (20 msg limit)
- Homelab system prompt as default project context
- tasks/session/new and tasks/session/clear endpoints
- Session memory survives across multiple Zulip DMs

Adapter:
- Passes deterministic session_id per sender_name
- Conversations continue naturally without re-explaining context
2026-06-27 19:26:28 +00:00
Abiba (pi) 1f615bbb17 fix(agent-zero): queue expiry detection in adapter
CI / validate (push) Failing after 2s
CI / deploy (push) Has been skipped
Zulip event queues expire after ~600s of inactivity. The adapter now
detects 400/BAD_EVENT_QUEUE_ID responses and auto-reconnects instead of
silently returning empty results.
2026-06-27 19:12:47 +00:00
Abiba (pi) 4938bad199 ci: staggered deployment pipeline + runner setup guide
CI / validate (push) Failing after 0s
CI / deploy (push) Has been skipped
Three-track deployment:
- v*.*.*-rc.* → Tanko canary (test first)
- v*.*.* → All Hermes agents (after canary)
- az-v*.*.* → kagentz (Agent Zero track)

Runner setup: docs/RUNNER-SETUP.md — deploy on CT 116 via Docker
2026-06-27 19:08:34 +00:00
Abiba (pi) d30b480525 ci: update Actions workflow — validate all plugins, auto-deploy on tags
CI / validate (push) Failing after 1s
CI / deploy (push) Has been skipped
2026-06-27 19:04:09 +00:00
root e946818375 refactor(pi): standalone Zulip gateway service — replaces pi extension
CI / validate (push) Failing after 1s
Complete rewrite of the pi Zulip extension as a standalone Node.js service
with direct harness API calls. No longer depends on pi's session — survives
pi shutdown and restart.

Changes:
- src/index.ts: Complete rewrite — standalone process, not a pi extension
  - Direct harness API calls (POST /v1/chat/completions) with conversation memory
  - Per-sender conversation history (up to 50 messages)
  - Placeholder->edit streaming for Zulip DMs
  - Typing indicators via Zulip API
  - Health endpoint on :9200
  - Exponential backoff reconnection
  - Graceful shutdown on SIGINT/SIGTERM
- abiba-zulip.service: systemd service unit file
- README.md: Updated deployment instructions
- package.json/tsconfig.json: Updated for standalone app

Deploy: npm install -> npx tsc -> systemctl enable abiba-zulip
Closes issue #24 (Hermes parity for pi)
2026-06-27 19:03:43 +00:00
root 2301f4aab9 Revert: remove hermes-enhancement (was not the right feature) 2026-06-27 19:03:43 +00:00
root aa305ce431 Add hermes-enhancement/: pi-style behavioral enhancement for Hermes agents
Self-service enhancement package for Hermes agents to adopt pi-style
conduct quality. Contains:
- prompts/behavioral-core.md: Distilled Three Pillars (~800 tokens)
- config/compression.yaml: 256K model optimization (80% threshold)
- config/mcp-servers.yaml: Tool parity (Context7, GitHub, Firecrawl, etc.)
- skills/: On-demand skills for conduct, verification, self-healing
- CHECKLIST-POC.md: Tanko POC verification checklist

POC pilot: Tanko
2026-06-27 19:03:43 +00:00
Abiba (pi) 7e6536ea57 fix(agent-zero): auto-date in system prompt, env vars for config
CI / validate (pull_request) Failing after 1s
CI / validate (push) Failing after 4s
v1.0.5
2026-06-27 18:57:32 +00:00
Abiba (pi) 4db655d4f9 feat(agent-zero): uvicorn A2A server calling LiteLLM directly
CI / validate (pull_request) Failing after 1s
2026-06-27 18:44:56 +00:00
Abiba (pi) 1cf6c2f806 feat(agent-zero): working A2A server with Agent Zero core integration
CI / validate (pull_request) Failing after 2s
A2A server uses Agent Zero's AgentContext.communicate() directly
to process Zulip messages inside the container.

Full chain verified: Zulip DM -> adapter -> A2A -> Agent Zero -> response -> Zulip
2026-06-27 18:21:20 +00:00
Abiba (pi) c6beb650c4 feat(agent-zero): Zulip adapter with A2A protocol for kagentz
CI / validate (pull_request) Failing after 2s
New project: agent-zero-zulip/ — direct Zulip integration for Agent Zero
agents using A2A protocol internally.

Architecture:
  kagentz (CT 105) ┌──────────────────────┐
                    │ Zulip Adapter  ◄──►  │ Agent Zero
                    │ polls Zulip    A2A   │ Docker container
                    │ port 8001            │
                    └──────────────────────┘

- adapter.py: Zulip event queue poller + A2A client
- No intermediate bridge — direct kagentz ↔ Zulip
- Heartbeat, reconnection, placeholder→edit streaming
- Designed for re-use: scottdenya, future Agent Zero agents
2026-06-27 18:04:00 +00:00
Abiba (pi) 1b0f1c627a fix(zulip): connect() accepts **kwargs for is_reconnect flag
CI / validate (pull_request) Failing after 1s
Hermes Gateway passes is_reconnect=True to connect() on reconnection.
Without **kwargs, the adapter crashes on reconnect.
2026-06-27 15:21:49 +00:00
Abiba (pi) 3690a7f568 fix(zulip): use PATCH /api/v1/messages/{id} for message editing
CI / validate (pull_request) Failing after 2s
Zulip API edits messages via PATCH /api/v1/messages/{message_id}
(POST returns 405 on this endpoint). Also:
- edit_message() now returns SendResult (not bool) for Gateway compatibility
- Clean up duplicate gateway instances before restart
2026-06-27 14:20:14 +00:00
Abiba (pi) 870f64d8a9 fix(zulip): edit_message accepts **kwargs, returns SendResult; use POST for edits
CI / validate (pull_request) Failing after 2s
The Gateway streaming interface calls edit_message() with finalize=True
and expects SendResult. Fixed:
1. Added **kwargs to edit_message() signature — silently ignores finalize
2. Changed return type from bool to SendResult for Gateway compatibility
3. Switched from PATCH to POST /api/v1/messages/{id} — Zulip docs use
   POST for message editing (PATCH returns 405 Method Not Allowed)
4. Same fixes applied to delete_message() and send()

Discovered during Tanko Gen 4 testing.
2026-06-27 14:18:42 +00:00