Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8354e88bc | ||
|
|
98d8ce6772 | ||
|
|
548e421fa1 | ||
|
|
c0191c9edc | ||
|
|
2d2259035a | ||
|
|
0147ac2abb | ||
|
|
c4ab31e56b |
@@ -0,0 +1,256 @@
|
||||
---
|
||||
kind: pattern
|
||||
name: delegation-prose-contract
|
||||
description: >
|
||||
Manager (Mumuni) operating doctrine for task decomposition, worker
|
||||
delegation, verification, and delivery. Defines when to delegate, which
|
||||
worker to use for what, how to handle failures, and the kanban board
|
||||
protocol. Enforces context-window discipline and separation of concerns.
|
||||
Runs on Mumuni (CT 118, storepve, .6) via Hermes agent.
|
||||
version: 1.0.0
|
||||
---
|
||||
|
||||
## Maintains
|
||||
|
||||
- Worker roster: 6 profiles (`syslog-code`, `syslog-devops`, `syslog-email`,
|
||||
`syslog-research`, `syslog-review`, `syslog-writer`)
|
||||
- Kanban board state at `~/.hermes/kanban/kanban.json`
|
||||
- Context window budget: ~65K tokens per request (131K total, 60% threshold)
|
||||
|
||||
## Topology
|
||||
|
||||
**Cluster:** 5 Proxmox nodes (ocupve, acerpve, minipve, amdpve, storepve)
|
||||
**Manager:** Mumuni (CT 118, storepve, .6) via Hermes agent
|
||||
**Workers:** 6 profiles, all running on the same agent — no separate hosts needed
|
||||
|
||||
This contract is infrastructure-agnostic in terms of which nodes are used.
|
||||
Workers execute tasks on whatever infrastructure they're given — SSH to .6,
|
||||
.pm, .9, .12, or .15 depending on the task. The contract defines the
|
||||
**who** and **when** — not the **where**.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
Without enforced delegation, the manager consumes the full iteration budget
|
||||
(60 calls) on single-turn tasks — SSH to 5 nodes, check each VM, read logs —
|
||||
leaving no capacity for actual coordination. The result: context overflow
|
||||
(59K tokens in system prompt), iteration exhaustion, and degraded response
|
||||
quality. This contract exists because I blew through my budget checking
|
||||
Proxmox node status instead of delegating to `syslog-devops`.
|
||||
|
||||
## Context Window Discipline
|
||||
|
||||
**The system prompt is ~6.5K tokens (stable: ~4.5K tool schemas + ~2K other guidance).**
|
||||
**Volatile (MEMORY.md + USER.md): ~300 tokens.**
|
||||
**Total base: ~6,800 tokens per request.**
|
||||
|
||||
The remaining budget is the conversation. Every tool call result adds to it.
|
||||
If a single call returns >10K tokens (e.g., `grep` on a large file, SSH output
|
||||
from multiple nodes), the context fills fast. That's why we delegate: workers
|
||||
process in isolation and return compact results.
|
||||
|
||||
## Trigger Conditions
|
||||
|
||||
Delegation is **mandatory** when any of these apply:
|
||||
|
||||
| Condition | Threshold | Example |
|
||||
|-----------|-----------|---------|
|
||||
| Multiple tool calls needed | 2+ calls with intermediate logic | Read file → analyze → write report |
|
||||
| Large data retrieval | Output >5K tokens | `grep -r "pattern" /path` on large dirs |
|
||||
| Cross-domain work | Spans 2+ worker specialties | Infra check + email filter |
|
||||
| Infrastructure changes | Any mutating operation | `qm set`, `systemctl restart`, `git push` |
|
||||
| Research/analysis | Needs browser or deep reading | Web research, code review, data analysis |
|
||||
| Code builds or changes | Writing or modifying code | Scripts, configs, patches |
|
||||
| Sequential dependencies | Worker B needs Worker A's output | Code → Review → Deliver |
|
||||
|
||||
**Single tool calls stay at manager level.** Quick `grep`, `ls`, `cat`,
|
||||
`curl`, `hermes tools list` — these are decision-making tools. The manager
|
||||
reads them directly.
|
||||
|
||||
## Worker Selection Matrix
|
||||
|
||||
| Worker | Model | Toolsets | Role | Use When |
|
||||
|--------|-------|----------|------|----------|
|
||||
| `syslog-code` | qwen3.6-27B-code | terminal, file, web, memory, skills | Code patches, automation, scripts | Writing/modifying code, creating scripts, debugging, reading/writing files |
|
||||
| `syslog-devops` | qwen3.6-27B-code | terminal, file, web, memory, skills | Infrastructure, DB, bridge, Proxmox | Server ops, SSH, Docker, Proxmox, DB queries, hardware checks |
|
||||
| `syslog-email` | ornith-1.0-35b | terminal, file, web, memory, skills | Email automation, mail operations | Sending/receiving email, inbox management, SMTP operations |
|
||||
| `syslog-research` | ornith-1.0-35b | terminal, file, web, memory, skills, **browser** | Analysis, classification, data processing | Web research, browser tasks, data analysis, classification, reading docs |
|
||||
| `syslog-review` | ornith-1.0-35b | terminal, file, web, memory, skills | Verification, QA, audit validation | **ALWAYS** verify worker output before delivery — especially for infra changes, code builds, and research findings |
|
||||
| `syslog-writer` | ornith-1.0-35b | terminal, file, web, memory, skills | Docs, content, branding, reports | Writing docs, reports, proposals, content, markdown formatting |
|
||||
|
||||
### Selection Rules
|
||||
|
||||
1. **Match specialty first.** A code task → `syslog-code`. An infra task →
|
||||
`syslog-devops`. Don't put a `syslog-email` worker on a code review.
|
||||
2. **Research tasks with browser needs → `syslog-research`.** Other workers
|
||||
don't have the browser toolset.
|
||||
3. **Verification → `syslog-review`.** Never deliver raw worker output.
|
||||
4. **Documentation/content → `syslog-writer`.** Let them own the prose.
|
||||
5. **If unsure, delegate to `syslog-research`** — it has the broadest toolset
|
||||
(includes browser) and high reasoning effort.
|
||||
|
||||
## Delegation Protocol
|
||||
|
||||
### Step 1: Decompose
|
||||
|
||||
Break the task into lanes. Each lane does ONE thing. Workers are independent —
|
||||
no lane depends on another's output mid-flight. If lanes depend on each other,
|
||||
dispatch sequentially.
|
||||
|
||||
### Step 2: Dispatch
|
||||
|
||||
Fire workers via `delegate_task`:
|
||||
|
||||
**Parallel (independent lanes):**
|
||||
```
|
||||
delegate_task(
|
||||
tasks=[
|
||||
{"goal": "Check all 5 Proxmox nodes for VM status", "context": "SSH to each node via 192.168.68.x, run 'qm list'"},
|
||||
{"goal": "Check Docker container health on .7/.116/.17", "context": "SSH to each host, check container status"},
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
**Sequential (dependent lanes):**
|
||||
Dispatch lane 1 → wait for result → dispatch lane 2.
|
||||
|
||||
### Step 3: Verify
|
||||
|
||||
**MANDATORY for:**
|
||||
- Infrastructure changes (any `qm`, `pct`, `systemctl`, `git push`)
|
||||
- Code builds and modifications
|
||||
- Research findings (web data, external sources)
|
||||
- Any output that will reach the user
|
||||
|
||||
**Fire `syslog-review` to verify:**
|
||||
```
|
||||
delegate_task(
|
||||
goal="Review the output of the devops worker. Verify the node status
|
||||
report is accurate, check for inconsistencies, confirm all nodes were
|
||||
reachable.",
|
||||
context="Worker was syslog-devops. Output is at /tmp/node-report.md.
|
||||
Verify against live system."
|
||||
)
|
||||
```
|
||||
|
||||
**If verification fails:**
|
||||
1. Send work back to original worker with review feedback
|
||||
2. Re-verify
|
||||
3. Max 2 re-verify cycles before escalating to Kwame
|
||||
|
||||
### Step 4: Deliver
|
||||
|
||||
Only verified results reach Kwame. Format per channel:
|
||||
- Telegram: Use `telegram-formatting` skill
|
||||
- Zulip: Use Zulip Markdown (CommonMark)
|
||||
- Email: Use `syslog-email` skill
|
||||
|
||||
## Kanban Board Protocol
|
||||
|
||||
**File:** `~/.hermes/kanban/kanban.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "unique-id",
|
||||
"title": "Task description",
|
||||
"created": "2026-07-09T01:00:00",
|
||||
"status": "backlog|in_progress|review|done",
|
||||
"lanes": [
|
||||
{
|
||||
"lane_id": "devops-check",
|
||||
"worker": "syslog-devops",
|
||||
"goal": "Check all 5 Proxmox nodes",
|
||||
"status": "dispatched|completed|failed",
|
||||
"output_file": "/tmp/node-report.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Update the board on every state change.**
|
||||
|
||||
## Failure Handling
|
||||
|
||||
### Worker Timeouts
|
||||
|
||||
- Child timeout: **900 seconds** (15 minutes)
|
||||
- Worker model `syslog-auto` is slow — it can hit the timeout limit with
|
||||
22+ API calls
|
||||
- **If a worker times out:** Re-dispatch with a narrower scope. Break the
|
||||
task into smaller pieces that fit in the timeout window.
|
||||
- **Avoid delegating sequential SSH hops** — each SSH connection adds latency
|
||||
that compounds quickly. Prefer API-based or local approaches when possible.
|
||||
|
||||
### Worker Selection Failures
|
||||
|
||||
- `syslog-devops` is best for infrastructure tasks (SSH, Proxmox, Docker)
|
||||
- `syslog-code` is best for code-level work (reading files, writing scripts)
|
||||
- `syslog-research` has the browser toolset — use for web research
|
||||
- `syslog-review` is the QA gate — always fire before delivery
|
||||
- **Never fire more than 3 parallel workers** (max_concurrent_children: 3)
|
||||
- **Never nest delegation** (max_spawn_depth: 1)
|
||||
|
||||
### Context Overflow
|
||||
|
||||
- If a task requires >10K tokens of output, delegate the processing
|
||||
- Workers return compact summaries, not raw data dumps
|
||||
- Pass file paths and concrete goals — never dump raw data into context
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- ❌ Reading large files into your own context before deciding → delegate the read
|
||||
- ❌ Carrying SSH/grep/output results in your context → delegate the analysis
|
||||
- ❌ Doing work yourself and then "pretending" to delegate → the user can tell
|
||||
- ❌ Skipping verification → raw worker output never reaches the user
|
||||
- ❌ Delegating single tool calls → keep quick reads/writes at manager level
|
||||
- ❌ Firing more than 3 workers in parallel → hard limit
|
||||
|
||||
## Emergency Exception
|
||||
|
||||
**In an emergency (server down, service must be restored immediately):**
|
||||
- Delegate the diagnosis (find the problem)
|
||||
- Execute the fix yourself (minimize handoff latency)
|
||||
- Verify the fix after delivery
|
||||
- Log the exception in the kanban board
|
||||
|
||||
The emergency exception exists because the user needs the service back NOW,
|
||||
not after three worker round-trips. But it's an exception — not the rule.
|
||||
|
||||
## What This Contract Doesn't Cover
|
||||
|
||||
1. **Worker profile configuration** — covered by `hermes-config-template.prose.md`
|
||||
2. **SSH key management** — covered by existing SSH/Proxmox contracts
|
||||
3. **Git workflow** — covered by `AGENTS.md` in the prose-contracts repo
|
||||
4. **Cron job management** — covered by individual cron contracts
|
||||
5. **Infra verification** — covered by `verify-before-mutate` protocol
|
||||
|
||||
## Verification
|
||||
|
||||
Run `scripts/worker-audit.py` to verify all 6 profiles are aligned:
|
||||
|
||||
```bash
|
||||
python3 /root/.hermes/skills/kanban-orchestrator/scripts/worker-audit.py
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- `kanban-orchestrator` skill: The operational playbook (detailed execution steps)
|
||||
- `worker-profile-audit.md` (skill reference): Worker configuration audit notes
|
||||
- `delegation-timeout-patterns.md` (skill reference): Timeout handling patterns
|
||||
- `verify-before-mutate` protocol: Infrastructure change verification
|
||||
- `hermes-config-template.prose.md`: Worker profile configuration
|
||||
|
||||
## Success Criteria
|
||||
|
||||
This contract succeeds when:
|
||||
|
||||
1. **No context overflow** — single-turn tasks don't exhaust the iteration budget
|
||||
2. **Workers do the work** — manager coordinates, doesn't execute
|
||||
3. **Verification before delivery** — all output passes through `syslog-review`
|
||||
4. **Kanban board is current** — every task has a lane, every lane has a status
|
||||
5. **User gets verified results** — raw worker output never reaches Kwame
|
||||
|
||||
---
|
||||
|
||||
**Last updated:** 2026-07-09
|
||||
**Author:** Mumuni (with Kwame's input on triggers and exception criteria)
|
||||
**Status:** Draft — awaiting PR review and merge to prose-contracts main
|
||||
@@ -0,0 +1,188 @@
|
||||
---
|
||||
kind: function
|
||||
name: hermes-zulip-restore
|
||||
description: >
|
||||
Restores Zulip connectivity for any Hermes agent (Mumuni CT114, Tanko CT112,
|
||||
Koby CT111). Deploys the zulip-platform adapter to the correct bundled plugin
|
||||
path, verifies env credentials, restarts the gateway, and confirms Zulip
|
||||
connects. Run this whenever a Hermes agent stops responding on Zulip or after
|
||||
a fresh agent deployment.
|
||||
agent: abiba
|
||||
version: 1.0.0
|
||||
status: active
|
||||
runtime_contract: 2
|
||||
---
|
||||
|
||||
# Hermes Zulip Restore — Bring Any Agent Back to Good State
|
||||
|
||||
Single-shot function that restores full Zulip connectivity for a Hermes agent.
|
||||
Covers adapter deployment, HTML stripping (slash command fix), env verification,
|
||||
gateway restart, and connection validation.
|
||||
|
||||
## Parameters
|
||||
|
||||
| Param | Type | Required | Default | Description |
|
||||
|-------|------|----------|---------|-------------|
|
||||
| `target` | string | yes | — | Agent name: `mumuni`, `tanko`, or `koby` |
|
||||
|
||||
## Maintains
|
||||
|
||||
- adapter_deployed: bool — Whether `_strip_html` adapter is at correct bundled path
|
||||
- zulip_connected: bool — Whether gateway_state shows zulip.state = "connected"
|
||||
- env_valid: bool — Whether .env has ZULIP_SITE, ZULIP_EMAIL, ZULIP_API_KEY
|
||||
- gateway_running: bool — Whether gateway process is running
|
||||
|
||||
### Postconditions
|
||||
|
||||
- `_strip_html` function present in `<hermes-agent>/plugins/platforms/zulip/adapter.py`
|
||||
- All three adapter files (__init__.py, adapter.py, plugin.yaml) present at bundled path
|
||||
- Zulip env vars set in `~/.hermes/.env` (or `/home/jerome/.hermes/.env` for Tanko)
|
||||
- Gateway restarted and zulip platform reports state `connected`
|
||||
- HTML stripping enabled for `/approve` and `/deny` slash command support
|
||||
|
||||
## 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
|
||||
- Zulip server accessible at `https://chat.sysloggh.net`
|
||||
|
||||
## 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 |
|
||||
|-------|-------|-------|
|
||||
| Zulip server | https://chat.sysloggh.net | ✅ Verified |
|
||||
| Git repo (zulip-platform) | `https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git` | ✅ Verified |
|
||||
| Bundled adapter path | `<HERMES_HOME>/hermes-agent/plugins/platforms/zulip/` | ✅ Verified |
|
||||
| Git branch | `feat/zulip-streaming` | ✅ Verified (contains _strip_html fix) |
|
||||
|
||||
## Execution
|
||||
|
||||
### Step 1: Locate Target
|
||||
|
||||
Map `target` to connectivity parameters from the live-state table above.
|
||||
For CT112 and CT111, route through `ssh root@amdpve` then `pct exec <id>`.
|
||||
|
||||
### Step 2: Deploy Zulip Adapter
|
||||
|
||||
On the target host:
|
||||
|
||||
```bash
|
||||
# Clone or update the plugin repo
|
||||
mkdir -p /tmp/zulip-deploy
|
||||
cd /tmp/zulip-deploy
|
||||
if [ -d zulip-platform-plugins ]; then
|
||||
cd zulip-platform-plugins && git pull origin feat/zulip-streaming
|
||||
else
|
||||
git clone --branch feat/zulip-streaming \
|
||||
https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins.git
|
||||
fi
|
||||
|
||||
# Ensure bundled plugin directory exists
|
||||
mkdir -p <HERMES_HOME>/hermes-agent/plugins/platforms/zulip
|
||||
|
||||
# Copy adapter files
|
||||
cp zulip-platform-plugins/plugins/platforms/zulip/adapter.py \
|
||||
zulip-platform-plugins/plugins/platforms/zulip/__init__.py \
|
||||
zulip-platform-plugins/plugins/platforms/zulip/plugin.yaml \
|
||||
<HERMES_HOME>/hermes-agent/plugins/platforms/zulip/
|
||||
|
||||
# Fix ownership (Tanko only)
|
||||
chown -R jerome:jerome <HERMES_HOME>/hermes-agent/plugins/platforms/zulip/ # Tanko only
|
||||
|
||||
# Clean up
|
||||
rm -rf /tmp/zulip-deploy
|
||||
```
|
||||
|
||||
### Step 3: Verify _strip_html is Present
|
||||
|
||||
```bash
|
||||
grep -q "_strip_html" <HERMES_HOME>/hermes-agent/plugins/platforms/zulip/adapter.py
|
||||
```
|
||||
Expected: exit code 0. If not found → adapter is stale, re-run Step 2 with fresh clone.
|
||||
|
||||
### Step 4: Verify Env Credentials
|
||||
|
||||
```bash
|
||||
grep -E "ZULIP_SITE|ZULIP_EMAIL|ZULIP_API_KEY" <HERMES_HOME>/.env
|
||||
```
|
||||
|
||||
Expected: all three variables set with non-empty values. If any missing:
|
||||
- ZULIP_SITE: `https://chat.sysloggh.net`
|
||||
- ZULIP_EMAIL: `<agent>-bot@chat.sysloggh.net`
|
||||
- ZULIP_API_KEY: obtain from Zulip admin panel (Bots → show API key)
|
||||
|
||||
### Step 5: Restart Gateway
|
||||
|
||||
```bash
|
||||
cd <HERMES_HOME>/hermes-agent
|
||||
# Use venv if available
|
||||
python3 -m hermes_cli.main gateway restart # or: venv/bin/python -m hermes_cli.main gateway restart
|
||||
```
|
||||
|
||||
Wait for the restart to complete (up to 45s). Check:
|
||||
|
||||
```bash
|
||||
grep "Gateway running" <HERMES_HOME>/logs/gateway.log | tail -1
|
||||
```
|
||||
|
||||
Expected: "Gateway running with N platform(s)" where N > 1 (includes zulip).
|
||||
|
||||
### Step 6: Validate Zulip Connection
|
||||
|
||||
```bash
|
||||
python3 -c "
|
||||
import json
|
||||
d = json.load(open('$HERMES_HOME/gateway_state.json'))
|
||||
print('zulip:', d.get('platforms', {}).get('zulip', {}).get('state', 'NOT FOUND'))
|
||||
"
|
||||
```
|
||||
|
||||
Expected: `zulip: connected`. If not connected, check gateway log:
|
||||
|
||||
```bash
|
||||
grep -E "zulip|Zulip|ZULIP" <HERMES_HOME>/logs/gateway.log | tail -10
|
||||
```
|
||||
|
||||
### Step 7: Report
|
||||
|
||||
Compile results: `{ adapter_deployed, zulip_connected, env_valid, gateway_running }`.
|
||||
|
||||
| State | Action |
|
||||
|-------|--------|
|
||||
| All true | ✅ Agent restored — relay success to user |
|
||||
| `adapter_deployed: false` | Re-run Step 2 |
|
||||
| `env_valid: false` | Prompt for missing credentials |
|
||||
| `zulip_connected: false` | Check Zulip server reachability, verify API key |
|
||||
| `gateway_running: false` | Check process logs for crash cause |
|
||||
|
||||
## Known Failure Modes
|
||||
|
||||
| Symptom | Root Cause | Recovery |
|
||||
|---------|-----------|----------|
|
||||
| Gateway running with 1 platform(s) | Adapter at wrong path (user plugins vs bundled) | Deploy to `<hermes-agent>/plugins/platforms/zulip/` not `~/.hermes/plugins/` |
|
||||
| Queue expired / BAD_EVENT_QUEUE_ID | Idle for 10+ minutes → normal | Auto-reconnects — no action needed |
|
||||
| No events received for N seconds | No DMs or @mentions sent to this bot | Normal if nobody messaged the agent |
|
||||
| `httpx` not found | Missing dependency | `pip install httpx` in the Hermes venv or system Python |
|
||||
| Slash commands not matching | Missing `_strip_html` — Zulip sends `<p>/approve</p>` | Verify `_strip_html` in adapter (Step 3) |
|
||||
| Permission denied on gateway restart | Running as wrong user | Use `su - jerome` for Tanko; root for others |
|
||||
|
||||
## Git Branch Reference
|
||||
|
||||
The `_strip_html` fix lives on `feat/zulip-streaming` branch:
|
||||
```
|
||||
https://git.sysloggh.net/SyslogSolution/zulip-platform-plugins/src/branch/feat/zulip-streaming
|
||||
```
|
||||
|
||||
Commit `55ca15d` — `fix(zulip): add _strip_html for slash command matching`
|
||||
Pull request #33 is the primary integration branch.
|
||||
|
||||
---
|
||||
|
||||
**Last verified good state**: 2026-07-08 — Mumuni, Tanko, Koby all connected with `_strip_html` applied.
|
||||
@@ -0,0 +1,256 @@
|
||||
---
|
||||
kind: pattern
|
||||
name: mumuni-delegation
|
||||
description: >
|
||||
Mumuni-specific operating doctrine for task decomposition, worker
|
||||
delegation, verification, and delivery. Defines when to delegate, which
|
||||
worker to use for what, how to handle failures, and the kanban board
|
||||
protocol. Enforces context-window discipline and separation of concerns.
|
||||
Runs on Mumuni (CT 118, storepve, .6) via Hermes agent.
|
||||
version: 1.0.0
|
||||
---
|
||||
|
||||
## Maintains
|
||||
|
||||
- Worker roster: 6 profiles (`syslog-code`, `syslog-devops`, `syslog-email`,
|
||||
`syslog-research`, `syslog-review`, `syslog-writer`)
|
||||
- Kanban board state at `~/.hermes/kanban/kanban.json`
|
||||
- Context window budget: ~65K tokens per request (131K total, 60% threshold)
|
||||
|
||||
## Topology
|
||||
|
||||
**Cluster:** 5 Proxmox nodes (ocupve, acerpve, minipve, amdpve, storepve)
|
||||
**Manager:** Mumuni (CT 118, storepve, .6) via Hermes agent
|
||||
**Workers:** 6 profiles, all running on the same agent — no separate hosts needed
|
||||
|
||||
This contract is infrastructure-agnostic in terms of which nodes are used.
|
||||
Workers execute tasks on whatever infrastructure they're given — SSH to .6,
|
||||
.pm, .9, .12, or .15 depending on the task. The contract defines the
|
||||
**who** and **when** — not the **where**.
|
||||
|
||||
## Why This Matters
|
||||
|
||||
Without enforced delegation, the manager consumes the full iteration budget
|
||||
(60 calls) on single-turn tasks — SSH to 5 nodes, check each VM, read logs —
|
||||
leaving no capacity for actual coordination. The result: context overflow
|
||||
(59K tokens in system prompt), iteration exhaustion, and degraded response
|
||||
quality. This contract exists because I blew through my budget checking
|
||||
Proxmox node status instead of delegating to `syslog-devops`.
|
||||
|
||||
## Context Window Discipline
|
||||
|
||||
**The system prompt is ~6.5K tokens (stable: ~4.5K tool schemas + ~2K other guidance).**
|
||||
**Volatile (MEMORY.md + USER.md): ~300 tokens.**
|
||||
**Total base: ~6,800 tokens per request.**
|
||||
|
||||
The remaining budget is the conversation. Every tool call result adds to it.
|
||||
If a single call returns >10K tokens (e.g., `grep` on a large file, SSH output
|
||||
from multiple nodes), the context fills fast. That's why we delegate: workers
|
||||
process in isolation and return compact results.
|
||||
|
||||
## Trigger Conditions
|
||||
|
||||
Delegation is **mandatory** when any of these apply:
|
||||
|
||||
| Condition | Threshold | Example |
|
||||
|-----------|-----------|---------|
|
||||
| Multiple tool calls needed | 2+ calls with intermediate logic | Read file → analyze → write report |
|
||||
| Large data retrieval | Output >5K tokens | `grep -r "pattern" /path` on large dirs |
|
||||
| Cross-domain work | Spans 2+ worker specialties | Infra check + email filter |
|
||||
| Infrastructure changes | Any mutating operation | `qm set`, `systemctl restart`, `git push` |
|
||||
| Research/analysis | Needs browser or deep reading | Web research, code review, data analysis |
|
||||
| Code builds or changes | Writing or modifying code | Scripts, configs, patches |
|
||||
| Sequential dependencies | Worker B needs Worker A's output | Code → Review → Deliver |
|
||||
|
||||
**Single tool calls stay at manager level.** Quick `grep`, `ls`, `cat`,
|
||||
`curl`, `hermes tools list` — these are decision-making tools. The manager
|
||||
reads them directly.
|
||||
|
||||
## Worker Selection Matrix
|
||||
|
||||
| Worker | Model | Toolsets | Role | Use When |
|
||||
|--------|-------|----------|------|----------|
|
||||
| `syslog-code` | qwen3.6-27B-code | terminal, file, web, memory, skills | Code patches, automation, scripts | Writing/modifying code, creating scripts, debugging, reading/writing files |
|
||||
| `syslog-devops` | qwen3.6-27B-code | terminal, file, web, memory, skills | Infrastructure, DB, bridge, Proxmox | Server ops, SSH, Docker, Proxmox, DB queries, hardware checks |
|
||||
| `syslog-email` | ornith-1.0-35b | terminal, file, web, memory, skills | Email automation, mail operations | Sending/receiving email, inbox management, SMTP operations |
|
||||
| `syslog-research` | ornith-1.0-35b | terminal, file, web, memory, skills, **browser** | Analysis, classification, data processing | Web research, browser tasks, data analysis, classification, reading docs |
|
||||
| `syslog-review` | ornith-1.0-35b | terminal, file, web, memory, skills | Verification, QA, audit validation | **ALWAYS** verify worker output before delivery — especially for infra changes, code builds, and research findings |
|
||||
| `syslog-writer` | ornith-1.0-35b | terminal, file, web, memory, skills | Docs, content, branding, reports | Writing docs, reports, proposals, content, markdown formatting |
|
||||
|
||||
### Selection Rules
|
||||
|
||||
1. **Match specialty first.** A code task → `syslog-code`. An infra task →
|
||||
`syslog-devops`. Don't put a `syslog-email` worker on a code review.
|
||||
2. **Research tasks with browser needs → `syslog-research`.** Other workers
|
||||
don't have the browser toolset.
|
||||
3. **Verification → `syslog-review`.** Never deliver raw worker output.
|
||||
4. **Documentation/content → `syslog-writer`.** Let them own the prose.
|
||||
5. **If unsure, delegate to `syslog-research`** — it has the broadest toolset
|
||||
(includes browser) and high reasoning effort.
|
||||
|
||||
## Delegation Protocol
|
||||
|
||||
### Step 1: Decompose
|
||||
|
||||
Break the task into lanes. Each lane does ONE thing. Workers are independent —
|
||||
no lane depends on another's output mid-flight. If lanes depend on each other,
|
||||
dispatch sequentially.
|
||||
|
||||
### Step 2: Dispatch
|
||||
|
||||
Fire workers via `delegate_task`:
|
||||
|
||||
**Parallel (independent lanes):**
|
||||
```
|
||||
delegate_task(
|
||||
tasks=[
|
||||
{"goal": "Check all 5 Proxmox nodes for VM status", "context": "SSH to each node via 192.168.68.x, run 'qm list'"},
|
||||
{"goal": "Check Docker container health on .7/.116/.17", "context": "SSH to each host, check container status"},
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
**Sequential (dependent lanes):**
|
||||
Dispatch lane 1 → wait for result → dispatch lane 2.
|
||||
|
||||
### Step 3: Verify
|
||||
|
||||
**MANDATORY for:**
|
||||
- Infrastructure changes (any `qm`, `pct`, `systemctl`, `git push`)
|
||||
- Code builds and modifications
|
||||
- Research findings (web data, external sources)
|
||||
- Any output that will reach the user
|
||||
|
||||
**Fire `syslog-review` to verify:**
|
||||
```
|
||||
delegate_task(
|
||||
goal="Review the output of the devops worker. Verify the node status
|
||||
report is accurate, check for inconsistencies, confirm all nodes were
|
||||
reachable.",
|
||||
context="Worker was syslog-devops. Output is at /tmp/node-report.md.
|
||||
Verify against live system."
|
||||
)
|
||||
```
|
||||
|
||||
**If verification fails:**
|
||||
1. Send work back to original worker with review feedback
|
||||
2. Re-verify
|
||||
3. Max 2 re-verify cycles before escalating to Kwame
|
||||
|
||||
### Step 4: Deliver
|
||||
|
||||
Only verified results reach Kwame. Format per channel:
|
||||
- Telegram: Use `telegram-formatting` skill
|
||||
- Zulip: Use Zulip Markdown (CommonMark)
|
||||
- Email: Use `syslog-email` skill
|
||||
|
||||
## Kanban Board Protocol
|
||||
|
||||
**File:** `~/.hermes/kanban/kanban.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"task_id": "unique-id",
|
||||
"title": "Task description",
|
||||
"created": "2026-07-09T01:00:00",
|
||||
"status": "backlog|in_progress|review|done",
|
||||
"lanes": [
|
||||
{
|
||||
"lane_id": "devops-check",
|
||||
"worker": "syslog-devops",
|
||||
"goal": "Check all 5 Proxmox nodes",
|
||||
"status": "dispatched|completed|failed",
|
||||
"output_file": "/tmp/node-report.md"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Update the board on every state change.**
|
||||
|
||||
## Failure Handling
|
||||
|
||||
### Worker Timeouts
|
||||
|
||||
- Child timeout: **900 seconds** (15 minutes)
|
||||
- Worker model `syslog-auto` is slow — it can hit the timeout limit with
|
||||
22+ API calls
|
||||
- **If a worker times out:** Re-dispatch with a narrower scope. Break the
|
||||
task into smaller pieces that fit in the timeout window.
|
||||
- **Avoid delegating sequential SSH hops** — each SSH connection adds latency
|
||||
that compounds quickly. Prefer API-based or local approaches when possible.
|
||||
|
||||
### Worker Selection Failures
|
||||
|
||||
- `syslog-devops` is best for infrastructure tasks (SSH, Proxmox, Docker)
|
||||
- `syslog-code` is best for code-level work (reading files, writing scripts)
|
||||
- `syslog-research` has the browser toolset — use for web research
|
||||
- `syslog-review` is the QA gate — always fire before delivery
|
||||
- **Never fire more than 3 parallel workers** (max_concurrent_children: 3)
|
||||
- **Never nest delegation** (max_spawn_depth: 1)
|
||||
|
||||
### Context Overflow
|
||||
|
||||
- If a task requires >10K tokens of output, delegate the processing
|
||||
- Workers return compact summaries, not raw data dumps
|
||||
- Pass file paths and concrete goals — never dump raw data into context
|
||||
|
||||
## Anti-patterns
|
||||
|
||||
- ❌ Reading large files into your own context before deciding → delegate the read
|
||||
- ❌ Carrying SSH/grep/output results in your context → delegate the analysis
|
||||
- ❌ Doing work yourself and then "pretending" to delegate → the user can tell
|
||||
- ❌ Skipping verification → raw worker output never reaches the user
|
||||
- ❌ Delegating single tool calls → keep quick reads/writes at manager level
|
||||
- ❌ Firing more than 3 workers in parallel → hard limit
|
||||
|
||||
## Emergency Exception
|
||||
|
||||
**In an emergency (server down, service must be restored immediately):**
|
||||
- Delegate the diagnosis (find the problem)
|
||||
- Execute the fix yourself (minimize handoff latency)
|
||||
- Verify the fix after delivery
|
||||
- Log the exception in the kanban board
|
||||
|
||||
The emergency exception exists because the user needs the service back NOW,
|
||||
not after three worker round-trips. But it's an exception — not the rule.
|
||||
|
||||
## What This Contract Doesn't Cover
|
||||
|
||||
1. **Worker profile configuration** — covered by `hermes-config-template.prose.md`
|
||||
2. **SSH key management** — covered by existing SSH/Proxmox contracts
|
||||
3. **Git workflow** — covered by `AGENTS.md` in the prose-contracts repo
|
||||
4. **Cron job management** — covered by individual cron contracts
|
||||
5. **Infra verification** — covered by `verify-before-mutate` protocol
|
||||
|
||||
## Verification
|
||||
|
||||
Run `scripts/worker-audit.py` to verify all 6 profiles are aligned:
|
||||
|
||||
```bash
|
||||
python3 /root/.hermes/skills/kanban-orchestrator/scripts/worker-audit.py
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- `kanban-orchestrator` skill: The operational playbook (detailed execution steps)
|
||||
- `worker-profile-audit.md` (skill reference): Worker configuration audit notes
|
||||
- `delegation-timeout-patterns.md` (skill reference): Timeout handling patterns
|
||||
- `verify-before-mutate` protocol: Infrastructure change verification
|
||||
- `hermes-config-template.prose.md`: Worker profile configuration
|
||||
|
||||
## Success Criteria
|
||||
|
||||
This contract succeeds when:
|
||||
|
||||
1. **No context overflow** — single-turn tasks don't exhaust the iteration budget
|
||||
2. **Workers do the work** — manager coordinates, doesn't execute
|
||||
3. **Verification before delivery** — all output passes through `syslog-review`
|
||||
4. **Kanban board is current** — every task has a lane, every lane has a status
|
||||
5. **User gets verified results** — raw worker output never reaches Kwame
|
||||
|
||||
---
|
||||
|
||||
**Last updated:** 2026-07-09
|
||||
**Author:** Mumuni (with Kwame's input on triggers and exception criteria)
|
||||
**Status:** Draft — awaiting PR review and merge to prose-contracts main
|
||||
Reference in New Issue
Block a user