Clawhub Select
by @techtanush
Enables secure, peer-to-peer task negotiation and commitment tracking between two OpenClaw agents without requiring a central server.
clawhub install claw-diplomatπ About This Skill
βββββββββββββββββββββββββββββββββββββββββββββ
claw-diplomat β ClawHub Skill Manifest v1.0.0
βββββββββββββββββββββββββββββββββββββββββββββ
name: claw-diplomat version: 1.0.0 skill_type: code # Contains executable Python scripts + TypeScript hooks β NOT instruction-only display_name: "Claw Diplomat π€" emoji: π€ tagline: "Peer-to-peer task negotiation between two OpenClaw agents. No server required." author: claw-diplomat-team license: MIT-0 homepage: https://clawhub.io/skills/claw-diplomat support: https://github.com/claw-diplomat/claw-diplomat/issues source_url: https://github.com/claw-diplomat/claw-diplomat
βββ Compatibility ββββββββββββββββββββββββββββ
openclaw_min_version: "2026.2.23" platforms: - macos - linux - windows # via WSL2βββ Categories & Discoverability ββββββββββββ
category: collaboration tags: - negotiation - peer-to-peer - collaboration - task-management - commitment-tracking - local-first - relay - encrypted - multi-agent - productivityβββ Runtime Requirements ββββββββββββββββββββ
requires: runtime: - python: ">=3.10" python_packages: - PyNaCl: ">=1.5" - noiseprotocol: ">=0.3" - websockets: ">=12.0" binaries: - python3 # negotiation scripts runtime - pip3 # package installation at setup time node_packages: - "@openclaw/sdk" # provided by OpenClaw gateway; not installed by this skillβββ Environment Variables βββββββββββββββββββ
env: optional: - name: DIPLOMAT_PORT default: "7432" description: "Base port. Inbound UDP hole-punch uses DIPLOMAT_PORT+1 (default 7433)." - name: DIPLOMAT_RELAY_URL default: "wss://claw-diplomat-relay-production.up.railway.app:443" description: "Relay server WebSocket URL. Override to use a self-hosted relay." - name: DIPLOMAT_TOKEN_TTL_DAYS default: "7" description: "Diplomat Address token validity in days. Range: 1β30." - name: DIPLOMAT_TIMEOUT_HOURS default: "24" description: "Hours to wait for peer response before a session expires." - name: DIPLOMAT_LOG_LEVEL default: "INFO" description: "Verbosity: DEBUG | INFO | WARN | ERROR" - name: DIPLOMAT_WORKSPACE default: "(OpenClaw workspace root)" description: "Override the workspace root path. Usually not needed."βββ Workspace File Access (exact paths) βββββ
workspace_access: reads: - SOUL.md - AGENTS.md - MEMORY.md - HEARTBEAT.md - "memory/" appends: - MEMORY.md - HEARTBEAT.md - "memory/YYYY-MM-DD.md" - "skills/claw-diplomat/archive.md" creates_or_overwrites: - "skills/claw-diplomat/diplomat.key" # mode 600; created once on first run - "skills/claw-diplomat/diplomat.pub" # mode 644; created once on first run - "skills/claw-diplomat/my-address.token" # overwritten on /claw-diplomat generate-address - "skills/claw-diplomat/peers.json" # updated on connect and reconnect - "skills/claw-diplomat/ledger.json" # updated on every state transition - "skills/claw-diplomat/pending_approvals.json" # inbound connection requests awaiting approval - "skills/claw-diplomat/listener.pid" # written by gateway hook never_writes: # These files are READ (for alias/peer lookup) but NEVER modified or appended. # "never_writes" = read-only for this skill; not the same as "never accessed". - SOUL.md - AGENTS.md - "Any path outside workspace root"βββ Network Permissions (all endpoints declared) β
network: outbound_https: - host: claw-diplomat-relay-production.up.railway.app port: 443 paths: - /reserve # GET: reserve relay slot for Diplomat Address - /myip # GET: discover public IP for nat_hint - /reserve/{token}/revoke # GET: revoke a relay token protocol: HTTPS purpose: "Relay slot reservation and IP discovery" encrypted: true frequency: "On /claw-diplomat generate-address and /claw-diplomat revoke only" outbound_wss: - host: claw-diplomat-relay-production.up.railway.app port: 443 path: /ws protocol: WSS (WebSocket over TLS) purpose: "Encrypted relay channel for peer-to-peer negotiation" encrypted: true frequency: "During active negotiation sessions only" - host: "${DIPLOMAT_RELAY_URL}" port: "(configurable)" protocol: WSS purpose: "Self-hosted relay (only used if DIPLOMAT_RELAY_URL is set)" encrypted: true frequency: "During active negotiation sessions only" inbound_udp: - port: "${DIPLOMAT_PORT+1}" # default 7433 protocol: UDP purpose: "NAT hole-punch direct connection (optional; relay is always the fallback)" frequency: "10-second attempt per new connection; does not persist" external_internet: true connects_to_external_apis: false # relay is infrastructure, not an API cloud_services: none # relay is self-hostable Docker; no lock-inβββ Hooks βββββββββββββββββββββββββββββββββββ
hooks: - name: diplomat-bootstrap location: hooks/diplomat-bootstrap/ events: - agent:bootstrap fail_open: true timeout_ms: 2000 purpose: "Inject active commitments into session context" - name: diplomat-heartbeat location: hooks/diplomat-heartbeat/ events: - command:new fail_open: true timeout_ms: 500 purpose: "Surface overdue/upcoming deadlines on every human message" - name: diplomat-gateway location: hooks/diplomat-gateway/ events: - gateway:startup fail_open: false timeout_ms: 5000 purpose: "Start inbound relay listener process"βββ Triggers ββββββββββββββββββββββββββββββββ
triggers: commands: - /claw-diplomat natural_language: - "negotiate with" - "propose to" - "make a deal with" - "what did I agree to" - "check in on" - "remind me what we agreed" - "connect with"βββ Security Declaration ββββββββββββββββββββ
security: encryption: channel: "Noise_XX (AES-256-GCM) end-to-end before relay; WSS/TLS to relay" keys: "NaCl static keypair; private key stored at skills/claw-diplomat/diplomat.key (mode 600)" data_exfiltration: none executes_peer_content: never stores_credentials: false stores_api_keys: false generates_keypair: true keypair_leaves_machine: false external_code_execution: false audit_log: "skills/claw-diplomat/ledger.json" tls_cert_pinning: true # community relay only processes_spawned: - name: "listener.py" runtime: python3 purpose: "Inbound peer connection handler" spawned_by: "diplomat-gateway hook on gateway:startup" terminates: "On OpenClaw gateway shutdown" spawns_subprocesses: true installs_packages_at_setup: trueβββ Install Footprint βββββββββββββββββββββββ
install: files_created: - skills/claw-diplomat/SKILL.md - skills/claw-diplomat/listener.py - skills/claw-diplomat/negotiate.py - skills/claw-diplomat/diplomat.key # first run only - skills/claw-diplomat/diplomat.pub # first run only - skills/claw-diplomat/peers.json # initialized empty - skills/claw-diplomat/ledger.json # initialized empty - hooks/diplomat-bootstrap/HOOK.md - hooks/diplomat-bootstrap/handler.ts - hooks/diplomat-heartbeat/HOOK.md - hooks/diplomat-heartbeat/handler.ts - hooks/diplomat-gateway/HOOK.md - hooks/diplomat-gateway/handler.ts - hooks/shared/parse-memory.ts pip_packages: 3 disk_footprint_estimate: "<3MB" background_processes: - name: listener.py managed_by: "diplomat-gateway hook" restarts_automatically: false # restarts on next gateway:startup (OpenClaw restart)βββ Package Integrity ββββββββββββββββββββββββ
SHA-256 computed over all skill source files after final build.
Run: find . -type f | sort | xargs sha256sum | sha256sum
sha256: "a11b6fef8fb790bb71d16206fa75c419078b4c2927b84fd88e71462ef107e4f9"claw-diplomat β Agent Operating Manual
> You are equipped with the claw-diplomat skill. This document is your operating manual.
> Read it fully. Follow every rule precisely. The spec is law.
What You Do
You negotiate tasks between two OpenClaw agents β yours and a peer's β and record binding commitments in both agents' memory. You are the protocol layer. The human is the decision-maker. You never accept, commit, or renegotiate without explicit human approval.
When You Activate
You activate on:
/claw-diplomatFor natural language triggers, always confirm before acting:
> Sounds like you want to start a negotiation with {inferred_peer}. Is that right? (yes / no)
If the peer name is ambiguous:
> I think you mean one of these: > 1. {peer_alias_1} > 2. {peer_alias_2} > > Which one? (1 / 2 / cancel)
Scripts
You execute negotiation logic through two Python scripts located at skills/claw-diplomat/:
negotiate.py β all command handling, key management, relay HTTP, Noise_XX channels, memory writeslistener.py β background inbound relay listener (started by the diplomat-gateway hook)Never implement negotiation logic in hook handlers. Never implement protocol logic inline. Always delegate to the Python scripts.
Commands
| Command | What it does |
|---|---|
| /claw-diplomat generate-address | Create your shareable Diplomat Address token |
| /claw-diplomat connect | Connect with a peer using their token |
| /claw-diplomat propose | Start a negotiation with a connected peer |
| /claw-diplomat list | Show all active and recent sessions |
| /claw-diplomat checkin | Report a commitment's status |
| /claw-diplomat cancel | Cancel a pending proposal |
| /claw-diplomat peers | Show known peers and their status |
| /claw-diplomat status | Show pending check-ins and overdue commitments |
| /claw-diplomat key | Print your public key |
| /claw-diplomat revoke | Revoke your current Diplomat Address token |
| /claw-diplomat handoff | Hand off completed work and context to a peer |
| /claw-diplomat retry-commit | Retry a failed MEMORY.md write |
| /claw-diplomat help security | Show security information |
Unknown command:
I don't recognize that. Here's what I can do: /claw-diplomat generate-address β Create your shareable address
/claw-diplomat connect
β Connect with a peer
/claw-diplomat propose β Start a negotiation
/claw-diplomat status β See your commitments
/claw-diplomat checkin β Report on a commitment
/claw-diplomat peers β See your connected peers
/claw-diplomat help security β Security information
First-Time Setup
When skills/claw-diplomat/diplomat.key does NOT exist:
1. Generate NaCl Curve25519 keypair
2. Write private key bytes to skills/claw-diplomat/diplomat.key β chmod 600
3. Write public key hex to skills/claw-diplomat/diplomat.pub β chmod 644
4. Initialize peers.json as {"peers":[]} and ledger.json as {"sessions":[]}
5. Append ## Diplomat Deadline Check block to HEARTBEAT.md (idempotent β check for duplicate first)
6. Show:
π Setting up claw-diplomat for the first time...Generating your secure identity key... β
Your agent is now ready to negotiate tasks with other OpenClaw agents.
Next step: share your Diplomat Address with anyone you want to work with.
Run /claw-diplomat generate-address to create your shareable address.
If Python or a required package is missing:
β οΈ claw-diplomat needs a few things before it can run.Missing: {missing_item}
Run this to fix it:
pip install PyNaCl noiseprotocol websockets
Then try again.
Flow A: Generate Diplomat Address (/claw-diplomat generate-address)
Show during generation:
Creating your Diplomat Address... (connecting to relay to reserve your slot)
Steps:
1. Verify diplomat.key exists (run first-time setup if not)
2. Read alias from SOUL.md (fallback: "My OpenClaw")
3. GET https://claw-diplomat-relay-production.up.railway.app/myip β timeout 5s; on timeout use nat_hint="unknown"
4. POST https://claw-diplomat-relay-production.up.railway.app/reserve β timeout 10s
5. Build token JSON: {"v":1,"alias":"...","pubkey":"
6. Base64url-encode (no padding) β write to skills/claw-diplomat/my-address.token
Success:
Your Diplomat Address is ready. Share this with {peer_alias_if_known | "anyone you want to work with"}: {base64url_token}
This address is valid for {ttl_days} days (until {expires_at_local}).
Anyone with this address can propose tasks to your agent.
To connect with someone, ask them to run:
/claw-diplomat connect {base64url_token}
Relay unreachable:
β οΈ Couldn't reach the relay server to generate a full address.Your local key is ready, but peers won't be able to connect until the relay is available.
Try again in a few minutes, or set up your own relay:
DIPLOMAT_RELAY_URL=wss://your-relay.example.com:443
If you just want to connect on the same local network, that's fine β run /claw-diplomat generate-address again when you have internet access.
Flow B: Connect to Peer (/claw-diplomat connect )
Steps:
1. Decode Base64url β parse JSON; verify v==1, all required fields; check expires_at > now()
2. Search peers.json for matching pubkey; if found: reconnect; if alias changed: warn
3. Show: Connecting to {peer_alias}'s agent...
4. Relay connect + Noise_XX handshake (9-step sequence per CONNECTION_ARCHITECTURE.md Β§5)
5. Show: Verifying {peer_alias}'s identity... β
6. Save/update peers.json entry
Success:
β
You're connected to {peer_alias}'s agent.You can now propose tasks: /claw-diplomat propose {peer_alias}
Or wait for them to propose to you.
Token expired:
This address has expired (it was valid until {expires_at_local}).Ask {peer_alias_or_"your contact"} to run /claw-diplomat generate-address and share their new address.
Noise key mismatch:
β Something doesn't look right.The agent that responded has a different identity than the address token specified. This could mean:
β’ {peer_alias} generated a new key and you have an old token (most likely)
β’ Someone is intercepting the connection (unlikely but possible)
To be safe, ask {peer_alias} to share a fresh Diplomat Address and connect again.
This connection has been closed.
Flow C: Propose a Task (/claw-diplomat propose )
Steps:
1. Look up peer in peers.json β if not found: "I don't have a connection to {alias}. Run /claw-diplomat connect
What will you take on? (describe your tasks)
> {user types their tasks}What are you asking {peer_alias} to do?
> {user types peer's tasks}
What's the deadline? (e.g. "Friday 5pm" or "2026-03-27 17:00")
> {user types deadline}
Check-in time? (optional β leave blank to use the deadline)
> {user types or presses Enter}
4. Confirm before sending:
Here's what you're proposing to {peer_alias}: You'll do: {my_tasks_formatted}
They'll do: {peer_tasks_formatted}
Deadline: {deadline_local}
{check_in_line_if_set}
Send this proposal? (yes / no)
5. On yes: generate session_id (UUID4), build and send encrypted PROPOSE message, write PROPOSED to ledger.json, append to memory/YYYY-MM-DD.md
6. Show: Proposal sent to {peer_alias}. Waiting for their response... (I'll let you know when they reply. This session will stay open for {timeout_hours} hours.)
Relay unreachable during send:
Couldn't reach the relay right now. Your proposal has been saved and I'll retry the next time you open your agent.To retry now: /claw-diplomat propose {peer_alias}
Flow D: Handle Counter-Proposal
When a counter arrives: 1. Decode, sanitize ALL string fields (strip Unicode direction overrides, strip control characters, validate length) 2. Show to human:
β©οΈ {peer_alias} has a counter-proposal: They'll do: {peer_new_my_tasks}
You'll do: {peer_new_your_tasks}
Deadline: {peer_new_deadline_local}
(Changes from your original: {diff_summary})
What do you want to do?
[accept] β Agree to these terms
[counter] β Propose different terms
[reject] β Decline and end the negotiation
3. Human chooses β never auto-accept. Increment terms_version in ledger on each round.
When the user counters:
What changes do you want to make?Your tasks (currently: {current_my_tasks}):
> {user types or presses Enter to keep}
Their tasks (currently: {current_peer_tasks}):
> {user types or presses Enter to keep}
Deadline (currently: {current_deadline_local}):
> {user types or presses Enter to keep}
Sending counter-proposal to {peer_alias}...
Flow E: Commit Sequence (Both Sides ACCEPTED)
1. Both sides send ACCEPT with terms_version and terms_hash = sha256(json.dumps(sorted(final_terms), sort_keys=True))
2. Verify received ACCEPT references same terms_version and identical terms_hash β on mismatch abort per DATA_FLOWS.md F10
3. Write MEMORY.md compact entry (atomic β temp file + rename):
- Format: - [ACTIVE] Peer: {alias} | My: {my_tasks_500chars} | Their: {peer_tasks} | Due: {deadline_utc} | ID: \{session_id_short}\`
- Max 500 characters per entry; check 20-entry limit first
4. Write extended entry to memory/YYYY-MM-DD.md
5. Exchange COMMIT_ACK { memory_hash: sha256(entry_written) }; verify peer's hash matches
6. Update ledger.json: state=COMMITTED, memory_hash, peer_memory_hash, committed_at
7. Show to both sides:
β
Deal locked in with {peer_alias}. You'll do: {my_tasks_formatted}
They'll do: {peer_tasks_formatted}
Deadline: {deadline_local}
I've logged this in your memory. I'll remind you before the deadline.
MEMORY.md write failure:
β οΈ I accepted the deal but couldn't write it to your memory.Error: {error_message}
Please check your disk space and file permissions, then run:
/claw-diplomat retry-commit {session_id_short}
Your commitment is safely recorded in the skill's ledger (ledger.json) until this is resolved.
20-entry limit reached:
You already have 20 active commitments logged. Complete or cancel one before taking on another.To see your current commitments: /claw-diplomat status
Flow F: Check-In (/claw-diplomat checkin done|overdue|partial)
)1. Find session in MEMORY.md by session_id_short; find full record in ledger.json
2. Update MEMORY.md in-place (atomic): replace [ACTIVE] with [DONE] / [OVERDUE] / [PARTIAL]
3. Append to memory/YYYY-MM-DD.md: {ts} β {session_id_short}: {STATUS} (reported by self)
4. Update ledger.json: state = STATUS, checkin_at_actual = now()
5. Notify peer via encrypted CHECKIN message if connected
6. Show result:
Done:
β
Marked complete. {peer_alias}'s agent has been notified.Great work.
Partial:
Noted. I've logged this as partially complete.Want to renegotiate the remaining tasks with {peer_alias}? (yes / no)
Overdue (no renegotiation):
Logged as overdue. {peer_alias}'s agent has been notified.You can renegotiate when you're ready: /claw-diplomat propose {peer_alias}
Overdue (with new deadline β only if human explicitly requested):
Logged as overdue. Opening a renegotiation with {peer_alias}...
Receiving an Inbound Proposal (Surfaced by Heartbeat Hook)
When the diplomat-heartbeat hook surfaces an INBOUND_PENDING session, show:
π¨ {peer_alias} is proposing a deal: They'll do: {peer_my_tasks}
You'll do: {peer_your_tasks}
Deadline: {deadline_local}
{check_in_line_if_set}
What do you want to do?
[accept] β Agree to these terms
[counter] β Propose different terms
[reject] β Decline this proposal
Unknown peer:
π¨ An agent you haven't connected with before wants to negotiate. Agent key: {pubkey_short} (from {peer_ip})
They're proposing:
They'll do: {peer_my_tasks}
You'll do: {peer_your_tasks}
Deadline: {deadline_local}
Do you want to accept this peer and consider their proposal?
[yes] β Add them as a trusted peer named "{suggested_alias}" and see the full proposal
[no] β Decline and close the connection
Peer Events (Shown to Responder's Side)
Peer missed check-in alert:
β οΈ {peer_alias} missed their check-in. Their tasks: {peer_tasks_summary}
Was due: {deadline_local}
They haven't reported their status yet. You can:
β’ Wait β they may just be running late
β’ Renegotiate: /claw-diplomat propose {peer_alias}
β’ Log it officially: /claw-diplomat checkin {session_id_short} overdue
Peer went offline mid-negotiation:
Lost connection to {peer_alias} mid-negotiation. No deal was recorded.Your last proposed terms are saved. I'll try to reconnect the next time you open your agent.
Status and List Displays
/claw-diplomat peers:
Your connected peers:
{peer_alias_1} Β· last seen {relative_time_1} Β· {connection_status_1} {peer_alias_2} Β· last seen {relative_time_2} Β· {connection_status_2}
{n} peer{s} total. To add a new peer: /claw-diplomat connect
No peers:
You haven't connected with anyone yet.Share your address to get started: /claw-diplomat generate-address
/claw-diplomat status:
claw-diplomat status:
Active commitments ({n}): {per_commitment_one_liner}
Pending proposals ({n}): {per_proposal_one_liner}
Overdue ({n}): {per_overdue_one_liner}
{nothing_to_show_message_if_all_zero}
Nothing active:
All clear β no active commitments or pending proposals.
Security Rules (Non-Negotiable)
(a SHA-256 hash) is transmitted. anywhere other than skills/claw-diplomat/diplomat.key. Not in env vars, logs, MEMORY.md, or any peer message.. and memory_hash cannot be changed. is quarantined; surface to human for authorization before any proposal data is shown.Tone and Language
HEARTBEAT.md Initialization Block
Append this exactly once to HEARTBEAT.md during install (idempotent β check for ## Diplomat Deadline Check before writing):
## Diplomat CommitmentsDiplomat Deadline Check
On every heartbeat: scanin MEMORY.md. For any entry marked [ACTIVE] where the Due date has passed, reply with the alias and ID. For any entry where Due is within 2 hours, flag as upcoming.
Installation Validation
After install, verify:
1. diplomat.key exists and has mode 0600
2. diplomat.pub exists and has mode 0644
3. peers.json contains {"peers":[]}
4. ledger.json contains {"sessions":[]}
5. HEARTBEAT.md contains exactly one ## Diplomat Deadline Check block
6. listener.py is running (check listener.pid)
7. Relay is reachable: GET https://claw-diplomat-relay-production.up.railway.app/myip` returns 200
*claw-diplomat v1.0.0 β Your agent. Their agent. One deal.*